blob: 808ed68f54f3edf3819047baa45f553117417d53 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Abhishek Singhb3e376c2017-01-04 15:27:13 +05302 * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lama7f454d2014-07-24 12:04:06 -070023 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +053026 *
Kiet Lamaa8e15a2014-02-11 23:30:06 -080027 */
Kiet Lam842dad02014-02-18 18:44:02 -080028
29
Kiet Lama7f454d2014-07-24 12:04:06 -070030
31
Jeff Johnson295189b2012-06-20 16:38:30 -070032/**========================================================================
33
34 \file wlan_hdd_cfg80211.c
35
36 \brief WLAN Host Device Driver implementation
37
Jeff Johnson295189b2012-06-20 16:38:30 -070038 ========================================================================*/
39
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070040/**=========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -070041
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070042 EDIT HISTORY FOR FILE
Jeff Johnson295189b2012-06-20 16:38:30 -070043
44
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070045 This section contains comments describing changes made to the module.
46 Notice that changes are listed in reverse chronological order.
Jeff Johnson295189b2012-06-20 16:38:30 -070047
48
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070049 $Header:$ $DateTime: $ $Author: $
Jeff Johnson295189b2012-06-20 16:38:30 -070050
51
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070052 when who what, where, why
Jeff Johnson295189b2012-06-20 16:38:30 -070053 -------- --- --------------------------------------------------------
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070054 21/12/09 Ashwani Created module.
Jeff Johnson295189b2012-06-20 16:38:30 -070055
56 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070057 Ganesh K
Jeff Johnson295189b2012-06-20 16:38:30 -070058 ==========================================================================*/
59
Jeff Johnson295189b2012-06-20 16:38:30 -070060
61#include <linux/version.h>
62#include <linux/module.h>
63#include <linux/kernel.h>
64#include <linux/init.h>
65#include <linux/wireless.h>
66#include <wlan_hdd_includes.h>
67#include <net/arp.h>
68#include <net/cfg80211.h>
69#include <linux/wireless.h>
70#include <wlan_hdd_wowl.h>
71#include <aniGlobal.h>
72#include "ccmApi.h"
73#include "sirParams.h"
74#include "dot11f.h"
75#include "wlan_hdd_assoc.h"
76#include "wlan_hdd_wext.h"
77#include "sme_Api.h"
78#include "wlan_hdd_p2p.h"
79#include "wlan_hdd_cfg80211.h"
80#include "wlan_hdd_hostapd.h"
81#include "sapInternal.h"
82#include "wlan_hdd_softap_tx_rx.h"
83#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053084#include "wlan_hdd_assoc.h"
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053085#include "wlan_hdd_power.h"
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053086#include "wlan_hdd_trace.h"
87#include "vos_types.h"
88#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070089#ifdef WLAN_BTAMP_FEATURE
90#include "bap_hdd_misc.h"
91#endif
92#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080093#include "wlan_hdd_tdls.h"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053094#include "wlan_hdd_wmm.h"
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053095#include "wlan_qct_wda.h"
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053096#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070097#include "wlan_hdd_dev_pwr.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +053098#include "qwlan_version.h"
c_manjeecfd1efb2015-09-25 19:32:34 +053099#include "wlan_logging_sock_svc.h"
Agrawal Ashishcfe83282016-09-29 13:03:45 +0530100#include "wlan_hdd_misc.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +0530101
Jeff Johnson295189b2012-06-20 16:38:30 -0700102
103#define g_mode_rates_size (12)
104#define a_mode_rates_size (8)
105#define FREQ_BASE_80211G (2407)
106#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700107#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530108#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700109#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800110 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700111
112#define HDD2GHZCHAN(freq, chan, flag) { \
113 .band = IEEE80211_BAND_2GHZ, \
114 .center_freq = (freq), \
115 .hw_value = (chan),\
116 .flags = (flag), \
117 .max_antenna_gain = 0 ,\
118 .max_power = 30, \
119}
120
121#define HDD5GHZCHAN(freq, chan, flag) { \
122 .band = IEEE80211_BAND_5GHZ, \
123 .center_freq = (freq), \
124 .hw_value = (chan),\
125 .flags = (flag), \
126 .max_antenna_gain = 0 ,\
127 .max_power = 30, \
128}
129
130#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
131{\
132 .bitrate = rate, \
133 .hw_value = rate_id, \
134 .flags = flag, \
135}
136
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530137#ifdef WLAN_FEATURE_VOWIFI_11R
138#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
139#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
140#endif
141
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530142#define HDD_CHANNEL_14 14
Dasari Srinivase18b2cf2014-10-28 17:09:42 +0530143#define WLAN_HDD_MAX_FEATURE_SET 8
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530144
Sunil Duttc69bccb2014-05-26 21:30:20 +0530145#ifdef WLAN_FEATURE_LINK_LAYER_STATS
146/*
147 * Used to allocate the size of 4096 for the link layer stats.
148 * The size of 4096 is considered assuming that all data per
149 * respective event fit with in the limit.Please take a call
150 * on the limit based on the data requirements on link layer
151 * statistics.
152 */
153#define LL_STATS_EVENT_BUF_SIZE 4096
154#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +0530155#ifdef WLAN_FEATURE_EXTSCAN
156/*
157 * Used to allocate the size of 4096 for the EXTScan NL data.
158 * The size of 4096 is considered assuming that all data per
159 * respective event fit with in the limit.Please take a call
160 * on the limit based on the data requirements.
161 */
162
163#define EXTSCAN_EVENT_BUF_SIZE 4096
164#define EXTSCAN_MAX_CACHED_RESULTS_PER_IND 32
165#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +0530166
Atul Mittal115287b2014-07-08 13:26:33 +0530167/*EXT TDLS*/
168/*
169 * Used to allocate the size of 4096 for the TDLS.
170 * The size of 4096 is considered assuming that all data per
171 * respective event fit with in the limit.Please take a call
172 * on the limit based on the data requirements on link layer
173 * statistics.
174 */
175#define EXTTDLS_EVENT_BUF_SIZE 4096
176
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +0530177/*
178 * Values for Mac spoofing feature
179 *
180 */
181#define MAC_ADDR_SPOOFING_FW_HOST_DISABLE 0
182#define MAC_ADDR_SPOOFING_FW_HOST_ENABLE 1
183#define MAC_ADDR_SPOOFING_FW_ENABLE_HOST_DISABLE 2
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +0530184#define MAC_ADDR_SPOOFING_DEFER_INTERVAL 10 //in ms
185
Anurag Chouhan343af7e2016-12-16 13:11:19 +0530186/*
187 * max_sched_scan_plans defined to 10
188 */
189#define MAX_SCHED_SCAN_PLANS 10
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +0530190
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530191static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700192{
193 WLAN_CIPHER_SUITE_WEP40,
194 WLAN_CIPHER_SUITE_WEP104,
195 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800196#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700197#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
198 WLAN_CIPHER_SUITE_KRK,
199 WLAN_CIPHER_SUITE_CCMP,
200#else
201 WLAN_CIPHER_SUITE_CCMP,
202#endif
203#ifdef FEATURE_WLAN_WAPI
204 WLAN_CIPHER_SUITE_SMS4,
205#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700206#ifdef WLAN_FEATURE_11W
207 WLAN_CIPHER_SUITE_AES_CMAC,
208#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700209};
210
211static inline int is_broadcast_ether_addr(const u8 *addr)
212{
213 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
214 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
215}
216
Agrawal Ashish97dec502015-11-26 20:20:58 +0530217const static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530218{
Jeff Johnson295189b2012-06-20 16:38:30 -0700219 HDD2GHZCHAN(2412, 1, 0) ,
220 HDD2GHZCHAN(2417, 2, 0) ,
221 HDD2GHZCHAN(2422, 3, 0) ,
222 HDD2GHZCHAN(2427, 4, 0) ,
223 HDD2GHZCHAN(2432, 5, 0) ,
224 HDD2GHZCHAN(2437, 6, 0) ,
225 HDD2GHZCHAN(2442, 7, 0) ,
226 HDD2GHZCHAN(2447, 8, 0) ,
227 HDD2GHZCHAN(2452, 9, 0) ,
228 HDD2GHZCHAN(2457, 10, 0) ,
229 HDD2GHZCHAN(2462, 11, 0) ,
230 HDD2GHZCHAN(2467, 12, 0) ,
231 HDD2GHZCHAN(2472, 13, 0) ,
232 HDD2GHZCHAN(2484, 14, 0) ,
233};
234
Agrawal Ashish97dec502015-11-26 20:20:58 +0530235const static struct ieee80211_channel hdd_channels_5_GHZ[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700236{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700237 HDD5GHZCHAN(4920, 240, 0) ,
238 HDD5GHZCHAN(4940, 244, 0) ,
239 HDD5GHZCHAN(4960, 248, 0) ,
240 HDD5GHZCHAN(4980, 252, 0) ,
241 HDD5GHZCHAN(5040, 208, 0) ,
242 HDD5GHZCHAN(5060, 212, 0) ,
243 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700244 HDD5GHZCHAN(5180, 36, 0) ,
245 HDD5GHZCHAN(5200, 40, 0) ,
246 HDD5GHZCHAN(5220, 44, 0) ,
247 HDD5GHZCHAN(5240, 48, 0) ,
248 HDD5GHZCHAN(5260, 52, 0) ,
249 HDD5GHZCHAN(5280, 56, 0) ,
250 HDD5GHZCHAN(5300, 60, 0) ,
251 HDD5GHZCHAN(5320, 64, 0) ,
252 HDD5GHZCHAN(5500,100, 0) ,
253 HDD5GHZCHAN(5520,104, 0) ,
254 HDD5GHZCHAN(5540,108, 0) ,
255 HDD5GHZCHAN(5560,112, 0) ,
256 HDD5GHZCHAN(5580,116, 0) ,
257 HDD5GHZCHAN(5600,120, 0) ,
258 HDD5GHZCHAN(5620,124, 0) ,
259 HDD5GHZCHAN(5640,128, 0) ,
260 HDD5GHZCHAN(5660,132, 0) ,
261 HDD5GHZCHAN(5680,136, 0) ,
262 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800263#ifdef FEATURE_WLAN_CH144
264 HDD5GHZCHAN(5720,144, 0) ,
265#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700266 HDD5GHZCHAN(5745,149, 0) ,
267 HDD5GHZCHAN(5765,153, 0) ,
268 HDD5GHZCHAN(5785,157, 0) ,
269 HDD5GHZCHAN(5805,161, 0) ,
270 HDD5GHZCHAN(5825,165, 0) ,
271};
272
273static struct ieee80211_rate g_mode_rates[] =
274{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530275 HDD_G_MODE_RATETAB(10, 0x1, 0),
276 HDD_G_MODE_RATETAB(20, 0x2, 0),
277 HDD_G_MODE_RATETAB(55, 0x4, 0),
278 HDD_G_MODE_RATETAB(110, 0x8, 0),
279 HDD_G_MODE_RATETAB(60, 0x10, 0),
280 HDD_G_MODE_RATETAB(90, 0x20, 0),
281 HDD_G_MODE_RATETAB(120, 0x40, 0),
282 HDD_G_MODE_RATETAB(180, 0x80, 0),
283 HDD_G_MODE_RATETAB(240, 0x100, 0),
284 HDD_G_MODE_RATETAB(360, 0x200, 0),
285 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700286 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530287};
Jeff Johnson295189b2012-06-20 16:38:30 -0700288
289static struct ieee80211_rate a_mode_rates[] =
290{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530291 HDD_G_MODE_RATETAB(60, 0x10, 0),
292 HDD_G_MODE_RATETAB(90, 0x20, 0),
293 HDD_G_MODE_RATETAB(120, 0x40, 0),
294 HDD_G_MODE_RATETAB(180, 0x80, 0),
295 HDD_G_MODE_RATETAB(240, 0x100, 0),
296 HDD_G_MODE_RATETAB(360, 0x200, 0),
297 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700298 HDD_G_MODE_RATETAB(540, 0x800, 0),
299};
300
301static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
302{
Agrawal Ashish97dec502015-11-26 20:20:58 +0530303 .channels = NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700304 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
305 .band = IEEE80211_BAND_2GHZ,
306 .bitrates = g_mode_rates,
307 .n_bitrates = g_mode_rates_size,
308 .ht_cap.ht_supported = 1,
309 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
310 | IEEE80211_HT_CAP_GRN_FLD
311 | IEEE80211_HT_CAP_DSSSCCK40
312 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
313 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
314 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
315 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
316 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
317 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
318};
319
Jeff Johnson295189b2012-06-20 16:38:30 -0700320static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
321{
Agrawal Ashish97dec502015-11-26 20:20:58 +0530322 .channels = NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700323 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
324 .band = IEEE80211_BAND_5GHZ,
325 .bitrates = a_mode_rates,
326 .n_bitrates = a_mode_rates_size,
327 .ht_cap.ht_supported = 1,
328 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
329 | IEEE80211_HT_CAP_GRN_FLD
330 | IEEE80211_HT_CAP_DSSSCCK40
331 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
332 | IEEE80211_HT_CAP_SGI_40
333 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
334 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
335 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
336 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
337 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
338 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
339};
340
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530341/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700342 TX/RX direction for each kind of interface */
343static const struct ieee80211_txrx_stypes
344wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
345 [NL80211_IFTYPE_STATION] = {
346 .tx = 0xffff,
347 .rx = BIT(SIR_MAC_MGMT_ACTION) |
348 BIT(SIR_MAC_MGMT_PROBE_REQ),
349 },
350 [NL80211_IFTYPE_AP] = {
351 .tx = 0xffff,
352 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
353 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
354 BIT(SIR_MAC_MGMT_PROBE_REQ) |
355 BIT(SIR_MAC_MGMT_DISASSOC) |
356 BIT(SIR_MAC_MGMT_AUTH) |
357 BIT(SIR_MAC_MGMT_DEAUTH) |
358 BIT(SIR_MAC_MGMT_ACTION),
359 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700360 [NL80211_IFTYPE_ADHOC] = {
361 .tx = 0xffff,
362 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
363 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
364 BIT(SIR_MAC_MGMT_PROBE_REQ) |
365 BIT(SIR_MAC_MGMT_DISASSOC) |
366 BIT(SIR_MAC_MGMT_AUTH) |
367 BIT(SIR_MAC_MGMT_DEAUTH) |
368 BIT(SIR_MAC_MGMT_ACTION),
369 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700370 [NL80211_IFTYPE_P2P_CLIENT] = {
371 .tx = 0xffff,
372 .rx = BIT(SIR_MAC_MGMT_ACTION) |
373 BIT(SIR_MAC_MGMT_PROBE_REQ),
374 },
375 [NL80211_IFTYPE_P2P_GO] = {
376 /* This is also same as for SoftAP */
377 .tx = 0xffff,
378 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
379 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
380 BIT(SIR_MAC_MGMT_PROBE_REQ) |
381 BIT(SIR_MAC_MGMT_DISASSOC) |
382 BIT(SIR_MAC_MGMT_AUTH) |
383 BIT(SIR_MAC_MGMT_DEAUTH) |
384 BIT(SIR_MAC_MGMT_ACTION),
385 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700386};
387
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800388#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800389static const struct ieee80211_iface_limit
390wlan_hdd_iface_limit[] = {
391 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800392 /* max = 3 ; Our driver create two interfaces during driver init
393 * wlan0 and p2p0 interfaces. p2p0 is considered as station
394 * interface until a group is formed. In JB architecture, once the
395 * group is formed, interface type of p2p0 is changed to P2P GO or
396 * Client.
397 * When supplicant remove the group, it first issue a set interface
398 * cmd to change the mode back to Station. In JB this works fine as
399 * we advertize two station type interface during driver init.
400 * Some vendors create separate interface for P2P GO/Client,
401 * after group formation(Third one). But while group remove
402 * supplicant first tries to change the mode(3rd interface) to STATION
403 * But as we advertized only two sta type interfaces nl80211 was
404 * returning error for the third one which was leading to failure in
405 * delete interface. Ideally while removing the group, supplicant
406 * should not try to change the 3rd interface mode to Station type.
407 * Till we get a fix in wpa_supplicant, we advertize max STA
408 * interface type to 3
409 */
410 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800411 .types = BIT(NL80211_IFTYPE_STATION),
412 },
413 {
414 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700415 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800416 },
417 {
418 .max = 1,
419 .types = BIT(NL80211_IFTYPE_P2P_GO) |
420 BIT(NL80211_IFTYPE_P2P_CLIENT),
421 },
422};
423
424/* By default, only single channel concurrency is allowed */
425static struct ieee80211_iface_combination
426wlan_hdd_iface_combination = {
427 .limits = wlan_hdd_iface_limit,
428 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800429 /*
430 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
431 * and p2p0 interfaces during driver init
432 * Some vendors create separate interface for P2P operations.
433 * wlan0: STA interface
434 * p2p0: P2P Device interface, action frames goes
435 * through this interface.
436 * p2p-xx: P2P interface, After GO negotiation this interface is
437 * created for p2p operations(GO/CLIENT interface).
438 */
439 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800440 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
441 .beacon_int_infra_match = false,
442};
443#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800444
Jeff Johnson295189b2012-06-20 16:38:30 -0700445static struct cfg80211_ops wlan_hdd_cfg80211_ops;
446
447/* Data rate 100KBPS based on IE Index */
448struct index_data_rate_type
449{
450 v_U8_t beacon_rate_index;
451 v_U16_t supported_rate[4];
452};
453
454/* 11B, 11G Rate table include Basic rate and Extended rate
455 The IDX field is the rate index
456 The HI field is the rate when RSSI is strong or being ignored
457 (in this case we report actual rate)
458 The MID field is the rate when RSSI is moderate
459 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
460 The LO field is the rate when RSSI is low
461 (in this case we don't report rates, actual current rate used)
462 */
463static const struct
464{
465 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700466 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700467} supported_data_rate[] =
468{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700469/* IDX HI HM LM LO (RSSI-based index */
470 {2, { 10, 10, 10, 0}},
471 {4, { 20, 20, 10, 0}},
472 {11, { 55, 20, 10, 0}},
473 {12, { 60, 55, 20, 0}},
474 {18, { 90, 55, 20, 0}},
475 {22, {110, 55, 20, 0}},
476 {24, {120, 90, 60, 0}},
477 {36, {180, 120, 60, 0}},
478 {44, {220, 180, 60, 0}},
479 {48, {240, 180, 90, 0}},
480 {66, {330, 180, 90, 0}},
481 {72, {360, 240, 90, 0}},
482 {96, {480, 240, 120, 0}},
483 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700484};
485
486/* MCS Based rate table */
487static struct index_data_rate_type supported_mcs_rate[] =
488{
489/* MCS L20 L40 S20 S40 */
490 {0, {65, 135, 72, 150}},
491 {1, {130, 270, 144, 300}},
492 {2, {195, 405, 217, 450}},
493 {3, {260, 540, 289, 600}},
494 {4, {390, 810, 433, 900}},
495 {5, {520, 1080, 578, 1200}},
496 {6, {585, 1215, 650, 1350}},
497 {7, {650, 1350, 722, 1500}}
498};
499
Leo Chang6f8870f2013-03-26 18:11:36 -0700500#ifdef WLAN_FEATURE_11AC
501
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530502#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700503
504struct index_vht_data_rate_type
505{
506 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530507 v_U16_t supported_VHT80_rate[2];
508 v_U16_t supported_VHT40_rate[2];
509 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700510};
511
512typedef enum
513{
514 DATA_RATE_11AC_MAX_MCS_7,
515 DATA_RATE_11AC_MAX_MCS_8,
516 DATA_RATE_11AC_MAX_MCS_9,
517 DATA_RATE_11AC_MAX_MCS_NA
518} eDataRate11ACMaxMcs;
519
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530520/* SSID broadcast type */
521typedef enum eSSIDBcastType
522{
523 eBCAST_UNKNOWN = 0,
524 eBCAST_NORMAL = 1,
525 eBCAST_HIDDEN = 2,
526} tSSIDBcastType;
527
Leo Chang6f8870f2013-03-26 18:11:36 -0700528/* MCS Based VHT rate table */
529static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
530{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530531/* MCS L80 S80 L40 S40 L20 S40*/
532 {0, {293, 325}, {135, 150}, {65, 72}},
533 {1, {585, 650}, {270, 300}, {130, 144}},
534 {2, {878, 975}, {405, 450}, {195, 217}},
535 {3, {1170, 1300}, {540, 600}, {260, 289}},
536 {4, {1755, 1950}, {810, 900}, {390, 433}},
537 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
538 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
539 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
540 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
541 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700542};
543#endif /* WLAN_FEATURE_11AC */
544
c_hpothu79aab322014-07-14 21:11:01 +0530545/*array index points to MCS and array value points respective rssi*/
546static int rssiMcsTbl[][10] =
547{
548/*MCS 0 1 2 3 4 5 6 7 8 9*/
549 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
550 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
551 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
552};
553
Jeff Johnson295189b2012-06-20 16:38:30 -0700554extern struct net_device_ops net_ops_struct;
Dasari Srinivas7875a302014-09-26 17:50:57 +0530555#ifdef FEATURE_WLAN_SCAN_PNO
556static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
557#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700558
Leo Chang9056f462013-08-01 19:21:11 -0700559#ifdef WLAN_NL80211_TESTMODE
560enum wlan_hdd_tm_attr
561{
562 WLAN_HDD_TM_ATTR_INVALID = 0,
563 WLAN_HDD_TM_ATTR_CMD = 1,
564 WLAN_HDD_TM_ATTR_DATA = 2,
565 WLAN_HDD_TM_ATTR_TYPE = 3,
566 /* keep last */
567 WLAN_HDD_TM_ATTR_AFTER_LAST,
568 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
569};
570
571enum wlan_hdd_tm_cmd
572{
573 WLAN_HDD_TM_CMD_WLAN_HB = 1,
574};
575
576#define WLAN_HDD_TM_DATA_MAX_LEN 5000
577
578static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
579{
580 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
581 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
582 .len = WLAN_HDD_TM_DATA_MAX_LEN },
583};
584#endif /* WLAN_NL80211_TESTMODE */
585
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800586#ifdef FEATURE_WLAN_CH_AVOID
587/*
588 * FUNCTION: wlan_hdd_send_avoid_freq_event
589 * This is called when wlan driver needs to send vendor specific
590 * avoid frequency range event to userspace
591 */
592int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
593 tHddAvoidFreqList *pAvoidFreqList)
594{
595 struct sk_buff *vendor_event;
596
597 ENTER();
598
599 if (!pHddCtx)
600 {
601 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
602 "%s: HDD context is null", __func__);
603 return -1;
604 }
605
606 if (!pAvoidFreqList)
607 {
608 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
609 "%s: pAvoidFreqList is null", __func__);
610 return -1;
611 }
612
613 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530614#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
615 NULL,
616#endif
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800617 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530618 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800619 GFP_KERNEL);
620 if (!vendor_event)
621 {
622 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
623 "%s: cfg80211_vendor_event_alloc failed", __func__);
624 return -1;
625 }
626
627 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
628 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
629
630 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
631
632 EXIT();
633 return 0;
634}
635#endif /* FEATURE_WLAN_CH_AVOID */
636
Srinivas Dasari030bad32015-02-18 23:23:54 +0530637/*
638 * FUNCTION: __wlan_hdd_cfg80211_nan_request
639 * This is called when wlan driver needs to send vendor specific
640 * nan request event.
641 */
642static int __wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
643 struct wireless_dev *wdev,
644 const void *data, int data_len)
645{
646 tNanRequestReq nan_req;
647 VOS_STATUS status;
648 int ret_val = -1;
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530649 struct net_device *dev = wdev->netdev;
650 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
651 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530652 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
653
654 if (0 == data_len)
655 {
656 hddLog(VOS_TRACE_LEVEL_ERROR,
657 FL("NAN - Invalid Request, length = 0"));
658 return ret_val;
659 }
660
661 if (NULL == data)
662 {
663 hddLog(VOS_TRACE_LEVEL_ERROR,
664 FL("NAN - Invalid Request, data is NULL"));
665 return ret_val;
666 }
667
668 status = wlan_hdd_validate_context(pHddCtx);
669 if (0 != status)
670 {
671 hddLog(VOS_TRACE_LEVEL_ERROR,
672 FL("HDD context is not valid"));
673 return -EINVAL;
674 }
675
676 hddLog(LOG1, FL("Received NAN command"));
677 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
678 (tANI_U8 *)data, data_len);
679
680 /* check the NAN Capability */
681 if (TRUE != sme_IsFeatureSupportedByFW(NAN))
682 {
683 hddLog(VOS_TRACE_LEVEL_ERROR,
684 FL("NAN is not supported by Firmware"));
685 return -EINVAL;
686 }
687
688 nan_req.request_data_len = data_len;
689 nan_req.request_data = data;
690
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530691 status = sme_NanRequest(hHal, &nan_req, pAdapter->sessionId);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530692 if (VOS_STATUS_SUCCESS == status)
693 {
694 ret_val = 0;
695 }
696 return ret_val;
697}
698
699/*
700 * FUNCTION: wlan_hdd_cfg80211_nan_request
701 * Wrapper to protect the nan vendor command from ssr
702 */
703static int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
704 struct wireless_dev *wdev,
705 const void *data, int data_len)
706{
707 int ret;
708
709 vos_ssr_protect(__func__);
710 ret = __wlan_hdd_cfg80211_nan_request(wiphy, wdev, data, data_len);
711 vos_ssr_unprotect(__func__);
712
713 return ret;
714}
715
716/*
717 * FUNCTION: wlan_hdd_cfg80211_nan_callback
718 * This is a callback function and it gets called
719 * when we need to report nan response event to
720 * upper layers.
721 */
722static void wlan_hdd_cfg80211_nan_callback(void* ctx, tSirNanEvent* msg)
723{
724 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
725 struct sk_buff *vendor_event;
726 int status;
727 tSirNanEvent *data;
728
729 ENTER();
730 if (NULL == msg)
731 {
732 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
733 FL(" msg received here is null"));
734 return;
735 }
736 data = msg;
737
738 status = wlan_hdd_validate_context(pHddCtx);
739
740 if (0 != status)
741 {
742 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
743 FL("HDD context is not valid"));
744 return;
745 }
746
747 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530748#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
749 NULL,
750#endif
Srinivas Dasari030bad32015-02-18 23:23:54 +0530751 data->event_data_len +
752 NLMSG_HDRLEN,
753 QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX,
754 GFP_KERNEL);
755
756 if (!vendor_event)
757 {
758 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
759 FL("cfg80211_vendor_event_alloc failed"));
760 return;
761 }
762 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN,
763 data->event_data_len, data->event_data))
764 {
765 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
766 FL("QCA_WLAN_VENDOR_ATTR_NAN put fail"));
767 kfree_skb(vendor_event);
768 return;
769 }
770 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
771 EXIT();
772}
773
774/*
775 * FUNCTION: wlan_hdd_cfg80211_nan_init
776 * This function is called to register the callback to sme layer
777 */
778inline void wlan_hdd_cfg80211_nan_init(hdd_context_t *pHddCtx)
779{
780 sme_NanRegisterCallback(pHddCtx->hHal, wlan_hdd_cfg80211_nan_callback);
781}
782
783
Sunil Duttc69bccb2014-05-26 21:30:20 +0530784#ifdef WLAN_FEATURE_LINK_LAYER_STATS
785
786static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
787 struct sk_buff *vendor_event)
788{
789 if (nla_put_u8(vendor_event,
790 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
791 stats->rate.preamble) ||
792 nla_put_u8(vendor_event,
793 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
794 stats->rate.nss) ||
795 nla_put_u8(vendor_event,
796 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
797 stats->rate.bw) ||
798 nla_put_u8(vendor_event,
799 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
800 stats->rate.rateMcsIdx) ||
801 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
802 stats->rate.bitrate ) ||
803 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
804 stats->txMpdu ) ||
805 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
806 stats->rxMpdu ) ||
807 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
808 stats->mpduLost ) ||
809 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
810 stats->retries) ||
811 nla_put_u32(vendor_event,
812 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
813 stats->retriesShort ) ||
814 nla_put_u32(vendor_event,
815 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
816 stats->retriesLong))
817 {
818 hddLog(VOS_TRACE_LEVEL_ERROR,
819 FL("QCA_WLAN_VENDOR_ATTR put fail"));
820 return FALSE;
821 }
822 return TRUE;
823}
824
825static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
826 struct sk_buff *vendor_event)
827{
828 u32 i = 0;
829 struct nlattr *rateInfo;
830 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
831 stats->type) ||
832 nla_put(vendor_event,
833 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
834 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
835 nla_put_u32(vendor_event,
836 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
837 stats->capabilities) ||
838 nla_put_u32(vendor_event,
839 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
840 stats->numRate))
841 {
842 hddLog(VOS_TRACE_LEVEL_ERROR,
843 FL("QCA_WLAN_VENDOR_ATTR put fail"));
844 goto error;
845 }
846
847 rateInfo = nla_nest_start(vendor_event,
848 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530849 if(!rateInfo)
850 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530851 for (i = 0; i < stats->numRate; i++)
852 {
853 struct nlattr *rates;
854 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
855 stats->rateStats +
856 (i * sizeof(tSirWifiRateStat)));
857 rates = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530858 if(!rates)
859 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530860
861 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
862 {
863 hddLog(VOS_TRACE_LEVEL_ERROR,
864 FL("QCA_WLAN_VENDOR_ATTR put fail"));
865 return FALSE;
866 }
867 nla_nest_end(vendor_event, rates);
868 }
869 nla_nest_end(vendor_event, rateInfo);
870
871 return TRUE;
872error:
873 return FALSE;
874}
875
876static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
877 struct sk_buff *vendor_event)
878{
879 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
880 stats->ac ) ||
881 nla_put_u32(vendor_event,
882 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
883 stats->txMpdu ) ||
884 nla_put_u32(vendor_event,
885 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
886 stats->rxMpdu ) ||
887 nla_put_u32(vendor_event,
888 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
889 stats->txMcast ) ||
890 nla_put_u32(vendor_event,
891 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
892 stats->rxMcast ) ||
893 nla_put_u32(vendor_event,
894 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
895 stats->rxAmpdu ) ||
896 nla_put_u32(vendor_event,
897 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
898 stats->txAmpdu ) ||
899 nla_put_u32(vendor_event,
900 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
901 stats->mpduLost )||
902 nla_put_u32(vendor_event,
903 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
904 stats->retries ) ||
905 nla_put_u32(vendor_event,
906 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
907 stats->retriesShort ) ||
908 nla_put_u32(vendor_event,
909 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
910 stats->retriesLong ) ||
911 nla_put_u32(vendor_event,
912 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
913 stats->contentionTimeMin ) ||
914 nla_put_u32(vendor_event,
915 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
916 stats->contentionTimeMax ) ||
917 nla_put_u32(vendor_event,
918 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
919 stats->contentionTimeAvg ) ||
920 nla_put_u32(vendor_event,
921 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
922 stats->contentionNumSamples ))
923 {
924 hddLog(VOS_TRACE_LEVEL_ERROR,
925 FL("QCA_WLAN_VENDOR_ATTR put fail") );
926 return FALSE;
927 }
928 return TRUE;
929}
930
931static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
932 struct sk_buff *vendor_event)
933{
Dino Myclec8f3f332014-07-21 16:48:27 +0530934 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530935 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
936 nla_put(vendor_event,
937 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
938 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
939 nla_put_u32(vendor_event,
940 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
941 stats->state ) ||
942 nla_put_u32(vendor_event,
943 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
944 stats->roaming ) ||
945 nla_put_u32(vendor_event,
946 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
947 stats->capabilities ) ||
948 nla_put(vendor_event,
949 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
950 strlen(stats->ssid), stats->ssid) ||
951 nla_put(vendor_event,
952 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
953 WNI_CFG_BSSID_LEN, stats->bssid) ||
954 nla_put(vendor_event,
955 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
956 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
957 nla_put(vendor_event,
958 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
959 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
960 )
961 {
962 hddLog(VOS_TRACE_LEVEL_ERROR,
963 FL("QCA_WLAN_VENDOR_ATTR put fail") );
964 return FALSE;
965 }
966 return TRUE;
967}
968
Dino Mycle3b9536d2014-07-09 22:05:24 +0530969static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
970 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530971 struct sk_buff *vendor_event)
972{
973 int i = 0;
974 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530975 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
976 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +0530977 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530978
Sunil Duttc69bccb2014-05-26 21:30:20 +0530979 if (FALSE == put_wifi_interface_info(
980 &pWifiIfaceStat->info,
981 vendor_event))
982 {
983 hddLog(VOS_TRACE_LEVEL_ERROR,
984 FL("QCA_WLAN_VENDOR_ATTR put fail") );
985 return FALSE;
986
987 }
Dino Mycle3b9536d2014-07-09 22:05:24 +0530988 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
989 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
990 if (NULL == pWifiIfaceStatTL)
991 {
992 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
993 return FALSE;
994 }
995
Srinivas Dasaria8a304f2014-11-15 16:13:37 +0530996 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
997 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
998 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
999 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
1000
1001 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
1002 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
1003 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
1004 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301005
1006 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
1007 {
1008 if (VOS_STATUS_SUCCESS ==
1009 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1010 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
1011 {
1012 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
1013 * obtained from TL structure
1014 */
1015
1016 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
1017 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301018 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
1019
Srinivas Dasari98947432014-11-07 19:41:24 +05301020 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
1021 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
1022 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
1023 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
1024 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
1025 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
1026 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
1027 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301028
Srinivas Dasari98947432014-11-07 19:41:24 +05301029 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
1030 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
1031 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
1032 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
1033 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
1034 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
1035 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
1036 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301037
Srinivas Dasari98947432014-11-07 19:41:24 +05301038 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
1039 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
1040 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
1041 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
1042 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
1043 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
1044 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
1045 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301046 }
1047 else
1048 {
1049 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
1050 }
1051
Dino Mycle3b9536d2014-07-09 22:05:24 +05301052 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
1053 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
1054 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
1055 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
1056 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
1057 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
1058 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
1059 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
1060 }
1061 else
1062 {
1063 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
1064 }
1065
1066
Sunil Duttc69bccb2014-05-26 21:30:20 +05301067
1068 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301069 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1070 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_IFACE) ||
1071 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301072 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
1073 pWifiIfaceStat->beaconRx) ||
1074 nla_put_u32(vendor_event,
1075 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
1076 pWifiIfaceStat->mgmtRx) ||
1077 nla_put_u32(vendor_event,
1078 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
1079 pWifiIfaceStat->mgmtActionRx) ||
1080 nla_put_u32(vendor_event,
1081 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
1082 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301083 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301084 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
1085 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301086 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301087 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
1088 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301089 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301090 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
1091 pWifiIfaceStat->rssiAck))
1092 {
1093 hddLog(VOS_TRACE_LEVEL_ERROR,
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05301094 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1095 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301096 return FALSE;
1097 }
1098
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05301099#ifdef FEATURE_EXT_LL_STAT
1100 /*
1101 * Ensure when EXT_LL_STAT is supported by both host and fwr,
1102 * then host should send Leaky AP stats to upper layer,
1103 * otherwise no need to send these stats.
1104 */
1105 if(sme_IsFeatureSupportedByFW(EXT_LL_STAT) &&
1106 sme_IsFeatureSupportedByDriver(EXT_LL_STAT)
1107 )
1108 {
1109 hddLog(VOS_TRACE_LEVEL_INFO,
1110 FL("EXT_LL_STAT is supported by fwr and host %u %u %u %llu"),
1111 pWifiIfaceStat->leakyApStat.is_leaky_ap,
1112 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked,
1113 pWifiIfaceStat->leakyApStat.rx_leak_window,
1114 pWifiIfaceStat->leakyApStat.avg_bcn_spread);
1115 if (nla_put_u32(vendor_event,
1116 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_DETECTED,
1117 pWifiIfaceStat->leakyApStat.is_leaky_ap) ||
1118 nla_put_u32(vendor_event,
1119 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_AVG_NUM_FRAMES_LEAKED,
1120 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked) ||
1121 nla_put_u32(vendor_event,
1122 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_GUARD_TIME,
1123 pWifiIfaceStat->leakyApStat.rx_leak_window) ||
1124 nla_put_u64(vendor_event,
1125 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_AVERAGE_TSF_OFFSET,
1126 pWifiIfaceStat->leakyApStat.avg_bcn_spread))
1127 {
1128 hddLog(VOS_TRACE_LEVEL_ERROR,
1129 FL("EXT_LL_STAT put fail"));
1130 vos_mem_free(pWifiIfaceStatTL);
1131 return FALSE;
1132 }
1133 }
1134#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +05301135 wmmInfo = nla_nest_start(vendor_event,
1136 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301137 if(!wmmInfo)
1138 {
1139 vos_mem_free(pWifiIfaceStatTL);
1140 return FALSE;
1141 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301142 for (i = 0; i < WIFI_AC_MAX; i++)
1143 {
1144 struct nlattr *wmmStats;
1145 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301146 if(!wmmStats)
1147 {
1148 vos_mem_free(pWifiIfaceStatTL);
1149 return FALSE;
1150 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301151 if (FALSE == put_wifi_wmm_ac_stat(
1152 &pWifiIfaceStat->AccessclassStats[i],
1153 vendor_event))
1154 {
1155 hddLog(VOS_TRACE_LEVEL_ERROR,
1156 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05301157 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301158 return FALSE;
1159 }
1160
1161 nla_nest_end(vendor_event, wmmStats);
1162 }
1163 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +05301164 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301165 return TRUE;
1166}
1167
1168static tSirWifiInterfaceMode
1169 hdd_map_device_to_ll_iface_mode ( int deviceMode )
1170{
1171 switch (deviceMode)
1172 {
1173 case WLAN_HDD_INFRA_STATION:
1174 return WIFI_INTERFACE_STA;
1175 case WLAN_HDD_SOFTAP:
1176 return WIFI_INTERFACE_SOFTAP;
1177 case WLAN_HDD_P2P_CLIENT:
1178 return WIFI_INTERFACE_P2P_CLIENT;
1179 case WLAN_HDD_P2P_GO:
1180 return WIFI_INTERFACE_P2P_GO;
1181 case WLAN_HDD_IBSS:
1182 return WIFI_INTERFACE_IBSS;
1183 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05301184 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301185 }
1186}
1187
1188static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
1189 tpSirWifiInterfaceInfo pInfo)
1190{
1191 v_U8_t *staMac = NULL;
1192 hdd_station_ctx_t *pHddStaCtx;
1193 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1194 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
1195
1196 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
1197
1198 vos_mem_copy(pInfo->macAddr,
1199 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1200
1201 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1202 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
1203 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
1204 {
1205 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1206 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
1207 {
1208 pInfo->state = WIFI_DISCONNECTED;
1209 }
1210 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
1211 {
1212 hddLog(VOS_TRACE_LEVEL_ERROR,
1213 "%s: Session ID %d, Connection is in progress", __func__,
1214 pAdapter->sessionId);
1215 pInfo->state = WIFI_ASSOCIATING;
1216 }
1217 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1218 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
1219 {
1220 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
1221 hddLog(VOS_TRACE_LEVEL_ERROR,
1222 "%s: client " MAC_ADDRESS_STR
1223 " is in the middle of WPS/EAPOL exchange.", __func__,
1224 MAC_ADDR_ARRAY(staMac));
1225 pInfo->state = WIFI_AUTHENTICATING;
1226 }
1227 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
1228 {
1229 pInfo->state = WIFI_ASSOCIATED;
1230 vos_mem_copy(pInfo->bssid,
1231 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
1232 vos_mem_copy(pInfo->ssid,
1233 pHddStaCtx->conn_info.SSID.SSID.ssId,
1234 pHddStaCtx->conn_info.SSID.SSID.length);
1235 //NULL Terminate the string.
1236 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
1237 }
1238 }
1239 vos_mem_copy(pInfo->countryStr,
1240 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1241
1242 vos_mem_copy(pInfo->apCountryStr,
1243 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1244
1245 return TRUE;
1246}
1247
1248/*
1249 * hdd_link_layer_process_peer_stats () - This function is called after
1250 * receiving Link Layer Peer statistics from FW.This function converts
1251 * the firmware data to the NL data and sends the same to the kernel/upper
1252 * layers.
1253 */
1254static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
1255 v_VOID_t *pData)
1256{
1257 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301258 tpSirWifiPeerStat pWifiPeerStat;
1259 tpSirWifiPeerInfo pWifiPeerInfo;
1260 struct nlattr *peerInfo;
1261 struct sk_buff *vendor_event;
1262 int status, i;
1263
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301264 ENTER();
1265
Sunil Duttc69bccb2014-05-26 21:30:20 +05301266 status = wlan_hdd_validate_context(pHddCtx);
1267 if (0 != status)
1268 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301269 return;
1270 }
1271
1272 pWifiPeerStat = (tpSirWifiPeerStat) pData;
1273
1274 hddLog(VOS_TRACE_LEVEL_INFO,
1275 "LL_STATS_PEER_ALL : numPeers %u",
1276 pWifiPeerStat->numPeers);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301277 /*
1278 * Allocate a size of 4096 for the peer stats comprising
1279 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1280 * sizeof (tSirWifiRateStat).Each field is put with an
1281 * NL attribute.The size of 4096 is considered assuming
1282 * that number of rates shall not exceed beyond 50 with
1283 * the sizeof (tSirWifiRateStat) being 32.
1284 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301285 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1286 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301287 if (!vendor_event)
1288 {
1289 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301290 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
Sunil Duttc69bccb2014-05-26 21:30:20 +05301291 __func__);
1292 return;
1293 }
1294 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301295 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1296 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_PEER) ||
1297 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301298 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1299 pWifiPeerStat->numPeers))
1300 {
1301 hddLog(VOS_TRACE_LEVEL_ERROR,
1302 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1303 kfree_skb(vendor_event);
1304 return;
1305 }
1306
1307 peerInfo = nla_nest_start(vendor_event,
1308 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301309 if(!peerInfo)
1310 {
1311 hddLog(VOS_TRACE_LEVEL_ERROR,
1312 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
1313 __func__);
1314 kfree_skb(vendor_event);
1315 return;
1316 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301317
1318 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1319 pWifiPeerStat->peerInfo);
1320
1321 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1322 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301323 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301324 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301325
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301326 if(!peers)
1327 {
1328 hddLog(VOS_TRACE_LEVEL_ERROR,
1329 "%s: peer stats put fail",
1330 __func__);
1331 kfree_skb(vendor_event);
1332 return;
1333 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301334 if (FALSE == put_wifi_peer_info(
1335 pWifiPeerInfo, vendor_event))
1336 {
1337 hddLog(VOS_TRACE_LEVEL_ERROR,
1338 "%s: put_wifi_peer_info put fail", __func__);
1339 kfree_skb(vendor_event);
1340 return;
1341 }
1342
1343 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1344 pWifiPeerStat->peerInfo +
1345 (i * sizeof(tSirWifiPeerInfo)) +
1346 (numRate * sizeof (tSirWifiRateStat)));
1347 nla_nest_end(vendor_event, peers);
1348 }
1349 nla_nest_end(vendor_event, peerInfo);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301350 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301351 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301352}
1353
1354/*
1355 * hdd_link_layer_process_iface_stats () - This function is called after
1356 * receiving Link Layer Interface statistics from FW.This function converts
1357 * the firmware data to the NL data and sends the same to the kernel/upper
1358 * layers.
1359 */
1360static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1361 v_VOID_t *pData)
1362{
1363 tpSirWifiIfaceStat pWifiIfaceStat;
1364 struct sk_buff *vendor_event;
1365 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1366 int status;
1367
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301368 ENTER();
1369
Sunil Duttc69bccb2014-05-26 21:30:20 +05301370 status = wlan_hdd_validate_context(pHddCtx);
1371 if (0 != status)
1372 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301373 return;
1374 }
1375 /*
1376 * Allocate a size of 4096 for the interface stats comprising
1377 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1378 * assuming that all these fit with in the limit.Please take
1379 * a call on the limit based on the data requirements on
1380 * interface statistics.
1381 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301382 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1383 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301384 if (!vendor_event)
1385 {
1386 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301387 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301388 return;
1389 }
1390
1391 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1392
Dino Mycle3b9536d2014-07-09 22:05:24 +05301393
1394 if (FALSE == hdd_get_interface_info( pAdapter,
1395 &pWifiIfaceStat->info))
1396 {
1397 hddLog(VOS_TRACE_LEVEL_ERROR,
1398 FL("hdd_get_interface_info get fail") );
1399 kfree_skb(vendor_event);
1400 return;
1401 }
1402
1403 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
1404 vendor_event))
1405 {
1406 hddLog(VOS_TRACE_LEVEL_ERROR,
1407 FL("put_wifi_iface_stats fail") );
1408 kfree_skb(vendor_event);
1409 return;
1410 }
1411
Sunil Duttc69bccb2014-05-26 21:30:20 +05301412 hddLog(VOS_TRACE_LEVEL_INFO,
1413 "WMI_LINK_STATS_IFACE Data");
1414
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301415 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301416
1417 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301418}
1419
1420/*
1421 * hdd_link_layer_process_radio_stats () - This function is called after
1422 * receiving Link Layer Radio statistics from FW.This function converts
1423 * the firmware data to the NL data and sends the same to the kernel/upper
1424 * layers.
1425 */
1426static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1427 v_VOID_t *pData)
1428{
1429 int status, i;
1430 tpSirWifiRadioStat pWifiRadioStat;
1431 tpSirWifiChannelStats pWifiChannelStats;
1432 struct sk_buff *vendor_event;
1433 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1434 struct nlattr *chList;
1435
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301436 ENTER();
1437
Sunil Duttc69bccb2014-05-26 21:30:20 +05301438 status = wlan_hdd_validate_context(pHddCtx);
1439 if (0 != status)
1440 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301441 return;
1442 }
1443 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1444
1445 hddLog(VOS_TRACE_LEVEL_INFO,
1446 "LL_STATS_RADIO"
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05301447 " number of radios = %u"
Sunil Duttc69bccb2014-05-26 21:30:20 +05301448 " radio is %d onTime is %u "
1449 " txTime is %u rxTime is %u "
1450 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301451 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301452 " onTimePnoScan is %u onTimeHs20 is %u "
1453 " numChannels is %u",
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05301454 NUM_RADIOS,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301455 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1456 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1457 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301458 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301459 pWifiRadioStat->onTimeRoamScan,
1460 pWifiRadioStat->onTimePnoScan,
1461 pWifiRadioStat->onTimeHs20,
1462 pWifiRadioStat->numChannels);
1463 /*
1464 * Allocate a size of 4096 for the Radio stats comprising
1465 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1466 * (tSirWifiChannelStats).Each channel data is put with an
1467 * NL attribute.The size of 4096 is considered assuming that
1468 * number of channels shall not exceed beyond 60 with the
1469 * sizeof (tSirWifiChannelStats) being 24 bytes.
1470 */
1471
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301472 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1473 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301474 if (!vendor_event)
1475 {
1476 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301477 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301478 return;
1479 }
1480
1481 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301482 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1483 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO) ||
1484 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301485 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
1486 pWifiRadioStat->radio) ||
1487 nla_put_u32(vendor_event,
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05301488 QCA_WLAN_VENDOR_ATTR_LL_STATS_NUM_RADIOS,
1489 NUM_RADIOS) ||
1490 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301491 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
1492 pWifiRadioStat->onTime) ||
1493 nla_put_u32(vendor_event,
1494 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
1495 pWifiRadioStat->txTime) ||
1496 nla_put_u32(vendor_event,
1497 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
1498 pWifiRadioStat->rxTime) ||
1499 nla_put_u32(vendor_event,
1500 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
1501 pWifiRadioStat->onTimeScan) ||
1502 nla_put_u32(vendor_event,
1503 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
1504 pWifiRadioStat->onTimeNbd) ||
1505 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301506 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
1507 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05301508 nla_put_u32(vendor_event,
1509 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
1510 pWifiRadioStat->onTimeRoamScan) ||
1511 nla_put_u32(vendor_event,
1512 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
1513 pWifiRadioStat->onTimePnoScan) ||
1514 nla_put_u32(vendor_event,
1515 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
1516 pWifiRadioStat->onTimeHs20) ||
1517 nla_put_u32(vendor_event,
1518 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
1519 pWifiRadioStat->numChannels))
1520 {
1521 hddLog(VOS_TRACE_LEVEL_ERROR,
1522 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1523 kfree_skb(vendor_event);
1524 return ;
1525 }
1526
1527 chList = nla_nest_start(vendor_event,
1528 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301529 if(!chList)
1530 {
1531 hddLog(VOS_TRACE_LEVEL_ERROR,
1532 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
1533 __func__);
1534 kfree_skb(vendor_event);
1535 return;
1536 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301537 for (i = 0; i < pWifiRadioStat->numChannels; i++)
1538 {
1539 struct nlattr *chInfo;
1540
1541 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
1542 pWifiRadioStat->channels +
1543 (i * sizeof(tSirWifiChannelStats)));
1544
Sunil Duttc69bccb2014-05-26 21:30:20 +05301545 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301546 if(!chInfo)
1547 {
1548 hddLog(VOS_TRACE_LEVEL_ERROR,
1549 "%s: failed to put chInfo",
1550 __func__);
1551 kfree_skb(vendor_event);
1552 return;
1553 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301554
1555 if (nla_put_u32(vendor_event,
1556 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
1557 pWifiChannelStats->channel.width) ||
1558 nla_put_u32(vendor_event,
1559 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
1560 pWifiChannelStats->channel.centerFreq) ||
1561 nla_put_u32(vendor_event,
1562 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
1563 pWifiChannelStats->channel.centerFreq0) ||
1564 nla_put_u32(vendor_event,
1565 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
1566 pWifiChannelStats->channel.centerFreq1) ||
1567 nla_put_u32(vendor_event,
1568 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
1569 pWifiChannelStats->onTime) ||
1570 nla_put_u32(vendor_event,
1571 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
1572 pWifiChannelStats->ccaBusyTime))
1573 {
1574 hddLog(VOS_TRACE_LEVEL_ERROR,
1575 FL("cfg80211_vendor_event_alloc failed") );
1576 kfree_skb(vendor_event);
1577 return ;
1578 }
1579 nla_nest_end(vendor_event, chInfo);
1580 }
1581 nla_nest_end(vendor_event, chList);
1582
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301583 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301584
1585 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301586 return;
1587}
1588
1589/*
1590 * hdd_link_layer_stats_ind_callback () - This function is called after
1591 * receiving Link Layer indications from FW.This callback converts the firmware
1592 * data to the NL data and send the same to the kernel/upper layers.
1593 */
1594static void hdd_link_layer_stats_ind_callback ( void *pCtx,
1595 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05301596 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301597{
Dino Mycled3d50022014-07-07 12:58:25 +05301598 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
1599 hdd_adapter_t *pAdapter = NULL;
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301600 struct hdd_ll_stats_context *context;
Dino Mycled3d50022014-07-07 12:58:25 +05301601 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301602 int status;
1603
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301604 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301605
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301606 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301607 if (0 != status)
1608 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301609 return;
1610 }
1611
Dino Mycled3d50022014-07-07 12:58:25 +05301612 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
1613 if (NULL == pAdapter)
1614 {
1615 hddLog(VOS_TRACE_LEVEL_ERROR,
1616 FL(" MAC address %pM does not exist with host"),
1617 macAddr);
1618 return;
1619 }
1620
Sunil Duttc69bccb2014-05-26 21:30:20 +05301621 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301622 "%s: Interface: %s LLStats indType: %d", __func__,
1623 pAdapter->dev->name, indType);
1624
Sunil Duttc69bccb2014-05-26 21:30:20 +05301625 switch (indType)
1626 {
1627 case SIR_HAL_LL_STATS_RESULTS_RSP:
1628 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301629 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301630 "LL_STATS RESP paramID = 0x%x, ifaceId = %u MAC: %pM "
1631 "respId = %u, moreResultToFollow = %u",
1632 linkLayerStatsResults->paramId, linkLayerStatsResults->ifaceId,
1633 macAddr, linkLayerStatsResults->respId,
1634 linkLayerStatsResults->moreResultToFollow);
1635
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301636 spin_lock(&hdd_context_lock);
1637 context = &pHddCtx->ll_stats_context;
1638 /* validate response received from target */
1639 if ((context->request_id != linkLayerStatsResults->respId) ||
1640 !(context->request_bitmap & linkLayerStatsResults->paramId))
1641 {
1642 spin_unlock(&hdd_context_lock);
1643 hddLog(LOGE,
1644 FL("Error : Request id %d response id %d request bitmap 0x%x"
1645 "response bitmap 0x%x"),
1646 context->request_id, linkLayerStatsResults->respId,
1647 context->request_bitmap, linkLayerStatsResults->paramId);
1648 return;
1649 }
1650 spin_unlock(&hdd_context_lock);
1651
Sunil Duttc69bccb2014-05-26 21:30:20 +05301652 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
1653 {
1654 hdd_link_layer_process_radio_stats(pAdapter,
1655 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301656 spin_lock(&hdd_context_lock);
1657 context->request_bitmap &= ~(WMI_LINK_STATS_RADIO);
1658 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301659 }
1660 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
1661 {
1662 hdd_link_layer_process_iface_stats(pAdapter,
1663 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301664 spin_lock(&hdd_context_lock);
1665 context->request_bitmap &= ~(WMI_LINK_STATS_IFACE);
1666 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301667 }
1668 else if ( linkLayerStatsResults->paramId &
1669 WMI_LINK_STATS_ALL_PEER )
1670 {
1671 hdd_link_layer_process_peer_stats(pAdapter,
1672 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301673 spin_lock(&hdd_context_lock);
1674 context->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER);
1675 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301676 } /* WMI_LINK_STATS_ALL_PEER */
1677 else
1678 {
1679 hddLog(VOS_TRACE_LEVEL_ERROR,
1680 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
1681 }
1682
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301683 spin_lock(&hdd_context_lock);
1684 /* complete response event if all requests are completed */
1685 if (0 == context->request_bitmap)
1686 complete(&context->response_event);
1687 spin_unlock(&hdd_context_lock);
1688
Sunil Duttc69bccb2014-05-26 21:30:20 +05301689 break;
1690 }
1691 default:
1692 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
1693 break;
1694 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301695
1696 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301697 return;
1698}
1699
1700const struct
1701nla_policy
1702qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
1703{
1704 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
1705 { .type = NLA_U32 },
1706 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
1707 { .type = NLA_U32 },
1708};
1709
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301710static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1711 struct wireless_dev *wdev,
1712 const void *data,
1713 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301714{
1715 int status;
1716 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301717 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301718 struct net_device *dev = wdev->netdev;
1719 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1720 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1721
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301722 ENTER();
1723
Sunil Duttc69bccb2014-05-26 21:30:20 +05301724 status = wlan_hdd_validate_context(pHddCtx);
1725 if (0 != status)
1726 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301727 return -EINVAL;
1728 }
1729
1730 if (NULL == pAdapter)
1731 {
1732 hddLog(VOS_TRACE_LEVEL_ERROR,
1733 FL("HDD adapter is Null"));
1734 return -ENODEV;
1735 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301736 /* check the LLStats Capability */
1737 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1738 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1739 {
Anurag Chouhan65ea6dc2016-10-25 19:59:14 +05301740 hddLog(VOS_TRACE_LEVEL_WARN,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301741 FL("Link Layer Statistics not supported by Firmware"));
1742 return -EINVAL;
1743 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301744
1745 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1746 (struct nlattr *)data,
1747 data_len, qca_wlan_vendor_ll_set_policy))
1748 {
1749 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1750 return -EINVAL;
1751 }
1752 if (!tb_vendor
1753 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1754 {
1755 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1756 return -EINVAL;
1757 }
1758 if (!tb_vendor[
1759 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1760 {
1761 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1762 return -EINVAL;
1763 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301764 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301765 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301766
Dino Mycledf0a5d92014-07-04 09:41:55 +05301767 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301768 nla_get_u32(
1769 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1770
Dino Mycledf0a5d92014-07-04 09:41:55 +05301771 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301772 nla_get_u32(
1773 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1774
Dino Mycled3d50022014-07-07 12:58:25 +05301775 vos_mem_copy(linkLayerStatsSetReq.macAddr,
1776 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301777
1778
1779 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301780 "LL_STATS_SET reqId = %d, MAC = %pM, mpduSizeThreshold = %d "
1781 "Statistics Gathering = %d ",
1782 linkLayerStatsSetReq.reqId, linkLayerStatsSetReq.macAddr,
1783 linkLayerStatsSetReq.mpduSizeThreshold,
1784 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301785
1786 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1787 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05301788 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301789 {
1790 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1791 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301792 return -EINVAL;
1793
1794 }
Srinivas Dasari98947432014-11-07 19:41:24 +05301795
Sunil Duttc69bccb2014-05-26 21:30:20 +05301796 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301797 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301798 {
1799 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1800 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301801 return -EINVAL;
1802 }
1803
1804 pAdapter->isLinkLayerStatsSet = 1;
1805
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301806 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301807 return 0;
1808}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301809static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1810 struct wireless_dev *wdev,
1811 const void *data,
1812 int data_len)
1813{
1814 int ret = 0;
1815
1816 vos_ssr_protect(__func__);
1817 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
1818 vos_ssr_unprotect(__func__);
1819
1820 return ret;
1821}
Sunil Duttc69bccb2014-05-26 21:30:20 +05301822
1823const struct
1824nla_policy
1825qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1826{
1827 /* Unsigned 32bit value provided by the caller issuing the GET stats
1828 * command. When reporting
1829 * the stats results, the driver uses the same value to indicate
1830 * which GET request the results
1831 * correspond to.
1832 */
1833 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1834
1835 /* Unsigned 32bit value . bit mask to identify what statistics are
1836 requested for retrieval */
1837 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1838};
1839
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301840static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1841 struct wireless_dev *wdev,
1842 const void *data,
1843 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301844{
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301845 unsigned long rc;
1846 struct hdd_ll_stats_context *context;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301847 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1848 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301849 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301850 struct net_device *dev = wdev->netdev;
1851 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma10313ba2015-07-29 19:14:39 +05301852 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301853 int status;
1854
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301855 ENTER();
1856
Sunil Duttc69bccb2014-05-26 21:30:20 +05301857 status = wlan_hdd_validate_context(pHddCtx);
1858 if (0 != status)
1859 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301860 return -EINVAL ;
1861 }
1862
1863 if (NULL == pAdapter)
1864 {
1865 hddLog(VOS_TRACE_LEVEL_FATAL,
1866 "%s: HDD adapter is Null", __func__);
1867 return -ENODEV;
1868 }
Mukul Sharma10313ba2015-07-29 19:14:39 +05301869
1870 if (pHddStaCtx == NULL)
1871 {
1872 hddLog(VOS_TRACE_LEVEL_FATAL,
1873 "%s: HddStaCtx is Null", __func__);
1874 return -ENODEV;
1875 }
1876
Dino Mycledf0a5d92014-07-04 09:41:55 +05301877 /* check the LLStats Capability */
1878 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1879 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1880 {
1881 hddLog(VOS_TRACE_LEVEL_ERROR,
1882 FL("Link Layer Statistics not supported by Firmware"));
1883 return -EINVAL;
1884 }
1885
Sunil Duttc69bccb2014-05-26 21:30:20 +05301886
1887 if (!pAdapter->isLinkLayerStatsSet)
1888 {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05301889 hddLog(VOS_TRACE_LEVEL_ERROR,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301890 "%s: isLinkLayerStatsSet : %d",
1891 __func__, pAdapter->isLinkLayerStatsSet);
1892 return -EINVAL;
1893 }
1894
Mukul Sharma10313ba2015-07-29 19:14:39 +05301895 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
1896 {
1897 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1898 "%s: Roaming in progress, so unable to proceed this request", __func__);
1899 return -EBUSY;
1900 }
1901
Sunil Duttc69bccb2014-05-26 21:30:20 +05301902 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
1903 (struct nlattr *)data,
1904 data_len, qca_wlan_vendor_ll_get_policy))
1905 {
1906 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1907 return -EINVAL;
1908 }
1909
1910 if (!tb_vendor
1911 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
1912 {
1913 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
1914 return -EINVAL;
1915 }
1916
1917 if (!tb_vendor
1918 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
1919 {
1920 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
1921 return -EINVAL;
1922 }
1923
Sunil Duttc69bccb2014-05-26 21:30:20 +05301924
Dino Mycledf0a5d92014-07-04 09:41:55 +05301925 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301926 nla_get_u32( tb_vendor[
1927 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05301928 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301929 nla_get_u32( tb_vendor[
1930 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
1931
Dino Mycled3d50022014-07-07 12:58:25 +05301932 vos_mem_copy(linkLayerStatsGetReq.macAddr,
1933 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301934
1935 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301936 "LL_STATS_GET reqId = %d, MAC = %pM, paramIdMask = %d",
1937 linkLayerStatsGetReq.reqId, linkLayerStatsGetReq.macAddr,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301938 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301939
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301940 spin_lock(&hdd_context_lock);
1941 context = &pHddCtx->ll_stats_context;
1942 context->request_id = linkLayerStatsGetReq.reqId;
1943 context->request_bitmap = linkLayerStatsGetReq.paramIdMask;
1944 INIT_COMPLETION(context->response_event);
1945 spin_unlock(&hdd_context_lock);
1946
Sunil Duttc69bccb2014-05-26 21:30:20 +05301947 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301948 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301949 {
1950 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1951 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301952 return -EINVAL;
1953 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301954
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301955 rc = wait_for_completion_timeout(&context->response_event,
1956 msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS));
1957 if (!rc)
1958 {
1959 hddLog(LOGE,
1960 FL("Target response timed out request id %d request bitmap 0x%x"),
1961 context->request_id, context->request_bitmap);
1962 return -ETIMEDOUT;
1963 }
1964
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301965 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301966 return 0;
1967}
1968
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301969static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1970 struct wireless_dev *wdev,
1971 const void *data,
1972 int data_len)
1973{
1974 int ret = 0;
1975
1976 vos_ssr_protect(__func__);
1977 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
1978 vos_ssr_unprotect(__func__);
1979
1980 return ret;
1981}
1982
Sunil Duttc69bccb2014-05-26 21:30:20 +05301983const struct
1984nla_policy
1985qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
1986{
1987 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
1988 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
1989 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
1990 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
1991};
1992
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301993static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
1994 struct wireless_dev *wdev,
1995 const void *data,
1996 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301997{
1998 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1999 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302000 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302001 struct net_device *dev = wdev->netdev;
2002 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2003 u32 statsClearReqMask;
2004 u8 stopReq;
2005 int status;
2006
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302007 ENTER();
2008
Sunil Duttc69bccb2014-05-26 21:30:20 +05302009 status = wlan_hdd_validate_context(pHddCtx);
2010 if (0 != status)
2011 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302012 return -EINVAL;
2013 }
2014
2015 if (NULL == pAdapter)
2016 {
2017 hddLog(VOS_TRACE_LEVEL_FATAL,
2018 "%s: HDD adapter is Null", __func__);
2019 return -ENODEV;
2020 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302021 /* check the LLStats Capability */
2022 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2023 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2024 {
2025 hddLog(VOS_TRACE_LEVEL_ERROR,
2026 FL("Enable LLStats Capability"));
2027 return -EINVAL;
2028 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302029
2030 if (!pAdapter->isLinkLayerStatsSet)
2031 {
2032 hddLog(VOS_TRACE_LEVEL_FATAL,
2033 "%s: isLinkLayerStatsSet : %d",
2034 __func__, pAdapter->isLinkLayerStatsSet);
2035 return -EINVAL;
2036 }
2037
2038 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
2039 (struct nlattr *)data,
2040 data_len, qca_wlan_vendor_ll_clr_policy))
2041 {
2042 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2043 return -EINVAL;
2044 }
2045
2046 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
2047
2048 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
2049 {
2050 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
2051 return -EINVAL;
2052
2053 }
2054
Sunil Duttc69bccb2014-05-26 21:30:20 +05302055
Dino Mycledf0a5d92014-07-04 09:41:55 +05302056 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302057 nla_get_u32(
2058 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
2059
Dino Mycledf0a5d92014-07-04 09:41:55 +05302060 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302061 nla_get_u8(
2062 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
2063
2064 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302065 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302066
Dino Mycled3d50022014-07-07 12:58:25 +05302067 vos_mem_copy(linkLayerStatsClearReq.macAddr,
2068 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302069
2070 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302071 "LL_STATS_CLEAR reqId = %d, MAC = %pM,"
2072 "statsClearReqMask = 0x%X, stopReq = %d",
2073 linkLayerStatsClearReq.reqId,
2074 linkLayerStatsClearReq.macAddr,
2075 linkLayerStatsClearReq.statsClearReqMask,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302076 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302077
2078 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302079 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302080 {
2081 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05302082 hdd_station_ctx_t *pHddStaCtx;
2083
2084 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2085 if (VOS_STATUS_SUCCESS !=
2086 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2087 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
2088 {
2089 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2090 "WLANTL_ClearInterfaceStats Failed", __func__);
2091 return -EINVAL;
2092 }
2093 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
2094 (statsClearReqMask & WIFI_STATS_IFACE)) {
2095 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
2096 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
2097 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
2098 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
2099 }
2100
Sunil Duttc69bccb2014-05-26 21:30:20 +05302101 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
2102 2 * sizeof(u32) +
2103 NLMSG_HDRLEN);
2104
2105 if (temp_skbuff != NULL)
2106 {
2107
2108 if (nla_put_u32(temp_skbuff,
2109 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
2110 statsClearReqMask) ||
2111 nla_put_u32(temp_skbuff,
2112 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
2113 stopReq))
2114 {
2115 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
2116 kfree_skb(temp_skbuff);
2117 return -EINVAL;
2118 }
2119 /* If the ask is to stop the stats collection as part of clear
2120 * (stopReq = 1) , ensure that no further requests of get
2121 * go to the firmware by having isLinkLayerStatsSet set to 0.
2122 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302123 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05302124 * case the firmware is just asked to clear the statistics.
2125 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05302126 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302127 pAdapter->isLinkLayerStatsSet = 0;
2128 return cfg80211_vendor_cmd_reply(temp_skbuff);
2129 }
2130 return -ENOMEM;
2131 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302132
2133 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302134 return -EINVAL;
2135}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302136static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2137 struct wireless_dev *wdev,
2138 const void *data,
2139 int data_len)
2140{
2141 int ret = 0;
2142
2143 vos_ssr_protect(__func__);
2144 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
2145 vos_ssr_unprotect(__func__);
2146
2147 return ret;
2148
2149
2150}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302151#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
2152
Dino Mycle6fb96c12014-06-10 11:52:40 +05302153#ifdef WLAN_FEATURE_EXTSCAN
2154static const struct nla_policy
2155wlan_hdd_extscan_config_policy
2156 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
2157{
2158 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
2159 { .type = NLA_U32 },
2160 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
2161 { .type = NLA_U32 },
2162 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
2163 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
2164 { .type = NLA_U32 },
2165 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
2166 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
2167
2168 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
2169 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
2170 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
2171 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
2172 { .type = NLA_U8 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302173 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] =
2174 { .type = NLA_U32 },
2175 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT] =
2176 { .type = NLA_U32 },
2177 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] =
2178 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302179 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
2180 { .type = NLA_U32 },
2181 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
2182 { .type = NLA_U32 },
2183 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
2184 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302185 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] =
2186 { .type = NLA_U8 },
2187 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302188 { .type = NLA_U8 },
2189 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
2190 { .type = NLA_U8 },
2191 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
2192 { .type = NLA_U8 },
2193
2194 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
2195 { .type = NLA_U32 },
2196 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] =
2197 { .type = NLA_UNSPEC },
2198 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
2199 { .type = NLA_S32 },
2200 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
2201 { .type = NLA_S32 },
2202 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
2203 { .type = NLA_U32 },
2204 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
2205 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302206 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] =
2207 { .type = NLA_U32 },
2208 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] =
2209 { .type = NLA_BINARY,
2210 .len = IEEE80211_MAX_SSID_LEN + 1 },
2211 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302212 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302213 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] =
2214 { .type = NLA_U32 },
2215 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] =
2216 { .type = NLA_U8 },
2217 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] =
2218 { .type = NLA_S32 },
2219 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] =
2220 { .type = NLA_S32 },
2221 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] =
2222 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302223};
2224
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302225/**
2226 * wlan_hdd_cfg80211_extscan_get_capabilities_rsp() - response from target
2227 * @ctx: hdd global context
2228 * @data: capabilities data
2229 *
2230 * Return: none
2231 */
2232static void
2233wlan_hdd_cfg80211_extscan_get_capabilities_rsp(void *ctx, void *pMsg)
Dino Mycle6fb96c12014-06-10 11:52:40 +05302234{
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302235 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302236 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302237 tSirEXTScanCapabilitiesEvent *data =
2238 (tSirEXTScanCapabilitiesEvent *) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302239
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302240 ENTER();
2241
2242 if (wlan_hdd_validate_context(pHddCtx))
2243 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302244 return;
2245 }
2246
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302247 if (!pMsg)
2248 {
2249 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2250 return;
2251 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302252
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302253 vos_spin_lock_acquire(&hdd_context_lock);
2254
2255 context = &pHddCtx->ext_scan_context;
2256 /* validate response received from target*/
2257 if (context->request_id != data->requestId)
2258 {
2259 vos_spin_lock_release(&hdd_context_lock);
2260 hddLog(LOGE,
2261 FL("Target response id did not match: request_id %d resposne_id %d"),
2262 context->request_id, data->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302263 return;
2264 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302265 else
2266 {
2267 context->capability_response = *data;
2268 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302269 }
2270
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302271 vos_spin_lock_release(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302272
Dino Mycle6fb96c12014-06-10 11:52:40 +05302273 return;
2274}
2275
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302276/*
2277 * define short names for the global vendor params
2278 * used by wlan_hdd_send_ext_scan_capability()
2279 */
2280#define PARAM_REQUEST_ID \
2281 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
2282#define PARAM_STATUS \
2283 QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS
2284#define MAX_SCAN_CACHE_SIZE \
2285 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE
2286#define MAX_SCAN_BUCKETS \
2287 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS
2288#define MAX_AP_CACHE_PER_SCAN \
2289 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN
2290#define MAX_RSSI_SAMPLE_SIZE \
2291 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE
2292#define MAX_SCAN_RPT_THRHOLD \
2293 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
2294#define MAX_HOTLIST_BSSIDS \
2295 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS
2296#define MAX_BSSID_HISTORY_ENTRIES \
2297 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
2298#define MAX_HOTLIST_SSIDS \
2299 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302300#define MAX_SIGNIFICANT_WIFI_CHANGE_APS \
2301 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302302
2303static int wlan_hdd_send_ext_scan_capability(void *ctx)
2304{
2305 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2306 struct sk_buff *skb = NULL;
2307 int ret;
2308 tSirEXTScanCapabilitiesEvent *data;
2309 tANI_U32 nl_buf_len;
2310
2311 ret = wlan_hdd_validate_context(pHddCtx);
2312 if (0 != ret)
2313 {
2314 return ret;
2315 }
2316
2317 data = &(pHddCtx->ext_scan_context.capability_response);
2318
2319 nl_buf_len = NLMSG_HDRLEN;
2320 nl_buf_len += (sizeof(data->requestId) + NLA_HDRLEN) +
2321 (sizeof(data->status) + NLA_HDRLEN) +
2322 (sizeof(data->scanCacheSize) + NLA_HDRLEN) +
2323 (sizeof(data->scanBuckets) + NLA_HDRLEN) +
2324 (sizeof(data->maxApPerScan) + NLA_HDRLEN) +
2325 (sizeof(data->maxRssiSampleSize) + NLA_HDRLEN) +
2326 (sizeof(data->maxScanReportingThreshold) + NLA_HDRLEN) +
2327 (sizeof(data->maxHotlistAPs) + NLA_HDRLEN) +
2328 (sizeof(data->maxBsidHistoryEntries) + NLA_HDRLEN) +
2329 (sizeof(data->maxHotlistSSIDs) + NLA_HDRLEN);
2330
2331 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, nl_buf_len);
2332
2333 if (!skb)
2334 {
2335 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
2336 return -ENOMEM;
2337 }
2338
2339 hddLog(LOG1, "Req Id (%u) Status (%u)", data->requestId, data->status);
2340 hddLog(LOG1, "Scan cache size (%u) Scan buckets (%u) Max AP per scan (%u)",
2341 data->scanCacheSize, data->scanBuckets, data->maxApPerScan);
2342 hddLog(LOG1, "max_rssi_sample_size (%u) max_scan_reporting_threshold (%u)",
2343 data->maxRssiSampleSize, data->maxScanReportingThreshold);
2344 hddLog(LOG1, "max_hotlist_bssids (%u) max_bssid_history_entries (%u)"
2345 "max_hotlist_ssids (%u)", data->maxHotlistAPs,
2346 data->maxBsidHistoryEntries, data->maxHotlistSSIDs);
2347
2348 if (nla_put_u32(skb, PARAM_REQUEST_ID, data->requestId) ||
2349 nla_put_u32(skb, PARAM_STATUS, data->status) ||
2350 nla_put_u32(skb, MAX_SCAN_CACHE_SIZE, data->scanCacheSize) ||
2351 nla_put_u32(skb, MAX_SCAN_BUCKETS, data->scanBuckets) ||
2352 nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN,
2353 data->maxApPerScan) ||
2354 nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE,
2355 data->maxRssiSampleSize) ||
2356 nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD,
2357 data->maxScanReportingThreshold) ||
2358 nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->maxHotlistAPs) ||
2359 nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES,
2360 data->maxBsidHistoryEntries) ||
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302361 nla_put_u32(skb, MAX_HOTLIST_SSIDS, data->maxHotlistSSIDs) ||
2362 nla_put_u32(skb, MAX_SIGNIFICANT_WIFI_CHANGE_APS, 0))
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302363 {
2364 hddLog(LOGE, FL("nla put fail"));
2365 goto nla_put_failure;
2366 }
2367
2368 cfg80211_vendor_cmd_reply(skb);
2369 return 0;
2370
2371nla_put_failure:
2372 kfree_skb(skb);
2373 return -EINVAL;;
2374}
2375
2376/*
2377 * done with short names for the global vendor params
2378 * used by wlan_hdd_send_ext_scan_capability()
2379 */
2380#undef PARAM_REQUEST_ID
2381#undef PARAM_STATUS
2382#undef MAX_SCAN_CACHE_SIZE
2383#undef MAX_SCAN_BUCKETS
2384#undef MAX_AP_CACHE_PER_SCAN
2385#undef MAX_RSSI_SAMPLE_SIZE
2386#undef MAX_SCAN_RPT_THRHOLD
2387#undef MAX_HOTLIST_BSSIDS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302388#undef MAX_BSSID_HISTORY_ENTRIES
2389#undef MAX_HOTLIST_SSIDS
Dino Mycle6fb96c12014-06-10 11:52:40 +05302390
2391static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
2392{
2393 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
2394 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302395 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302396 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302397
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302398 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302399
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302400 if (wlan_hdd_validate_context(pHddCtx))
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302401 return;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302402
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302403 if (!pMsg)
2404 {
2405 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302406 return;
2407 }
2408
Dino Mycle6fb96c12014-06-10 11:52:40 +05302409 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2410 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2411
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302412 context = &pHddCtx->ext_scan_context;
2413 spin_lock(&hdd_context_lock);
2414 if (context->request_id == pData->requestId) {
2415 context->response_status = pData->status ? -EINVAL : 0;
2416 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302417 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302418 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302419
2420 /*
2421 * Store the Request ID for comparing with the requestID obtained
2422 * in other requests.HDD shall return a failure is the extscan_stop
2423 * request is issued with a different requestId as that of the
2424 * extscan_start request. Also, This requestId shall be used while
2425 * indicating the full scan results to the upper layers.
2426 * The requestId is stored with the assumption that the firmware
2427 * shall return the ext scan start request's requestId in ext scan
2428 * start response.
2429 */
2430 if (pData->status == 0)
2431 pMac->sme.extScanStartReqId = pData->requestId;
2432
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302433 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302434 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302435}
2436
2437
2438static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2439{
2440 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2441 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302442 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302443
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302444 ENTER();
2445
2446 if (wlan_hdd_validate_context(pHddCtx)){
2447 return;
2448 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302449
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302450 if (!pMsg)
2451 {
2452 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302453 return;
2454 }
2455
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302456 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2457 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302458
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302459 context = &pHddCtx->ext_scan_context;
2460 spin_lock(&hdd_context_lock);
2461 if (context->request_id == pData->requestId) {
2462 context->response_status = pData->status ? -EINVAL : 0;
2463 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302464 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302465 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302466
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302467 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302468 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302469}
2470
Dino Mycle6fb96c12014-06-10 11:52:40 +05302471static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2472 void *pMsg)
2473{
2474 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302475 tpSirEXTScanSetBssidHotListRspParams pData =
2476 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302477 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302478
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302479 ENTER();
2480
2481 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05302482 return;
2483 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302484
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302485 if (!pMsg)
2486 {
2487 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2488 return;
2489 }
2490
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302491 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2492 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302493
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302494 context = &pHddCtx->ext_scan_context;
2495 spin_lock(&hdd_context_lock);
2496 if (context->request_id == pData->requestId) {
2497 context->response_status = pData->status ? -EINVAL : 0;
2498 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302499 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302500 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302501
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302502 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302503 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302504}
2505
2506static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2507 void *pMsg)
2508{
2509 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302510 tpSirEXTScanResetBssidHotlistRspParams pData =
2511 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302512 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302513
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302514 ENTER();
2515
2516 if (wlan_hdd_validate_context(pHddCtx)) {
2517 return;
2518 }
2519 if (!pMsg)
2520 {
2521 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302522 return;
2523 }
2524
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302525 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2526 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302527
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302528 context = &pHddCtx->ext_scan_context;
2529 spin_lock(&hdd_context_lock);
2530 if (context->request_id == pData->requestId) {
2531 context->response_status = pData->status ? -EINVAL : 0;
2532 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302533 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302534 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302535
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302536 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302537 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302538}
2539
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05302540static void wlan_hdd_cfg80211_extscan_set_ssid_hotlist_rsp(void *ctx,
2541 void *pMsg)
2542{
2543 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2544 tpSirEXTScanSetSsidHotListRspParams pData =
2545 (tpSirEXTScanSetSsidHotListRspParams) pMsg;
2546 struct hdd_ext_scan_context *context;
2547
2548 if (wlan_hdd_validate_context(pHddCtx)){
2549 return;
2550 }
2551
2552 if (!pMsg)
2553 {
2554 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2555 return;
2556 }
2557
2558 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2559 pData->status);
2560
2561 context = &pHddCtx->ext_scan_context;
2562 spin_lock(&hdd_context_lock);
2563 if (context->request_id == pData->requestId) {
2564 context->response_status = pData->status ? -EINVAL : 0;
2565 complete(&context->response_event);
2566 }
2567 spin_unlock(&hdd_context_lock);
2568
2569 return;
2570}
2571
2572static void wlan_hdd_cfg80211_extscan_reset_ssid_hotlist_rsp(void *ctx,
2573 void *pMsg)
2574{
2575 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2576 tpSirEXTScanResetSsidHotlistRspParams pData =
2577 (tpSirEXTScanResetSsidHotlistRspParams) pMsg;
2578 struct hdd_ext_scan_context *context;
2579
2580 if (wlan_hdd_validate_context(pHddCtx)) {
2581 return;
2582 }
2583 if (!pMsg)
2584 {
2585 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2586 return;
2587 }
2588
2589 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2590 pData->status);
2591
2592 context = &pHddCtx->ext_scan_context;
2593 spin_lock(&hdd_context_lock);
2594 if (context->request_id == pData->requestId) {
2595 context->response_status = pData->status ? -EINVAL : 0;
2596 complete(&context->response_event);
2597 }
2598 spin_unlock(&hdd_context_lock);
2599
2600 return;
2601}
2602
2603
Dino Mycle6fb96c12014-06-10 11:52:40 +05302604static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2605 void *pMsg)
2606{
2607 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2608 struct sk_buff *skb = NULL;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302609 tANI_U32 i = 0, j, resultsPerEvent, scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302610 tANI_S32 totalResults;
2611 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302612 tpSirWifiScanResult pSirWifiScanResult, head_ptr;
2613 struct hdd_ext_scan_context *context;
2614 bool ignore_cached_results = false;
2615 tExtscanCachedScanResult *result;
2616 struct nlattr *nla_results;
2617 tANI_U16 ieLength= 0;
2618 tANI_U8 *ie = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302619
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302620 ENTER();
2621
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302622 if (wlan_hdd_validate_context(pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302623 return;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302624
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302625 if (!pMsg)
2626 {
2627 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2628 return;
2629 }
2630
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302631 spin_lock(&hdd_context_lock);
2632 context = &pHddCtx->ext_scan_context;
2633 ignore_cached_results = context->ignore_cached_results;
2634 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302635
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302636 if (ignore_cached_results) {
2637 hddLog(LOGE,
2638 FL("Ignore the cached results received after timeout"));
2639 return;
2640 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302641
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302642 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u More Data %u No of scan ids %u",
2643 pData->requestId, pData->moreData, pData->scanResultSize);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302644
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302645 result = (tExtscanCachedScanResult *)&(pData->result);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302646
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302647 for (scan_id_index = 0; scan_id_index < pData->scanResultSize;
2648 scan_id_index++) {
2649 result+= scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302650
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302651 totalResults = result->num_results;
2652 hddLog(VOS_TRACE_LEVEL_INFO, "scan_id %u flags %u Num results %u",
2653 result->scan_id, result->flags, totalResults);
2654 i = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302655
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302656 do{
2657 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2658 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2659 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302660
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302661 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2662 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN);
2663
2664 if (!skb) {
2665 hddLog(VOS_TRACE_LEVEL_ERROR,
2666 FL("cfg80211_vendor_event_alloc failed"));
2667 return;
2668 }
2669
2670 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2671
2672 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2673 pData->requestId) ||
2674 nla_put_u32(skb,
2675 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2676 resultsPerEvent)) {
2677 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2678 goto fail;
2679 }
2680 if (nla_put_u8(skb,
2681 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2682 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302683 {
2684 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2685 goto fail;
2686 }
2687
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302688 if (nla_put_u32(skb,
2689 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
2690 result->scan_id)) {
2691 hddLog(LOGE, FL("put fail"));
2692 goto fail;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302693 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302694
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302695 nla_results = nla_nest_start(skb,
2696 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_LIST);
2697 if (!nla_results)
2698 goto fail;
2699
2700 if (resultsPerEvent) {
2701 struct nlattr *aps;
2702 struct nlattr *nla_result;
2703
2704 nla_result = nla_nest_start(skb, scan_id_index);
2705 if(!nla_result)
2706 goto fail;
2707
2708 if (nla_put_u32(skb,
2709 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
2710 result->scan_id) ||
2711 nla_put_u32(skb,
2712 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_FLAGS,
2713 result->flags) ||
2714 nla_put_u32(skb,
2715 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2716 totalResults)) {
2717 hddLog(LOGE, FL("put fail"));
2718 goto fail;
2719 }
2720
2721 aps = nla_nest_start(skb,
2722 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2723 if (!aps)
2724 {
2725 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2726 goto fail;
2727 }
2728
2729 head_ptr = (tpSirWifiScanResult) &(result->ap);
2730
2731 for (j = 0; j < resultsPerEvent; j++, i++) {
2732 struct nlattr *ap;
2733 pSirWifiScanResult = head_ptr + i;
2734
2735 /*
Srinivas Dasari91727c12016-03-23 17:59:06 +05302736 * Firmware returns timestamp from extscan_start till
2737 * BSSID was cached (in micro seconds). Add this with
2738 * time gap between system boot up to extscan_start
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302739 * to derive the time since boot when the
2740 * BSSID was cached.
2741 */
Srinivas Dasari91727c12016-03-23 17:59:06 +05302742 pSirWifiScanResult->ts +=
2743 pHddCtx->extscan_start_time_since_boot;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302744 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2745 "Ssid (%s)"
2746 "Bssid: %pM "
2747 "Channel (%u)"
2748 "Rssi (%d)"
2749 "RTT (%u)"
2750 "RTT_SD (%u)"
2751 "Beacon Period %u"
2752 "Capability 0x%x "
2753 "Ie length %d",
2754 i,
2755 pSirWifiScanResult->ts,
2756 pSirWifiScanResult->ssid,
2757 pSirWifiScanResult->bssid,
2758 pSirWifiScanResult->channel,
2759 pSirWifiScanResult->rssi,
2760 pSirWifiScanResult->rtt,
2761 pSirWifiScanResult->rtt_sd,
2762 pSirWifiScanResult->beaconPeriod,
2763 pSirWifiScanResult->capability,
2764 ieLength);
2765
2766 ap = nla_nest_start(skb, j + 1);
2767 if (!ap)
2768 {
2769 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2770 goto fail;
2771 }
2772
2773 if (nla_put_u64(skb,
2774 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2775 pSirWifiScanResult->ts) )
2776 {
2777 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2778 goto fail;
2779 }
2780 if (nla_put(skb,
2781 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2782 sizeof(pSirWifiScanResult->ssid),
2783 pSirWifiScanResult->ssid) )
2784 {
2785 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2786 goto fail;
2787 }
2788 if (nla_put(skb,
2789 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2790 sizeof(pSirWifiScanResult->bssid),
2791 pSirWifiScanResult->bssid) )
2792 {
2793 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2794 goto fail;
2795 }
2796 if (nla_put_u32(skb,
2797 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2798 pSirWifiScanResult->channel) )
2799 {
2800 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2801 goto fail;
2802 }
2803 if (nla_put_s32(skb,
2804 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2805 pSirWifiScanResult->rssi) )
2806 {
2807 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2808 goto fail;
2809 }
2810 if (nla_put_u32(skb,
2811 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2812 pSirWifiScanResult->rtt) )
2813 {
2814 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2815 goto fail;
2816 }
2817 if (nla_put_u32(skb,
2818 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2819 pSirWifiScanResult->rtt_sd))
2820 {
2821 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2822 goto fail;
2823 }
2824 if (nla_put_u32(skb,
2825 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
2826 pSirWifiScanResult->beaconPeriod))
2827 {
2828 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2829 goto fail;
2830 }
2831 if (nla_put_u32(skb,
2832 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
2833 pSirWifiScanResult->capability))
2834 {
2835 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2836 goto fail;
2837 }
2838 if (nla_put_u32(skb,
2839 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
2840 ieLength))
2841 {
2842 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2843 goto fail;
2844 }
2845
2846 if (ieLength)
2847 if (nla_put(skb,
2848 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
2849 ieLength, ie)) {
2850 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2851 goto fail;
2852 }
2853
2854 nla_nest_end(skb, ap);
2855 }
2856 nla_nest_end(skb, aps);
2857 nla_nest_end(skb, nla_result);
2858 }
2859
2860 nla_nest_end(skb, nla_results);
2861
2862 cfg80211_vendor_cmd_reply(skb);
2863
2864 } while (totalResults > 0);
2865 }
2866
2867 if (!pData->moreData) {
2868 spin_lock(&hdd_context_lock);
2869 context->response_status = 0;
2870 complete(&context->response_event);
2871 spin_unlock(&hdd_context_lock);
2872 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302873
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302874 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302875 return;
2876fail:
2877 kfree_skb(skb);
2878 return;
2879}
2880
2881static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
2882 void *pMsg)
2883{
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302884 tpSirEXTScanHotlistMatch pData = (tpSirEXTScanHotlistMatch) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302885 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2886 struct sk_buff *skb = NULL;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302887 tANI_U32 i, index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302888
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302889 ENTER();
2890
2891 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302892 hddLog(LOGE,
2893 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302894 return;
2895 }
2896 if (!pMsg)
2897 {
2898 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302899 return;
2900 }
2901
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302902 if (pData->bss_found)
2903 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX;
2904 else
2905 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX;
2906
Dino Mycle6fb96c12014-06-10 11:52:40 +05302907 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302908#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2909 NULL,
2910#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302911 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302912 index, GFP_KERNEL);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302913
2914 if (!skb) {
2915 hddLog(VOS_TRACE_LEVEL_ERROR,
2916 FL("cfg80211_vendor_event_alloc failed"));
2917 return;
2918 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302919
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302920 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2921 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numHotlistBss);
2922 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2923 hddLog(VOS_TRACE_LEVEL_INFO, "ap_found %u", pData->bss_found);
2924
2925 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302926 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
2927 "Ssid (%s) "
2928 "Bssid (" MAC_ADDRESS_STR ") "
2929 "Channel (%u) "
2930 "Rssi (%d) "
2931 "RTT (%u) "
2932 "RTT_SD (%u) ",
2933 i,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302934 pData->bssHotlist[i].ts,
2935 pData->bssHotlist[i].ssid,
2936 MAC_ADDR_ARRAY(pData->bssHotlist[i].bssid),
2937 pData->bssHotlist[i].channel,
2938 pData->bssHotlist[i].rssi,
2939 pData->bssHotlist[i].rtt,
2940 pData->bssHotlist[i].rtt_sd);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302941 }
2942
2943 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2944 pData->requestId) ||
2945 nla_put_u32(skb,
2946 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302947 pData->numHotlistBss)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302948 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2949 goto fail;
2950 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302951 if (pData->numHotlistBss) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302952 struct nlattr *aps;
2953
2954 aps = nla_nest_start(skb,
2955 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2956 if (!aps)
2957 goto fail;
2958
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302959 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302960 struct nlattr *ap;
2961
2962 ap = nla_nest_start(skb, i + 1);
2963 if (!ap)
2964 goto fail;
2965
2966 if (nla_put_u64(skb,
2967 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302968 pData->bssHotlist[i].ts) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302969 nla_put(skb,
2970 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302971 sizeof(pData->bssHotlist[i].ssid),
2972 pData->bssHotlist[i].ssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302973 nla_put(skb,
2974 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302975 sizeof(pData->bssHotlist[i].bssid),
2976 pData->bssHotlist[i].bssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302977 nla_put_u32(skb,
2978 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302979 pData->bssHotlist[i].channel) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302980 nla_put_s32(skb,
2981 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302982 pData->bssHotlist[i].rssi) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302983 nla_put_u32(skb,
2984 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302985 pData->bssHotlist[i].rtt) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302986 nla_put_u32(skb,
2987 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302988 pData->bssHotlist[i].rtt_sd))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302989 goto fail;
2990
2991 nla_nest_end(skb, ap);
2992 }
2993 nla_nest_end(skb, aps);
2994
2995 if (nla_put_u8(skb,
2996 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2997 pData->moreData))
2998 goto fail;
2999 }
3000
3001 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303002 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303003 return;
3004
3005fail:
3006 kfree_skb(skb);
3007 return;
3008
3009}
Dino Mycle6fb96c12014-06-10 11:52:40 +05303010
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303011/**
3012 * wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind() -
3013 * Handle an SSID hotlist match event
3014 * @ctx: HDD context registered with SME
3015 * @event: The SSID hotlist match event
3016 *
3017 * This function will take an SSID match event that was generated by
3018 * firmware and will convert it into a cfg80211 vendor event which is
3019 * sent to userspace.
3020 *
3021 * Return: none
3022 */
3023static void
3024wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind(void *ctx,
3025 void *pMsg)
3026{
3027 hdd_context_t *hdd_ctx = ctx;
3028 struct sk_buff *skb;
3029 tANI_U32 i, index;
3030 tpSirEXTScanSsidHotlistMatch pData = (tpSirEXTScanSsidHotlistMatch) pMsg;
3031
3032 ENTER();
3033
3034 if (wlan_hdd_validate_context(hdd_ctx)) {
3035 hddLog(LOGE,
3036 FL("HDD context is not valid or response"));
3037 return;
3038 }
3039 if (!pMsg)
3040 {
3041 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3042 return;
3043 }
3044
3045 if (pData->ssid_found) {
3046 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND_INDEX;
3047 hddLog(LOG1, "SSID hotlist found");
3048 } else {
3049 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST_INDEX;
3050 hddLog(LOG1, "SSID hotlist lost");
3051 }
3052
3053 skb = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
3054#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3055 NULL,
3056#endif
3057 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3058 index, GFP_KERNEL);
3059
3060 if (!skb) {
3061 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
3062 return;
3063 }
3064 hddLog(LOG1, "Req Id %u, Num of SSIDs %u, More Data (%u)",
3065 pData->requestId, pData->numHotlistSsid, pData->moreData);
3066
3067 for (i = 0; i < pData->numHotlistSsid; i++) {
3068 hddLog(LOG1, "[i=%d] Timestamp %llu "
3069 "Ssid: %s "
3070 "Bssid (" MAC_ADDRESS_STR ") "
3071 "Channel %u "
3072 "Rssi %d "
3073 "RTT %u "
3074 "RTT_SD %u",
3075 i,
3076 pData->ssidHotlist[i].ts,
3077 pData->ssidHotlist[i].ssid,
3078 MAC_ADDR_ARRAY(pData->ssidHotlist[i].bssid),
3079 pData->ssidHotlist[i].channel,
3080 pData->ssidHotlist[i].rssi,
3081 pData->ssidHotlist[i].rtt,
3082 pData->ssidHotlist[i].rtt_sd);
3083 }
3084
3085 if (nla_put_u32(skb,
3086 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3087 pData->requestId) ||
3088 nla_put_u32(skb,
3089 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3090 pData->numHotlistSsid)) {
3091 hddLog(LOGE, FL("put fail"));
3092 goto fail;
3093 }
3094
3095 if (pData->numHotlistSsid) {
3096 struct nlattr *aps;
3097 aps = nla_nest_start(skb,
3098 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3099 if (!aps) {
3100 hddLog(LOGE, FL("nest fail"));
3101 goto fail;
3102 }
3103
3104 for (i = 0; i < pData->numHotlistSsid; i++) {
3105 struct nlattr *ap;
3106
3107 ap = nla_nest_start(skb, i);
3108 if (!ap) {
3109 hddLog(LOGE, FL("nest fail"));
3110 goto fail;
3111 }
3112
3113 if (nla_put_u64(skb,
3114 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3115 pData->ssidHotlist[i].ts) ||
3116 nla_put(skb,
3117 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3118 sizeof(pData->ssidHotlist[i].ssid),
3119 pData->ssidHotlist[i].ssid) ||
3120 nla_put(skb,
3121 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3122 sizeof(pData->ssidHotlist[i].bssid),
3123 pData->ssidHotlist[i].bssid) ||
3124 nla_put_u32(skb,
3125 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3126 pData->ssidHotlist[i].channel) ||
3127 nla_put_s32(skb,
3128 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
3129 pData->ssidHotlist[i].rssi) ||
3130 nla_put_u32(skb,
3131 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3132 pData->ssidHotlist[i].rtt) ||
3133 nla_put_u32(skb,
3134 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3135 pData->ssidHotlist[i].rtt_sd)) {
3136 hddLog(LOGE, FL("put fail"));
3137 goto fail;
3138 }
3139 nla_nest_end(skb, ap);
3140 }
3141 nla_nest_end(skb, aps);
3142
3143 if (nla_put_u8(skb,
3144 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3145 pData->moreData)) {
3146 hddLog(LOGE, FL("put fail"));
3147 goto fail;
3148 }
3149 }
3150
3151 cfg80211_vendor_event(skb, GFP_KERNEL);
3152 return;
3153
3154fail:
3155 kfree_skb(skb);
3156 return;
3157
3158}
3159
3160
Dino Mycle6fb96c12014-06-10 11:52:40 +05303161static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
3162 void *pMsg)
3163{
3164 struct sk_buff *skb;
3165 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3166 tpSirWifiFullScanResultEvent pData =
3167 (tpSirWifiFullScanResultEvent) (pMsg);
3168
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303169 ENTER();
3170
3171 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303172 hddLog(LOGE,
3173 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303174 return;
3175 }
3176 if (!pMsg)
3177 {
3178 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303179 return;
3180 }
3181
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303182 /*
3183 * If the full scan result including IE data exceeds NL 4K size
3184 * limitation, drop that beacon/probe rsp frame.
3185 */
3186 if ((sizeof(*pData) + pData->ieLength) >= EXTSCAN_EVENT_BUF_SIZE) {
3187 hddLog(LOGE, FL("Frame exceeded NL size limilation, drop it!"));
3188 return;
3189 }
3190
Dino Mycle6fb96c12014-06-10 11:52:40 +05303191 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303192#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3193 NULL,
3194#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303195 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3196 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
3197 GFP_KERNEL);
3198
3199 if (!skb) {
3200 hddLog(VOS_TRACE_LEVEL_ERROR,
3201 FL("cfg80211_vendor_event_alloc failed"));
3202 return;
3203 }
3204
Dino Mycle6fb96c12014-06-10 11:52:40 +05303205 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
3206 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
3207 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
3208 "Ssid (%s)"
3209 "Bssid (" MAC_ADDRESS_STR ")"
3210 "Channel (%u)"
3211 "Rssi (%d)"
3212 "RTT (%u)"
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303213 "RTT_SD (%u)"
3214 "Bcn Period %d"
3215 "Capability 0x%X "),
Dino Mycle6fb96c12014-06-10 11:52:40 +05303216 pData->ap.ts,
3217 pData->ap.ssid,
3218 MAC_ADDR_ARRAY(pData->ap.bssid),
3219 pData->ap.channel,
3220 pData->ap.rssi,
3221 pData->ap.rtt,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303222 pData->ap.rtt_sd,
3223 pData->ap.beaconPeriod,
3224 pData->ap.capability);
3225
Dino Mycle6fb96c12014-06-10 11:52:40 +05303226 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
3227 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3228 pData->requestId) ||
3229 nla_put_u64(skb,
3230 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3231 pData->ap.ts) ||
3232 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3233 sizeof(pData->ap.ssid),
3234 pData->ap.ssid) ||
3235 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3236 WNI_CFG_BSSID_LEN,
3237 pData->ap.bssid) ||
3238 nla_put_u32(skb,
3239 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3240 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05303241 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303242 pData->ap.rssi) ||
3243 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3244 pData->ap.rtt) ||
3245 nla_put_u32(skb,
3246 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3247 pData->ap.rtt_sd) ||
3248 nla_put_u16(skb,
3249 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3250 pData->ap.beaconPeriod) ||
3251 nla_put_u16(skb,
3252 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3253 pData->ap.capability) ||
3254 nla_put_u32(skb,
3255 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303256 pData->ieLength) ||
3257 nla_put_u8(skb,
3258 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3259 pData->moreData))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303260 {
3261 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3262 goto nla_put_failure;
3263 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303264
3265 if (pData->ieLength) {
3266 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3267 pData->ieLength,
3268 pData->ie))
3269 {
3270 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3271 goto nla_put_failure;
3272 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303273 }
3274
3275 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303276 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303277 return;
3278
3279nla_put_failure:
3280 kfree_skb(skb);
3281 return;
3282}
3283
3284static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
3285 void *pMsg)
3286{
3287 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3288 struct sk_buff *skb = NULL;
3289 tpSirEXTScanResultsAvailableIndParams pData =
3290 (tpSirEXTScanResultsAvailableIndParams) pMsg;
3291
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303292 ENTER();
3293
3294 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303295 hddLog(LOGE,
3296 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303297 return;
3298 }
3299 if (!pMsg)
3300 {
3301 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303302 return;
3303 }
3304
3305 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303306#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3307 NULL,
3308#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303309 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3310 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
3311 GFP_KERNEL);
3312
3313 if (!skb) {
3314 hddLog(VOS_TRACE_LEVEL_ERROR,
3315 FL("cfg80211_vendor_event_alloc failed"));
3316 return;
3317 }
3318
Dino Mycle6fb96c12014-06-10 11:52:40 +05303319 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3320 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
3321 pData->numResultsAvailable);
3322 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3323 pData->requestId) ||
3324 nla_put_u32(skb,
3325 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3326 pData->numResultsAvailable)) {
3327 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3328 goto nla_put_failure;
3329 }
3330
3331 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303332 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303333 return;
3334
3335nla_put_failure:
3336 kfree_skb(skb);
3337 return;
3338}
3339
3340static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
3341{
3342 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3343 struct sk_buff *skb = NULL;
3344 tpSirEXTScanProgressIndParams pData =
3345 (tpSirEXTScanProgressIndParams) pMsg;
3346
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303347 ENTER();
3348
3349 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303350 hddLog(LOGE,
3351 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303352 return;
3353 }
3354 if (!pMsg)
3355 {
3356 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303357 return;
3358 }
3359
3360 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303361#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3362 NULL,
3363#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303364 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3365 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
3366 GFP_KERNEL);
3367
3368 if (!skb) {
3369 hddLog(VOS_TRACE_LEVEL_ERROR,
3370 FL("cfg80211_vendor_event_alloc failed"));
3371 return;
3372 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303373 hddLog(VOS_TRACE_LEVEL_INFO, FL("Request Id (%u) "), pData->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303374 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
3375 pData->extScanEventType);
3376 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
3377 pData->status);
3378
3379 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
3380 pData->extScanEventType) ||
3381 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05303382 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3383 pData->requestId) ||
3384 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303385 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
3386 pData->status)) {
3387 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3388 goto nla_put_failure;
3389 }
3390
3391 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303392 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303393 return;
3394
3395nla_put_failure:
3396 kfree_skb(skb);
3397 return;
3398}
3399
3400void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
3401 void *pMsg)
3402{
3403 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3404
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303405 ENTER();
3406
Dino Mycle6fb96c12014-06-10 11:52:40 +05303407 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303408 return;
3409 }
3410
3411 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
3412
3413
3414 switch(evType) {
3415 case SIR_HAL_EXTSCAN_START_RSP:
3416 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
3417 break;
3418
3419 case SIR_HAL_EXTSCAN_STOP_RSP:
3420 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
3421 break;
3422 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
3423 /* There is no need to send this response to upper layer
3424 Just log the message */
3425 hddLog(VOS_TRACE_LEVEL_INFO,
3426 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
3427 break;
3428 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
3429 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
3430 break;
3431
3432 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
3433 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
3434 break;
3435
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303436 case SIR_HAL_EXTSCAN_SET_SSID_HOTLIST_RSP:
3437 wlan_hdd_cfg80211_extscan_set_ssid_hotlist_rsp(ctx, pMsg);
3438 break;
3439
3440 case SIR_HAL_EXTSCAN_RESET_SSID_HOTLIST_RSP:
3441 wlan_hdd_cfg80211_extscan_reset_ssid_hotlist_rsp(ctx, pMsg);
3442 break;
3443
Dino Mycle6fb96c12014-06-10 11:52:40 +05303444 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303445 wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx, pMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303446 break;
3447 case SIR_HAL_EXTSCAN_PROGRESS_IND:
3448 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
3449 break;
3450 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
3451 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
3452 break;
3453 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
3454 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
3455 break;
3456 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
3457 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
3458 break;
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303459 case SIR_HAL_EXTSCAN_SSID_HOTLIST_MATCH_IND:
3460 wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind(ctx, pMsg);
3461 break;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303462 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
3463 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
3464 break;
3465 default:
3466 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
3467 break;
3468 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303469 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303470}
3471
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303472static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3473 struct wireless_dev *wdev,
3474 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303475{
Dino Myclee8843b32014-07-04 14:21:45 +05303476 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303477 struct net_device *dev = wdev->netdev;
3478 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3479 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3480 struct nlattr
3481 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3482 eHalStatus status;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303483 struct hdd_ext_scan_context *context;
3484 unsigned long rc;
3485 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303486
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303487 ENTER();
3488
Dino Mycle6fb96c12014-06-10 11:52:40 +05303489 status = wlan_hdd_validate_context(pHddCtx);
3490 if (0 != status)
3491 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303492 return -EINVAL;
3493 }
Dino Myclee8843b32014-07-04 14:21:45 +05303494 /* check the EXTScan Capability */
3495 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303496 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3497 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303498 {
3499 hddLog(VOS_TRACE_LEVEL_ERROR,
3500 FL("EXTScan not enabled/supported by Firmware"));
3501 return -EINVAL;
3502 }
3503
Dino Mycle6fb96c12014-06-10 11:52:40 +05303504 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3505 data, dataLen,
3506 wlan_hdd_extscan_config_policy)) {
3507 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3508 return -EINVAL;
3509 }
3510
3511 /* Parse and fetch request Id */
3512 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3513 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3514 return -EINVAL;
3515 }
3516
Dino Myclee8843b32014-07-04 14:21:45 +05303517 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303518 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303519 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303520
Dino Myclee8843b32014-07-04 14:21:45 +05303521 reqMsg.sessionId = pAdapter->sessionId;
3522 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303523
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303524 vos_spin_lock_acquire(&hdd_context_lock);
3525 context = &pHddCtx->ext_scan_context;
3526 context->request_id = reqMsg.requestId;
3527 INIT_COMPLETION(context->response_event);
3528 vos_spin_lock_release(&hdd_context_lock);
3529
Dino Myclee8843b32014-07-04 14:21:45 +05303530 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303531 if (!HAL_STATUS_SUCCESS(status)) {
3532 hddLog(VOS_TRACE_LEVEL_ERROR,
3533 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303534 return -EINVAL;
3535 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303536
3537 rc = wait_for_completion_timeout(&context->response_event,
3538 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3539 if (!rc) {
3540 hddLog(LOGE, FL("Target response timed out"));
3541 return -ETIMEDOUT;
3542 }
3543
3544 ret = wlan_hdd_send_ext_scan_capability(pHddCtx);
3545 if (ret)
3546 hddLog(LOGE, FL("Failed to send ext scan capability to user space"));
3547
3548 return ret;
3549
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303550 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303551 return 0;
3552}
3553
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303554static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3555 struct wireless_dev *wdev,
3556 const void *data, int dataLen)
3557{
3558 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303559
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303560 vos_ssr_protect(__func__);
3561 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
3562 vos_ssr_unprotect(__func__);
3563
3564 return ret;
3565}
3566
3567static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3568 struct wireless_dev *wdev,
3569 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303570{
Dino Myclee8843b32014-07-04 14:21:45 +05303571 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303572 struct net_device *dev = wdev->netdev;
3573 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3574 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3575 struct nlattr
3576 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3577 eHalStatus status;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303578 struct hdd_ext_scan_context *context;
3579 unsigned long rc;
3580 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303581
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303582 ENTER();
3583
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303584 if (VOS_FTM_MODE == hdd_get_conparam()) {
3585 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3586 return -EINVAL;
3587 }
3588
Dino Mycle6fb96c12014-06-10 11:52:40 +05303589 status = wlan_hdd_validate_context(pHddCtx);
3590 if (0 != status)
3591 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303592 return -EINVAL;
3593 }
Dino Myclee8843b32014-07-04 14:21:45 +05303594 /* check the EXTScan Capability */
3595 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303596 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3597 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303598 {
3599 hddLog(VOS_TRACE_LEVEL_ERROR,
3600 FL("EXTScan not enabled/supported by Firmware"));
3601 return -EINVAL;
3602 }
3603
Dino Mycle6fb96c12014-06-10 11:52:40 +05303604 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3605 data, dataLen,
3606 wlan_hdd_extscan_config_policy)) {
3607 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3608 return -EINVAL;
3609 }
3610 /* Parse and fetch request Id */
3611 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3612 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3613 return -EINVAL;
3614 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303615
Dino Myclee8843b32014-07-04 14:21:45 +05303616 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303617 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3618
Dino Myclee8843b32014-07-04 14:21:45 +05303619 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303620
Dino Myclee8843b32014-07-04 14:21:45 +05303621 reqMsg.sessionId = pAdapter->sessionId;
3622 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303623
3624 /* Parse and fetch flush parameter */
3625 if (!tb
3626 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3627 {
3628 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3629 goto failed;
3630 }
Dino Myclee8843b32014-07-04 14:21:45 +05303631 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303632 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3633
Dino Myclee8843b32014-07-04 14:21:45 +05303634 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303635
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303636 spin_lock(&hdd_context_lock);
3637 context = &pHddCtx->ext_scan_context;
3638 context->request_id = reqMsg.requestId;
3639 context->ignore_cached_results = false;
3640 INIT_COMPLETION(context->response_event);
3641 spin_unlock(&hdd_context_lock);
3642
Dino Myclee8843b32014-07-04 14:21:45 +05303643 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303644 if (!HAL_STATUS_SUCCESS(status)) {
3645 hddLog(VOS_TRACE_LEVEL_ERROR,
3646 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303647 return -EINVAL;
3648 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303649
3650 rc = wait_for_completion_timeout(&context->response_event,
3651 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3652 if (!rc) {
3653 hddLog(LOGE, FL("Target response timed out"));
3654 retval = -ETIMEDOUT;
3655 spin_lock(&hdd_context_lock);
3656 context->ignore_cached_results = true;
3657 spin_unlock(&hdd_context_lock);
3658 } else {
3659 spin_lock(&hdd_context_lock);
3660 retval = context->response_status;
3661 spin_unlock(&hdd_context_lock);
3662 }
3663
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303664 EXIT();
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303665 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303666
3667failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303668 return -EINVAL;
3669}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303670static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3671 struct wireless_dev *wdev,
3672 const void *data, int dataLen)
3673{
3674 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303675
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303676 vos_ssr_protect(__func__);
3677 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
3678 vos_ssr_unprotect(__func__);
3679
3680 return ret;
3681}
3682
3683static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303684 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05303685 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303686{
3687 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3688 struct net_device *dev = wdev->netdev;
3689 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3690 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3691 struct nlattr
3692 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3693 struct nlattr
3694 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3695 struct nlattr *apTh;
3696 eHalStatus status;
3697 tANI_U8 i = 0;
3698 int rem;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303699 struct hdd_ext_scan_context *context;
3700 tANI_U32 request_id;
3701 unsigned long rc;
3702 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303703
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303704 ENTER();
3705
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303706 if (VOS_FTM_MODE == hdd_get_conparam()) {
3707 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3708 return -EINVAL;
3709 }
3710
Dino Mycle6fb96c12014-06-10 11:52:40 +05303711 status = wlan_hdd_validate_context(pHddCtx);
3712 if (0 != status)
3713 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303714 return -EINVAL;
3715 }
Dino Myclee8843b32014-07-04 14:21:45 +05303716 /* check the EXTScan Capability */
3717 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303718 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3719 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303720 {
3721 hddLog(VOS_TRACE_LEVEL_ERROR,
3722 FL("EXTScan not enabled/supported by Firmware"));
3723 return -EINVAL;
3724 }
3725
Dino Mycle6fb96c12014-06-10 11:52:40 +05303726 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3727 data, dataLen,
3728 wlan_hdd_extscan_config_policy)) {
3729 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3730 return -EINVAL;
3731 }
3732
3733 /* Parse and fetch request Id */
3734 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3735 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3736 return -EINVAL;
3737 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303738 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3739 vos_mem_malloc(sizeof(*pReqMsg));
3740 if (!pReqMsg) {
3741 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3742 return -ENOMEM;
3743 }
3744
Dino Myclee8843b32014-07-04 14:21:45 +05303745
Dino Mycle6fb96c12014-06-10 11:52:40 +05303746 pReqMsg->requestId = nla_get_u32(
3747 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3748 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3749
3750 /* Parse and fetch number of APs */
3751 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3752 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3753 goto fail;
3754 }
3755
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303756 /* Parse and fetch lost ap sample size */
3757 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]) {
3758 hddLog(LOGE, FL("attr lost ap sample size failed"));
3759 goto fail;
3760 }
3761
3762 pReqMsg->lostBssidSampleSize = nla_get_u32(
3763 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]);
3764 hddLog(LOG1, FL("Lost ap sample size %d"), pReqMsg->lostBssidSampleSize);
3765
Dino Mycle6fb96c12014-06-10 11:52:40 +05303766 pReqMsg->sessionId = pAdapter->sessionId;
3767 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3768
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303769 pReqMsg->numBssid = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303770 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05303771 if (pReqMsg->numBssid > WLAN_EXTSCAN_MAX_HOTLIST_APS) {
3772 hddLog(LOGE, FL("Number of AP: %u exceeds max: %u"),
3773 pReqMsg->numBssid, WLAN_EXTSCAN_MAX_HOTLIST_APS);
3774 goto fail;
3775 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303776 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numBssid);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303777
3778 nla_for_each_nested(apTh,
3779 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05303780 if (i == pReqMsg->numBssid) {
3781 hddLog(LOGW, FL("Ignoring excess AP"));
3782 break;
3783 }
3784
Dino Mycle6fb96c12014-06-10 11:52:40 +05303785 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3786 nla_data(apTh), nla_len(apTh),
3787 NULL)) {
3788 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3789 goto fail;
3790 }
3791
3792 /* Parse and fetch MAC address */
3793 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3794 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3795 goto fail;
3796 }
3797 memcpy(pReqMsg->ap[i].bssid, nla_data(
3798 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3799 sizeof(tSirMacAddr));
3800 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3801
3802 /* Parse and fetch low RSSI */
3803 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3804 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3805 goto fail;
3806 }
3807 pReqMsg->ap[i].low = nla_get_s32(
3808 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3809 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3810
3811 /* Parse and fetch high RSSI */
3812 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3813 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3814 goto fail;
3815 }
3816 pReqMsg->ap[i].high = nla_get_s32(
3817 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3818 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3819 pReqMsg->ap[i].high);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303820 i++;
3821 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303822
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05303823 if (i < pReqMsg->numBssid) {
3824 hddLog(LOGW, FL("Number of AP %u less than expected %u"),
3825 i, pReqMsg->numBssid);
3826 pReqMsg->numBssid = i;
3827 }
3828
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303829 context = &pHddCtx->ext_scan_context;
3830 spin_lock(&hdd_context_lock);
3831 INIT_COMPLETION(context->response_event);
3832 context->request_id = request_id = pReqMsg->requestId;
3833 spin_unlock(&hdd_context_lock);
3834
Dino Mycle6fb96c12014-06-10 11:52:40 +05303835 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3836 if (!HAL_STATUS_SUCCESS(status)) {
3837 hddLog(VOS_TRACE_LEVEL_ERROR,
3838 FL("sme_SetBssHotlist failed(err=%d)"), status);
3839 vos_mem_free(pReqMsg);
3840 return -EINVAL;
3841 }
3842
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303843 /* request was sent -- wait for the response */
3844 rc = wait_for_completion_timeout(&context->response_event,
3845 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3846
3847 if (!rc) {
3848 hddLog(LOGE, FL("sme_SetBssHotlist timed out"));
3849 retval = -ETIMEDOUT;
3850 } else {
3851 spin_lock(&hdd_context_lock);
3852 if (context->request_id == request_id)
3853 retval = context->response_status;
3854 else
3855 retval = -EINVAL;
3856 spin_unlock(&hdd_context_lock);
3857 }
3858
Dino Myclee8843b32014-07-04 14:21:45 +05303859 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303860 EXIT();
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303861 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303862
3863fail:
3864 vos_mem_free(pReqMsg);
3865 return -EINVAL;
3866}
3867
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303868static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3869 struct wireless_dev *wdev,
3870 const void *data, int dataLen)
3871{
3872 int ret = 0;
3873
3874 vos_ssr_protect(__func__);
3875 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
3876 dataLen);
3877 vos_ssr_unprotect(__func__);
3878
3879 return ret;
3880}
3881
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303882/*
3883 * define short names for the global vendor params
3884 * used by wlan_hdd_cfg80211_extscan_set_ssid_hotlist()
3885 */
3886#define PARAM_MAX \
3887QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
3888#define PARAM_REQUEST_ID \
3889QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
3890#define PARAMS_LOST_SSID_SAMPLE_SIZE \
3891QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE
3892#define PARAMS_NUM_SSID \
3893QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID
3894#define THRESHOLD_PARAM \
3895QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM
3896#define PARAM_SSID \
3897QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID
3898#define PARAM_BAND \
3899QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND
3900#define PARAM_RSSI_LOW \
3901QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW
3902#define PARAM_RSSI_HIGH \
3903QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH
3904
3905/**
3906 * __wlan_hdd_cfg80211_extscan_set_ssid_hotlist() - set ssid hot list
3907 * @wiphy: Pointer to wireless phy
3908 * @wdev: Pointer to wireless device
3909 * @data: Pointer to data
3910 * @data_len: Data length
3911 *
3912 * Return: 0 on success, negative errno on failure
3913 */
3914static int
3915__wlan_hdd_cfg80211_extscan_set_ssid_hotlist(struct wiphy *wiphy,
3916 struct wireless_dev *wdev,
3917 const void *data,
3918 int data_len)
3919{
3920 tSirEXTScanSetSsidHotListReqParams *request;
3921 struct net_device *dev = wdev->netdev;
3922 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
3923 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
3924 struct nlattr *tb[PARAM_MAX + 1];
3925 struct nlattr *tb2[PARAM_MAX + 1];
3926 struct nlattr *ssids;
3927 struct hdd_ext_scan_context *context;
3928 uint32_t request_id;
3929 char ssid_string[SIR_MAC_MAX_SSID_LENGTH + 1] = {'\0'};
3930 int ssid_len;
Anurag Chouhand64d5232016-08-29 17:01:38 +05303931 int ssid_length;
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303932 eHalStatus status;
3933 int i, rem, retval;
3934 unsigned long rc;
3935
3936 ENTER();
3937
3938 if (VOS_FTM_MODE == hdd_get_conparam()) {
3939 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3940 return -EINVAL;
3941 }
3942
3943 retval = wlan_hdd_validate_context(hdd_ctx);
3944 if (0 != retval) {
3945 hddLog(LOGE, FL("HDD context is not valid"));
3946 return -EINVAL;
3947 }
3948
3949 /* check the EXTScan Capability */
3950 if ( (TRUE != hdd_ctx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303951 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3952 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303953 {
3954 hddLog(VOS_TRACE_LEVEL_ERROR,
3955 FL("EXTScan not enabled/supported by Firmware"));
3956 return -EINVAL;
3957 }
3958
3959 if (nla_parse(tb, PARAM_MAX,
3960 data, data_len,
3961 wlan_hdd_extscan_config_policy)) {
3962 hddLog(LOGE, FL("Invalid ATTR"));
3963 return -EINVAL;
3964 }
3965
3966 request = vos_mem_malloc(sizeof(*request));
3967 if (!request) {
3968 hddLog(LOGE, FL("vos_mem_malloc failed"));
3969 return -ENOMEM;
3970 }
3971
3972 /* Parse and fetch request Id */
3973 if (!tb[PARAM_REQUEST_ID]) {
3974 hddLog(LOGE, FL("attr request id failed"));
3975 goto fail;
3976 }
3977
3978 request->request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
3979 hddLog(LOG1, FL("Request Id %d"), request->request_id);
3980
3981 /* Parse and fetch lost SSID sample size */
3982 if (!tb[PARAMS_LOST_SSID_SAMPLE_SIZE]) {
3983 hddLog(LOGE, FL("attr number of Ssid failed"));
3984 goto fail;
3985 }
3986 request->lost_ssid_sample_size =
3987 nla_get_u32(tb[PARAMS_LOST_SSID_SAMPLE_SIZE]);
3988 hddLog(LOG1, FL("Lost SSID Sample Size %d"),
3989 request->lost_ssid_sample_size);
3990
3991 /* Parse and fetch number of hotlist SSID */
3992 if (!tb[PARAMS_NUM_SSID]) {
3993 hddLog(LOGE, FL("attr number of Ssid failed"));
3994 goto fail;
3995 }
3996 request->ssid_count = nla_get_u32(tb[PARAMS_NUM_SSID]);
3997 hddLog(LOG1, FL("Number of SSID %d"), request->ssid_count);
3998
3999 request->session_id = adapter->sessionId;
4000 hddLog(LOG1, FL("Session Id (%d)"), request->session_id);
4001
4002 i = 0;
4003 nla_for_each_nested(ssids, tb[THRESHOLD_PARAM], rem) {
4004 if (i >= WLAN_EXTSCAN_MAX_HOTLIST_SSIDS) {
4005 hddLog(LOGE,
4006 FL("Too Many SSIDs, %d exceeds %d"),
4007 i, WLAN_EXTSCAN_MAX_HOTLIST_SSIDS);
4008 break;
4009 }
4010 if (nla_parse(tb2, PARAM_MAX,
4011 nla_data(ssids), nla_len(ssids),
4012 wlan_hdd_extscan_config_policy)) {
4013 hddLog(LOGE, FL("nla_parse failed"));
4014 goto fail;
4015 }
4016
4017 /* Parse and fetch SSID */
4018 if (!tb2[PARAM_SSID]) {
4019 hddLog(LOGE, FL("attr ssid failed"));
4020 goto fail;
4021 }
Anurag Chouhand64d5232016-08-29 17:01:38 +05304022 ssid_length = nla_strlcpy(ssid_string, tb2[PARAM_SSID],
4023 sizeof(ssid_string));
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05304024 hddLog(LOG1, FL("SSID %s"),
4025 ssid_string);
4026 ssid_len = strlen(ssid_string);
SaidiReddy Yenugae4f6f372016-12-06 16:11:39 +05304027 if (ssid_length >= SIR_MAC_MAX_SSID_LENGTH) {
Anurag Chouhand64d5232016-08-29 17:01:38 +05304028 hddLog(LOGE, FL("Invalid ssid length"));
4029 goto fail;
4030 }
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05304031 memcpy(request->ssid[i].ssid.ssId, ssid_string, ssid_len);
4032 request->ssid[i].ssid.length = ssid_len;
4033 request->ssid[i].ssid.ssId[ssid_len] = '\0';
4034 hddLog(LOG1, FL("After copying SSID %s"),
4035 request->ssid[i].ssid.ssId);
4036 hddLog(LOG1, FL("After copying length: %d"),
4037 ssid_len);
4038
4039 /* Parse and fetch low RSSI */
4040 if (!tb2[PARAM_BAND]) {
4041 hddLog(LOGE, FL("attr band failed"));
4042 goto fail;
4043 }
4044 request->ssid[i].band = nla_get_u8(tb2[PARAM_BAND]);
4045 hddLog(LOG1, FL("band %d"), request->ssid[i].band);
4046
4047 /* Parse and fetch low RSSI */
4048 if (!tb2[PARAM_RSSI_LOW]) {
4049 hddLog(LOGE, FL("attr low RSSI failed"));
4050 goto fail;
4051 }
4052 request->ssid[i].rssi_low = nla_get_s32(tb2[PARAM_RSSI_LOW]);
4053 hddLog(LOG1, FL("RSSI low %d"), request->ssid[i].rssi_low);
4054
4055 /* Parse and fetch high RSSI */
4056 if (!tb2[PARAM_RSSI_HIGH]) {
4057 hddLog(LOGE, FL("attr high RSSI failed"));
4058 goto fail;
4059 }
4060 request->ssid[i].rssi_high = nla_get_u32(tb2[PARAM_RSSI_HIGH]);
4061 hddLog(LOG1, FL("RSSI high %d"), request->ssid[i].rssi_high);
4062 i++;
4063 }
4064
4065 context = &hdd_ctx->ext_scan_context;
4066 spin_lock(&hdd_context_lock);
4067 INIT_COMPLETION(context->response_event);
4068 context->request_id = request_id = request->request_id;
4069 spin_unlock(&hdd_context_lock);
4070
4071 status = sme_set_ssid_hotlist(hdd_ctx->hHal, request);
4072 if (!HAL_STATUS_SUCCESS(status)) {
4073 hddLog(LOGE,
4074 FL("sme_set_ssid_hotlist failed(err=%d)"), status);
4075 goto fail;
4076 }
4077
4078 vos_mem_free(request);
4079
4080 /* request was sent -- wait for the response */
4081 rc = wait_for_completion_timeout(&context->response_event,
4082 msecs_to_jiffies
4083 (WLAN_WAIT_TIME_EXTSCAN));
4084 if (!rc) {
4085 hddLog(LOGE, FL("sme_set_ssid_hotlist timed out"));
4086 retval = -ETIMEDOUT;
4087 } else {
4088 spin_lock(&hdd_context_lock);
4089 if (context->request_id == request_id)
4090 retval = context->response_status;
4091 else
4092 retval = -EINVAL;
4093 spin_unlock(&hdd_context_lock);
4094 }
4095
4096 return retval;
4097
4098fail:
4099 vos_mem_free(request);
4100 return -EINVAL;
4101}
4102
4103/*
4104 * done with short names for the global vendor params
4105 * used by wlan_hdd_cfg80211_extscan_set_ssid_hotlist()
4106 */
4107#undef PARAM_MAX
4108#undef PARAM_REQUEST_ID
4109#undef PARAMS_NUM_SSID
4110#undef THRESHOLD_PARAM
4111#undef PARAM_SSID
4112#undef PARAM_BAND
4113#undef PARAM_RSSI_LOW
4114#undef PARAM_RSSI_HIGH
4115
4116static int wlan_hdd_cfg80211_extscan_set_ssid_hotlist(struct wiphy *wiphy,
4117 struct wireless_dev *wdev,
4118 const void *data, int dataLen)
4119{
4120 int ret = 0;
4121
4122 vos_ssr_protect(__func__);
4123 ret = __wlan_hdd_cfg80211_extscan_set_ssid_hotlist(wiphy, wdev, data,
4124 dataLen);
4125 vos_ssr_unprotect(__func__);
4126
4127 return ret;
4128}
4129
4130static int
4131__wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(struct wiphy *wiphy,
4132 struct wireless_dev *wdev,
4133 const void *data,
4134 int data_len)
4135{
4136 tSirEXTScanResetSsidHotlistReqParams request;
4137 struct net_device *dev = wdev->netdev;
4138 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
4139 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
4140 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4141 struct hdd_ext_scan_context *context;
4142 uint32_t request_id;
4143 eHalStatus status;
4144 int retval;
4145 unsigned long rc;
4146
4147 ENTER();
4148
4149 if (VOS_FTM_MODE == hdd_get_conparam()) {
4150 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4151 return -EINVAL;
4152 }
4153
4154 retval = wlan_hdd_validate_context(hdd_ctx);
4155 if (0 != retval) {
4156 hddLog(LOGE, FL("HDD context is not valid"));
4157 return -EINVAL;
4158 }
4159
4160 /* check the EXTScan Capability */
4161 if ( (TRUE != hdd_ctx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304162 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4163 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05304164 {
4165 hddLog(LOGE,
4166 FL("EXTScan not enabled/supported by Firmware"));
4167 return -EINVAL;
4168 }
4169
4170 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4171 data, data_len,
4172 wlan_hdd_extscan_config_policy)) {
4173 hddLog(LOGE, FL("Invalid ATTR"));
4174 return -EINVAL;
4175 }
4176
4177 /* Parse and fetch request Id */
4178 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4179 hddLog(LOGE, FL("attr request id failed"));
4180 return -EINVAL;
4181 }
4182
4183 request.requestId = nla_get_u32(
4184 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4185 request.sessionId = adapter->sessionId;
4186 hddLog(LOG1, FL("Request Id %d Session Id %d"), request.requestId,
4187 request.sessionId);
4188
4189 context = &hdd_ctx->ext_scan_context;
4190 spin_lock(&hdd_context_lock);
4191 INIT_COMPLETION(context->response_event);
4192 context->request_id = request_id = request.requestId;
4193 spin_unlock(&hdd_context_lock);
4194
4195 status = sme_reset_ssid_hotlist(hdd_ctx->hHal, &request);
4196 if (!HAL_STATUS_SUCCESS(status)) {
4197 hddLog(LOGE,
4198 FL("sme_reset_ssid_hotlist failed(err=%d)"), status);
4199 return -EINVAL;
4200 }
4201
4202 /* request was sent -- wait for the response */
4203 rc = wait_for_completion_timeout(&context->response_event,
4204 msecs_to_jiffies
4205 (WLAN_WAIT_TIME_EXTSCAN));
4206 if (!rc) {
4207 hddLog(LOGE, FL("sme_reset_ssid_hotlist timed out"));
4208 retval = -ETIMEDOUT;
4209 } else {
4210 spin_lock(&hdd_context_lock);
4211 if (context->request_id == request_id)
4212 retval = context->response_status;
4213 else
4214 retval = -EINVAL;
4215 spin_unlock(&hdd_context_lock);
4216 }
4217
4218 return retval;
4219}
4220
4221static int
4222wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(struct wiphy *wiphy,
4223 struct wireless_dev *wdev,
4224 const void *data,
4225 int data_len)
4226{
4227 int ret;
4228
4229 vos_ssr_protect(__func__);
4230 ret = __wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(wiphy, wdev,
4231 data, data_len);
4232 vos_ssr_unprotect(__func__);
4233
4234 return ret;
4235}
4236
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304237static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304238 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304239 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304240{
Agrawal Ashish16abf782016-08-18 22:42:59 +05304241 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4242 struct net_device *dev = wdev->netdev;
4243 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4244 uint32_t chan_list[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4245 uint8_t num_channels = 0;
4246 uint8_t num_chan_new = 0;
4247 uint8_t buf[256] = {0};
Dino Mycle6fb96c12014-06-10 11:52:40 +05304248 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304249 tANI_U32 requestId, maxChannels;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304250 tWifiBand wifiBand;
4251 eHalStatus status;
4252 struct sk_buff *replySkb;
Agrawal Ashish16abf782016-08-18 22:42:59 +05304253 tANI_U8 i,j,k;
4254 int ret,len = 0;;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304255
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304256 ENTER();
4257
Dino Mycle6fb96c12014-06-10 11:52:40 +05304258 status = wlan_hdd_validate_context(pHddCtx);
4259 if (0 != status)
4260 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304261 return -EINVAL;
4262 }
Dino Myclee8843b32014-07-04 14:21:45 +05304263
Dino Mycle6fb96c12014-06-10 11:52:40 +05304264 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4265 data, dataLen,
4266 wlan_hdd_extscan_config_policy)) {
4267 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4268 return -EINVAL;
4269 }
4270
4271 /* Parse and fetch request Id */
4272 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4273 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4274 return -EINVAL;
4275 }
4276 requestId = nla_get_u32(
4277 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4278 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
4279
4280 /* Parse and fetch wifi band */
4281 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
4282 {
4283 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4284 return -EINVAL;
4285 }
4286 wifiBand = nla_get_u32(
4287 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
4288 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
4289
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304290 /* Parse and fetch max channels */
4291 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
4292 {
4293 hddLog(LOGE, FL("attr max channels failed"));
4294 return -EINVAL;
4295 }
4296 maxChannels = nla_get_u32(
4297 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
4298 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);
4299
Dino Mycle6fb96c12014-06-10 11:52:40 +05304300 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
Agrawal Ashish16abf782016-08-18 22:42:59 +05304301 wifiBand, chan_list,
4302 &num_channels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304303 if (eHAL_STATUS_SUCCESS != status) {
4304 hddLog(VOS_TRACE_LEVEL_ERROR,
4305 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
4306 return -EINVAL;
4307 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304308
Agrawal Ashish16abf782016-08-18 22:42:59 +05304309 num_channels = VOS_MIN(num_channels, maxChannels);
4310 num_chan_new = num_channels;
4311 /* remove the indoor only channels if iface is SAP */
4312 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
4313 {
4314 num_chan_new = 0;
4315 for (i = 0; i < num_channels; i++)
4316 for (j = 0; j < IEEE80211_NUM_BANDS; j++) {
4317 if (wiphy->bands[j] == NULL)
4318 continue;
4319 for (k = 0; k < wiphy->bands[j]->n_channels; k++) {
4320 if ((chan_list[i] ==
4321 wiphy->bands[j]->channels[k].center_freq) &&
4322 (!(wiphy->bands[j]->channels[k].flags &
4323 IEEE80211_CHAN_INDOOR_ONLY))) {
4324 chan_list[num_chan_new] = chan_list[i];
4325 num_chan_new++;
4326 }
4327 }
4328 }
4329 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304330
Agrawal Ashish16abf782016-08-18 22:42:59 +05304331 hddLog(LOG1, FL("Number of channels: %d"), num_chan_new);
4332 for (i = 0; i < num_chan_new; i++)
4333 len += scnprintf(buf + len, sizeof(buf) - len, "%u ", chan_list[i]);
4334 hddLog(LOG1, "Channels: %s", buf);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304335
4336 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
Agrawal Ashish16abf782016-08-18 22:42:59 +05304337 sizeof(u32) * num_chan_new +
Dino Mycle6fb96c12014-06-10 11:52:40 +05304338 NLMSG_HDRLEN);
4339
4340 if (!replySkb) {
4341 hddLog(VOS_TRACE_LEVEL_ERROR,
4342 FL("valid channels: buffer alloc fail"));
4343 return -EINVAL;
4344 }
4345 if (nla_put_u32(replySkb,
4346 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304347 num_chan_new) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05304348 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304349 sizeof(u32) * num_chan_new, chan_list)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304350
4351 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4352 kfree_skb(replySkb);
4353 return -EINVAL;
4354 }
4355
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304356 ret = cfg80211_vendor_cmd_reply(replySkb);
4357
4358 EXIT();
4359 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304360}
4361
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304362static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
4363 struct wireless_dev *wdev,
4364 const void *data, int dataLen)
4365{
4366 int ret = 0;
4367
4368 vos_ssr_protect(__func__);
4369 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
4370 dataLen);
4371 vos_ssr_unprotect(__func__);
4372
4373 return ret;
4374}
4375
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304376static int hdd_extscan_start_fill_bucket_channel_spec(
4377 hdd_context_t *pHddCtx,
4378 tpSirEXTScanStartReqParams pReqMsg,
4379 struct nlattr **tb)
4380{
4381 struct nlattr *bucket[
4382 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4383 struct nlattr *channel[
4384 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4385 struct nlattr *buckets;
4386 struct nlattr *channels;
4387 int rem1, rem2;
4388 eHalStatus status;
4389 tANI_U8 bktIndex, j, numChannels;
4390 tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4391 tANI_U32 passive_max_chn_time, active_max_chn_time;
4392
4393 bktIndex = 0;
4394
4395 nla_for_each_nested(buckets,
4396 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
4397 if (nla_parse(bucket,
4398 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4399 nla_data(buckets), nla_len(buckets), NULL)) {
4400 hddLog(LOGE, FL("nla_parse failed"));
4401 return -EINVAL;
4402 }
4403
4404 /* Parse and fetch bucket spec */
4405 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4406 hddLog(LOGE, FL("attr bucket index failed"));
4407 return -EINVAL;
4408 }
4409 pReqMsg->buckets[bktIndex].bucket = nla_get_u8(
4410 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4411 hddLog(LOG1, FL("Bucket spec Index %d"),
4412 pReqMsg->buckets[bktIndex].bucket);
4413
4414 /* Parse and fetch wifi band */
4415 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4416 hddLog(LOGE, FL("attr wifi band failed"));
4417 return -EINVAL;
4418 }
4419 pReqMsg->buckets[bktIndex].band = nla_get_u8(
4420 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4421 hddLog(LOG1, FL("Wifi band %d"),
4422 pReqMsg->buckets[bktIndex].band);
4423
4424 /* Parse and fetch period */
4425 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4426 hddLog(LOGE, FL("attr period failed"));
4427 return -EINVAL;
4428 }
4429 pReqMsg->buckets[bktIndex].period = nla_get_u32(
4430 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4431 hddLog(LOG1, FL("period %d"),
4432 pReqMsg->buckets[bktIndex].period);
4433
4434 /* Parse and fetch report events */
4435 if (!bucket[
4436 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4437 hddLog(LOGE, FL("attr report events failed"));
4438 return -EINVAL;
4439 }
4440 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
4441 bucket[
4442 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4443 hddLog(LOG1, FL("report events %d"),
4444 pReqMsg->buckets[bktIndex].reportEvents);
4445
4446 /* Parse and fetch max period */
4447 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
4448 hddLog(LOGE, FL("attr max period failed"));
4449 return -EINVAL;
4450 }
4451 pReqMsg->buckets[bktIndex].max_period = nla_get_u32(
4452 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);
4453 hddLog(LOG1, FL("max period %u"),
4454 pReqMsg->buckets[bktIndex].max_period);
4455
4456 /* Parse and fetch exponent */
4457 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
4458 hddLog(LOGE, FL("attr exponent failed"));
4459 return -EINVAL;
4460 }
4461 pReqMsg->buckets[bktIndex].exponent = nla_get_u32(
4462 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
4463 hddLog(LOG1, FL("exponent %u"),
4464 pReqMsg->buckets[bktIndex].exponent);
4465
4466 /* Parse and fetch step count */
4467 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
4468 hddLog(LOGE, FL("attr step count failed"));
4469 return -EINVAL;
4470 }
4471 pReqMsg->buckets[bktIndex].step_count = nla_get_u32(
4472 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
4473 hddLog(LOG1, FL("Step count %u"),
4474 pReqMsg->buckets[bktIndex].step_count);
4475
4476 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time);
4477 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time);
4478
4479 /* Framework shall pass the channel list if the input WiFi band is
4480 * WIFI_BAND_UNSPECIFIED.
4481 * If the input WiFi band is specified (any value other than
4482 * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
4483 */
4484 if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) {
4485 numChannels = 0;
4486 hddLog(LOG1, "WiFi band is specified, driver to fill channel list");
4487 status = sme_GetValidChannelsByBand(pHddCtx->hHal,
4488 pReqMsg->buckets[bktIndex].band,
4489 chanList, &numChannels);
4490 if (!HAL_STATUS_SUCCESS(status)) {
4491 hddLog(LOGE,
4492 FL("sme_GetValidChannelsByBand failed (err=%d)"),
4493 status);
4494 return -EINVAL;
4495 }
4496
4497 pReqMsg->buckets[bktIndex].numChannels =
4498 VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS);
4499 hddLog(LOG1, FL("Num channels %d"),
4500 pReqMsg->buckets[bktIndex].numChannels);
4501
4502 for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels;
4503 j++) {
4504 pReqMsg->buckets[bktIndex].channels[j].channel =
4505 chanList[j];
4506 pReqMsg->buckets[bktIndex].channels[j].
4507 chnlClass = 0;
4508 if (CSR_IS_CHANNEL_DFS(
4509 vos_freq_to_chan(chanList[j]))) {
4510 pReqMsg->buckets[bktIndex].channels[j].
4511 passive = 1;
4512 pReqMsg->buckets[bktIndex].channels[j].
4513 dwellTimeMs = passive_max_chn_time;
4514 } else {
4515 pReqMsg->buckets[bktIndex].channels[j].
4516 passive = 0;
4517 pReqMsg->buckets[bktIndex].channels[j].
4518 dwellTimeMs = active_max_chn_time;
4519 }
4520
4521 hddLog(LOG1,
4522 "Channel %u Passive %u Dwell time %u ms",
4523 pReqMsg->buckets[bktIndex].channels[j].channel,
4524 pReqMsg->buckets[bktIndex].channels[j].passive,
4525 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4526 }
4527
4528 bktIndex++;
4529 continue;
4530 }
4531
4532 /* Parse and fetch number of channels */
4533 if (!bucket[
4534 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
4535 hddLog(LOGE, FL("attr num channels failed"));
4536 return -EINVAL;
4537 }
4538
4539 pReqMsg->buckets[bktIndex].numChannels =
4540 nla_get_u32(bucket[
4541 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
4542 hddLog(LOG1, FL("num channels %d"),
4543 pReqMsg->buckets[bktIndex].numChannels);
4544
4545 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
4546 hddLog(LOGE, FL("attr channel spec failed"));
4547 return -EINVAL;
4548 }
4549
4550 j = 0;
4551 nla_for_each_nested(channels,
4552 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
4553 if (nla_parse(channel,
4554 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4555 nla_data(channels), nla_len(channels),
4556 wlan_hdd_extscan_config_policy)) {
4557 hddLog(LOGE, FL("nla_parse failed"));
4558 return -EINVAL;
4559 }
4560
4561 /* Parse and fetch channel */
4562 if (!channel[
4563 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
4564 hddLog(LOGE, FL("attr channel failed"));
4565 return -EINVAL;
4566 }
4567 pReqMsg->buckets[bktIndex].channels[j].channel =
4568 nla_get_u32(channel[
4569 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
4570 hddLog(LOG1, FL("channel %u"),
4571 pReqMsg->buckets[bktIndex].channels[j].channel);
4572
4573 /* Parse and fetch dwell time */
4574 if (!channel[
4575 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
4576 hddLog(LOGE, FL("attr dwelltime failed"));
4577 return -EINVAL;
4578 }
4579 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
4580 nla_get_u32(channel[
4581 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
4582
4583 hddLog(LOG1, FL("Dwell time (%u ms)"),
4584 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4585
4586
4587 /* Parse and fetch channel spec passive */
4588 if (!channel[
4589 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
4590 hddLog(LOGE,
4591 FL("attr channel spec passive failed"));
4592 return -EINVAL;
4593 }
4594 pReqMsg->buckets[bktIndex].channels[j].passive =
4595 nla_get_u8(channel[
4596 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
4597 hddLog(LOG1, FL("Chnl spec passive %u"),
4598 pReqMsg->buckets[bktIndex].channels[j].passive);
4599
4600 j++;
4601 }
4602
4603 bktIndex++;
4604 }
4605
4606 return 0;
4607}
4608
4609
4610/*
4611 * define short names for the global vendor params
4612 * used by wlan_hdd_cfg80211_extscan_start()
4613 */
4614#define PARAM_MAX \
4615QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
4616#define PARAM_REQUEST_ID \
4617QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
4618#define PARAM_BASE_PERIOD \
4619QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
4620#define PARAM_MAX_AP_PER_SCAN \
4621QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
4622#define PARAM_RPT_THRHLD_PERCENT \
4623QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
4624#define PARAM_RPT_THRHLD_NUM_SCANS \
4625QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
4626#define PARAM_NUM_BUCKETS \
4627QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
4628
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304629static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304630 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304631 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304632{
Dino Myclee8843b32014-07-04 14:21:45 +05304633 tpSirEXTScanStartReqParams pReqMsg = NULL;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304634 struct net_device *dev = wdev->netdev;
4635 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4636 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4637 struct nlattr *tb[PARAM_MAX + 1];
4638 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304639 eHalStatus status;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304640 tANI_U32 request_id;
4641 struct hdd_ext_scan_context *context;
4642 unsigned long rc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304643
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304644 ENTER();
4645
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304646 if (VOS_FTM_MODE == hdd_get_conparam()) {
4647 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4648 return -EINVAL;
4649 }
4650
Dino Mycle6fb96c12014-06-10 11:52:40 +05304651 status = wlan_hdd_validate_context(pHddCtx);
4652 if (0 != status)
4653 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304654 return -EINVAL;
4655 }
Dino Myclee8843b32014-07-04 14:21:45 +05304656 /* check the EXTScan Capability */
4657 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304658 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4659 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304660 {
4661 hddLog(VOS_TRACE_LEVEL_ERROR,
4662 FL("EXTScan not enabled/supported by Firmware"));
4663 return -EINVAL;
4664 }
4665
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304666 if (nla_parse(tb, PARAM_MAX,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304667 data, dataLen,
4668 wlan_hdd_extscan_config_policy)) {
4669 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4670 return -EINVAL;
4671 }
4672
4673 /* Parse and fetch request Id */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304674 if (!tb[PARAM_REQUEST_ID]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304675 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4676 return -EINVAL;
4677 }
4678
Dino Myclee8843b32014-07-04 14:21:45 +05304679 pReqMsg = (tpSirEXTScanStartReqParams)
4680 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304681 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05304682 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4683 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304684 }
4685
4686 pReqMsg->requestId = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304687 tb[PARAM_REQUEST_ID]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304688 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4689
4690 pReqMsg->sessionId = pAdapter->sessionId;
4691 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4692
4693 /* Parse and fetch base period */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304694 if (!tb[PARAM_BASE_PERIOD]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304695 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
4696 goto fail;
4697 }
4698 pReqMsg->basePeriod = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304699 tb[PARAM_BASE_PERIOD]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304700 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
4701 pReqMsg->basePeriod);
4702
4703 /* Parse and fetch max AP per scan */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304704 if (!tb[PARAM_MAX_AP_PER_SCAN]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304705 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
4706 goto fail;
4707 }
4708 pReqMsg->maxAPperScan = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304709 tb[PARAM_MAX_AP_PER_SCAN]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304710 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
4711 pReqMsg->maxAPperScan);
4712
4713 /* Parse and fetch report threshold */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304714 if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304715 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
4716 goto fail;
4717 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304718 pReqMsg->reportThresholdPercent = nla_get_u8(
4719 tb[PARAM_RPT_THRHLD_PERCENT]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304720 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304721 pReqMsg->reportThresholdPercent);
4722
4723 /* Parse and fetch report threshold num scans */
4724 if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
4725 hddLog(LOGE, FL("attr report_threshold num scans failed"));
4726 goto fail;
4727 }
4728 pReqMsg->reportThresholdNumScans = nla_get_u8(
4729 tb[PARAM_RPT_THRHLD_NUM_SCANS]);
4730 hddLog(LOG1, FL("Report Threshold num scans %d"),
4731 pReqMsg->reportThresholdNumScans);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304732
4733 /* Parse and fetch number of buckets */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304734 if (!tb[PARAM_NUM_BUCKETS]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304735 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
4736 goto fail;
4737 }
4738 pReqMsg->numBuckets = nla_get_u8(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304739 tb[PARAM_NUM_BUCKETS]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304740 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
4741 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
4742 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
4743 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
4744 }
4745 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
4746 pReqMsg->numBuckets);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304747
Dino Mycle6fb96c12014-06-10 11:52:40 +05304748 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
4749 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
4750 goto fail;
4751 }
4752
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304753 pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304754
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304755 if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
4756 goto fail;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304757
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304758 context = &pHddCtx->ext_scan_context;
4759 spin_lock(&hdd_context_lock);
4760 INIT_COMPLETION(context->response_event);
4761 context->request_id = request_id = pReqMsg->requestId;
4762 spin_unlock(&hdd_context_lock);
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304763
Dino Mycle6fb96c12014-06-10 11:52:40 +05304764 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
4765 if (!HAL_STATUS_SUCCESS(status)) {
4766 hddLog(VOS_TRACE_LEVEL_ERROR,
4767 FL("sme_EXTScanStart failed(err=%d)"), status);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304768 goto fail;
4769 }
4770
Srinivas Dasari91727c12016-03-23 17:59:06 +05304771 pHddCtx->extscan_start_time_since_boot = vos_get_monotonic_boottime();
4772
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304773 /* request was sent -- wait for the response */
4774 rc = wait_for_completion_timeout(&context->response_event,
4775 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4776
4777 if (!rc) {
4778 hddLog(LOGE, FL("sme_ExtScanStart timed out"));
4779 retval = -ETIMEDOUT;
4780 } else {
4781 spin_lock(&hdd_context_lock);
4782 if (context->request_id == request_id)
4783 retval = context->response_status;
4784 else
4785 retval = -EINVAL;
4786 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304787 }
4788
Dino Myclee8843b32014-07-04 14:21:45 +05304789 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304790 EXIT();
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304791 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304792
4793fail:
4794 vos_mem_free(pReqMsg);
4795 return -EINVAL;
4796}
4797
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304798/*
4799 * done with short names for the global vendor params
4800 * used by wlan_hdd_cfg80211_extscan_start()
4801 */
4802#undef PARAM_MAX
4803#undef PARAM_REQUEST_ID
4804#undef PARAM_BASE_PERIOD
4805#undef PARAMS_MAX_AP_PER_SCAN
4806#undef PARAMS_RPT_THRHLD_PERCENT
4807#undef PARAMS_RPT_THRHLD_NUM_SCANS
4808#undef PARAMS_NUM_BUCKETS
4809
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304810static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
4811 struct wireless_dev *wdev,
4812 const void *data, int dataLen)
4813{
4814 int ret = 0;
4815
4816 vos_ssr_protect(__func__);
4817 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
4818 vos_ssr_unprotect(__func__);
4819
4820 return ret;
4821}
4822
4823static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304824 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304825 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304826{
Dino Myclee8843b32014-07-04 14:21:45 +05304827 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304828 struct net_device *dev = wdev->netdev;
4829 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4830 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4831 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4832 eHalStatus status;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304833 int retval;
4834 unsigned long rc;
4835 struct hdd_ext_scan_context *context;
4836 tANI_U32 request_id;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304837
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304838 ENTER();
4839
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304840 if (VOS_FTM_MODE == hdd_get_conparam()) {
4841 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4842 return -EINVAL;
4843 }
4844
Dino Mycle6fb96c12014-06-10 11:52:40 +05304845 status = wlan_hdd_validate_context(pHddCtx);
4846 if (0 != status)
4847 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304848 return -EINVAL;
4849 }
Dino Myclee8843b32014-07-04 14:21:45 +05304850 /* check the EXTScan Capability */
4851 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304852 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4853 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304854 {
4855 hddLog(VOS_TRACE_LEVEL_ERROR,
4856 FL("EXTScan not enabled/supported by Firmware"));
4857 return -EINVAL;
4858 }
4859
Dino Mycle6fb96c12014-06-10 11:52:40 +05304860 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4861 data, dataLen,
4862 wlan_hdd_extscan_config_policy)) {
4863 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4864 return -EINVAL;
4865 }
4866
4867 /* Parse and fetch request Id */
4868 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4869 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4870 return -EINVAL;
4871 }
4872
Dino Myclee8843b32014-07-04 14:21:45 +05304873 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304874 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304875 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304876
Dino Myclee8843b32014-07-04 14:21:45 +05304877 reqMsg.sessionId = pAdapter->sessionId;
4878 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304879
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304880 context = &pHddCtx->ext_scan_context;
4881 spin_lock(&hdd_context_lock);
4882 INIT_COMPLETION(context->response_event);
Sravanti Palakonda7539fb92016-02-26 17:49:21 +05304883 context->request_id = request_id = reqMsg.requestId;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304884 spin_unlock(&hdd_context_lock);
4885
Dino Myclee8843b32014-07-04 14:21:45 +05304886 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304887 if (!HAL_STATUS_SUCCESS(status)) {
4888 hddLog(VOS_TRACE_LEVEL_ERROR,
4889 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304890 return -EINVAL;
4891 }
4892
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304893 /* request was sent -- wait for the response */
4894 rc = wait_for_completion_timeout(&context->response_event,
4895 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4896
4897 if (!rc) {
4898 hddLog(LOGE, FL("sme_ExtScanStop timed out"));
4899 retval = -ETIMEDOUT;
4900 } else {
4901 spin_lock(&hdd_context_lock);
4902 if (context->request_id == request_id)
4903 retval = context->response_status;
4904 else
4905 retval = -EINVAL;
4906 spin_unlock(&hdd_context_lock);
4907 }
4908
4909 return retval;
4910
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304911 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304912 return 0;
4913}
4914
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304915static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
4916 struct wireless_dev *wdev,
4917 const void *data, int dataLen)
4918{
4919 int ret = 0;
4920
4921 vos_ssr_protect(__func__);
4922 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
4923 vos_ssr_unprotect(__func__);
4924
4925 return ret;
4926}
4927
4928static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304929 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304930 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304931{
Dino Myclee8843b32014-07-04 14:21:45 +05304932 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304933 struct net_device *dev = wdev->netdev;
4934 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4935 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4936 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4937 eHalStatus status;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304938 struct hdd_ext_scan_context *context;
4939 tANI_U32 request_id;
4940 unsigned long rc;
4941 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304942
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304943 ENTER();
4944
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304945 if (VOS_FTM_MODE == hdd_get_conparam()) {
4946 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4947 return -EINVAL;
4948 }
4949
Dino Mycle6fb96c12014-06-10 11:52:40 +05304950 status = wlan_hdd_validate_context(pHddCtx);
4951 if (0 != status)
4952 {
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304953 hddLog(LOGE, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304954 return -EINVAL;
4955 }
Dino Myclee8843b32014-07-04 14:21:45 +05304956 /* check the EXTScan Capability */
4957 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304958 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4959 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304960 {
4961 hddLog(VOS_TRACE_LEVEL_ERROR,
4962 FL("EXTScan not enabled/supported by Firmware"));
4963 return -EINVAL;
4964 }
4965
Dino Mycle6fb96c12014-06-10 11:52:40 +05304966 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4967 data, dataLen,
4968 wlan_hdd_extscan_config_policy)) {
4969 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4970 return -EINVAL;
4971 }
4972
4973 /* Parse and fetch request Id */
4974 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4975 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4976 return -EINVAL;
4977 }
4978
Dino Myclee8843b32014-07-04 14:21:45 +05304979 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304980 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304981 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304982
Dino Myclee8843b32014-07-04 14:21:45 +05304983 reqMsg.sessionId = pAdapter->sessionId;
4984 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304985
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304986 context = &pHddCtx->ext_scan_context;
4987 spin_lock(&hdd_context_lock);
4988 INIT_COMPLETION(context->response_event);
4989 context->request_id = request_id = reqMsg.requestId;
4990 spin_unlock(&hdd_context_lock);
4991
Dino Myclee8843b32014-07-04 14:21:45 +05304992 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304993 if (!HAL_STATUS_SUCCESS(status)) {
4994 hddLog(VOS_TRACE_LEVEL_ERROR,
4995 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304996 return -EINVAL;
4997 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304998
4999 /* request was sent -- wait for the response */
5000 rc = wait_for_completion_timeout(&context->response_event,
5001 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5002 if (!rc) {
5003 hddLog(LOGE, FL("sme_ResetBssHotlist timed out"));
5004 retval = -ETIMEDOUT;
5005 } else {
5006 spin_lock(&hdd_context_lock);
5007 if (context->request_id == request_id)
5008 retval = context->response_status;
5009 else
5010 retval = -EINVAL;
5011 spin_unlock(&hdd_context_lock);
5012 }
5013
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305014 EXIT();
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305015 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305016}
5017
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305018static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
5019 struct wireless_dev *wdev,
5020 const void *data, int dataLen)
5021{
5022 int ret = 0;
5023
5024 vos_ssr_protect(__func__);
5025 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
5026 vos_ssr_unprotect(__func__);
5027
5028 return ret;
5029}
Dino Mycle6fb96c12014-06-10 11:52:40 +05305030#endif /* WLAN_FEATURE_EXTSCAN */
5031
Atul Mittal115287b2014-07-08 13:26:33 +05305032/*EXT TDLS*/
5033static const struct nla_policy
5034wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
5035{
5036 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
5037 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
5038 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
5039 {.type = NLA_S32 },
5040 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
5041 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
5042
5043};
5044
5045static const struct nla_policy
5046wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
5047{
5048 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
5049
5050};
5051
5052static const struct nla_policy
5053wlan_hdd_tdls_config_state_change_policy[
5054 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
5055{
5056 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {.type = NLA_UNSPEC },
5057 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
5058 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305059 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
5060 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
5061 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305062
5063};
5064
5065static const struct nla_policy
5066wlan_hdd_tdls_config_get_status_policy[
5067 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
5068{
5069 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {.type = NLA_UNSPEC },
5070 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
5071 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305072 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
5073 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
5074 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305075
5076};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305077
5078static const struct nla_policy
5079wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
5080{
5081 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {.type = NLA_UNSPEC },
5082};
5083
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305084static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305085 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305086 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305087 int data_len)
5088{
5089
5090 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5091 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
5092
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305093 ENTER();
5094
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305095 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305096 return -EINVAL;
5097 }
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +05305098 if (0 == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05305099 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305100 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05305101 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305102 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05305103 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305104 return -ENOTSUPP;
5105 }
5106
5107 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
5108 data, data_len, wlan_hdd_mac_config)) {
5109 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5110 return -EINVAL;
5111 }
5112
5113 /* Parse and fetch mac address */
5114 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
5115 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5116 return -EINVAL;
5117 }
5118
5119 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
5120 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5121 VOS_MAC_ADDR_LAST_3_BYTES);
5122
Siddharth Bhal76972212014-10-15 16:22:51 +05305123 pHddCtx->spoofMacAddr.isEnabled = TRUE;
5124
5125 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305126 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5127 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05305128 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
5129 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
5130 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
5131 {
5132 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
5133 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
5134 VOS_MAC_ADDRESS_LEN);
5135 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305136 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305137
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +05305138 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
5139 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305140
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305141 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305142 return 0;
5143}
5144
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305145static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
5146 struct wireless_dev *wdev,
5147 const void *data,
5148 int data_len)
5149{
5150 int ret = 0;
5151
5152 vos_ssr_protect(__func__);
5153 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
5154 vos_ssr_unprotect(__func__);
5155
5156 return ret;
5157}
5158
5159static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305160 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305161 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305162 int data_len)
5163{
5164 u8 peer[6] = {0};
5165 struct net_device *dev = wdev->netdev;
5166 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5167 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5168 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
5169 eHalStatus ret;
5170 tANI_S32 state;
5171 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305172 tANI_S32 global_operating_class = 0;
5173 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05305174 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305175 int retVal;
5176
5177 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305178
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305179 if (!pAdapter) {
5180 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5181 return -EINVAL;
5182 }
5183
Atul Mittal115287b2014-07-08 13:26:33 +05305184 ret = wlan_hdd_validate_context(pHddCtx);
5185 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305186 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305187 return -EINVAL;
5188 }
5189 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305190 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305191 return -ENOTSUPP;
5192 }
5193 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
5194 data, data_len,
5195 wlan_hdd_tdls_config_get_status_policy)) {
5196 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5197 return -EINVAL;
5198 }
5199
5200 /* Parse and fetch mac address */
5201 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
5202 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5203 return -EINVAL;
5204 }
5205
5206 memcpy(peer, nla_data(
5207 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
5208 sizeof(peer));
5209 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5210
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05305211 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05305212
Atul Mittal115287b2014-07-08 13:26:33 +05305213 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305214 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05305215 NLMSG_HDRLEN);
5216
5217 if (!skb) {
5218 hddLog(VOS_TRACE_LEVEL_ERROR,
5219 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5220 return -EINVAL;
5221 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305222 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 +05305223 reason,
5224 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305225 global_operating_class,
5226 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05305227 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305228 if (nla_put_s32(skb,
5229 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
5230 state) ||
5231 nla_put_s32(skb,
5232 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
5233 reason) ||
5234 nla_put_s32(skb,
5235 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
5236 global_operating_class) ||
5237 nla_put_s32(skb,
5238 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
5239 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05305240
5241 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5242 goto nla_put_failure;
5243 }
5244
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305245 retVal = cfg80211_vendor_cmd_reply(skb);
5246 EXIT();
5247 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05305248
5249nla_put_failure:
5250 kfree_skb(skb);
5251 return -EINVAL;
5252}
5253
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305254static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
5255 struct wireless_dev *wdev,
5256 const void *data,
5257 int data_len)
5258{
5259 int ret = 0;
5260
5261 vos_ssr_protect(__func__);
5262 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
5263 vos_ssr_unprotect(__func__);
5264
5265 return ret;
5266}
5267
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05305268static int wlan_hdd_cfg80211_exttdls_callback(
5269#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
5270 const tANI_U8* mac,
5271#else
5272 tANI_U8* mac,
5273#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305274 tANI_S32 state,
5275 tANI_S32 reason,
5276 void *ctx)
5277{
5278 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05305279 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305280 tANI_S32 global_operating_class = 0;
5281 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305282 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05305283
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305284 ENTER();
5285
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305286 if (!pAdapter) {
5287 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5288 return -EINVAL;
5289 }
5290
5291 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05305292 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305293 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305294 return -EINVAL;
5295 }
5296
5297 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305298 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305299 return -ENOTSUPP;
5300 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05305301 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
5302#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
5303 NULL,
5304#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305305 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
5306 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
5307 GFP_KERNEL);
5308
5309 if (!skb) {
5310 hddLog(VOS_TRACE_LEVEL_ERROR,
5311 FL("cfg80211_vendor_event_alloc failed"));
5312 return -EINVAL;
5313 }
5314 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305315 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
5316 reason,
5317 state,
5318 global_operating_class,
5319 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05305320 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
5321 MAC_ADDR_ARRAY(mac));
5322
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305323 if (nla_put(skb,
5324 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
5325 VOS_MAC_ADDR_SIZE, mac) ||
5326 nla_put_s32(skb,
5327 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
5328 state) ||
5329 nla_put_s32(skb,
5330 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
5331 reason) ||
5332 nla_put_s32(skb,
5333 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
5334 channel) ||
5335 nla_put_s32(skb,
5336 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
5337 global_operating_class)
5338 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05305339 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5340 goto nla_put_failure;
5341 }
5342
5343 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305344 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05305345 return (0);
5346
5347nla_put_failure:
5348 kfree_skb(skb);
5349 return -EINVAL;
5350}
5351
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305352static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305353 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305354 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305355 int data_len)
5356{
5357 u8 peer[6] = {0};
5358 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305359 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5360 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
5361 eHalStatus status;
5362 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305363 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305364 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305365
5366 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305367
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305368 if (!dev) {
5369 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5370 return -EINVAL;
5371 }
5372
5373 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5374 if (!pAdapter) {
5375 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5376 return -EINVAL;
5377 }
5378
Atul Mittal115287b2014-07-08 13:26:33 +05305379 status = wlan_hdd_validate_context(pHddCtx);
5380 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305381 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305382 return -EINVAL;
5383 }
5384 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305385 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305386 return -ENOTSUPP;
5387 }
5388 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
5389 data, data_len,
5390 wlan_hdd_tdls_config_enable_policy)) {
5391 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5392 return -EINVAL;
5393 }
5394
5395 /* Parse and fetch mac address */
5396 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
5397 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5398 return -EINVAL;
5399 }
5400
5401 memcpy(peer, nla_data(
5402 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
5403 sizeof(peer));
5404 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5405
5406 /* Parse and fetch channel */
5407 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
5408 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
5409 return -EINVAL;
5410 }
5411 pReqMsg.channel = nla_get_s32(
5412 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
5413 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
5414
5415 /* Parse and fetch global operating class */
5416 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
5417 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
5418 return -EINVAL;
5419 }
5420 pReqMsg.global_operating_class = nla_get_s32(
5421 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
5422 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
5423 pReqMsg.global_operating_class);
5424
5425 /* Parse and fetch latency ms */
5426 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
5427 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
5428 return -EINVAL;
5429 }
5430 pReqMsg.max_latency_ms = nla_get_s32(
5431 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
5432 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
5433 pReqMsg.max_latency_ms);
5434
5435 /* Parse and fetch required bandwidth kbps */
5436 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
5437 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
5438 return -EINVAL;
5439 }
5440
5441 pReqMsg.min_bandwidth_kbps = nla_get_s32(
5442 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
5443 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
5444 pReqMsg.min_bandwidth_kbps);
5445
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305446 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05305447 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05305448 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305449 wlan_hdd_cfg80211_exttdls_callback);
5450
5451 EXIT();
5452 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305453}
5454
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305455static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
5456 struct wireless_dev *wdev,
5457 const void *data,
5458 int data_len)
5459{
5460 int ret = 0;
5461
5462 vos_ssr_protect(__func__);
5463 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
5464 vos_ssr_unprotect(__func__);
5465
5466 return ret;
5467}
5468
5469static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305470 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305471 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305472 int data_len)
5473{
5474 u8 peer[6] = {0};
5475 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305476 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5477 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
5478 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305479 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305480 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305481
5482 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305483
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305484 if (!dev) {
5485 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5486 return -EINVAL;
5487 }
5488
5489 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5490 if (!pAdapter) {
5491 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
5492 return -EINVAL;
5493 }
5494
Atul Mittal115287b2014-07-08 13:26:33 +05305495 status = wlan_hdd_validate_context(pHddCtx);
5496 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305497 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305498 return -EINVAL;
5499 }
5500 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305501 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305502 return -ENOTSUPP;
5503 }
5504 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
5505 data, data_len,
5506 wlan_hdd_tdls_config_disable_policy)) {
5507 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5508 return -EINVAL;
5509 }
5510 /* Parse and fetch mac address */
5511 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
5512 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5513 return -EINVAL;
5514 }
5515
5516 memcpy(peer, nla_data(
5517 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
5518 sizeof(peer));
5519 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5520
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305521 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
5522
5523 EXIT();
5524 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305525}
5526
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305527static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
5528 struct wireless_dev *wdev,
5529 const void *data,
5530 int data_len)
5531{
5532 int ret = 0;
5533
5534 vos_ssr_protect(__func__);
5535 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
5536 vos_ssr_unprotect(__func__);
5537
5538 return ret;
5539}
5540
Dasari Srinivas7875a302014-09-26 17:50:57 +05305541static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305542__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05305543 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305544 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05305545{
5546 struct net_device *dev = wdev->netdev;
5547 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5548 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5549 struct sk_buff *skb = NULL;
5550 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305551 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305552
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305553 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305554
5555 ret = wlan_hdd_validate_context(pHddCtx);
5556 if (0 != ret)
5557 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305558 return ret;
5559 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305560 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
5561 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
5562 fset |= WIFI_FEATURE_INFRA;
5563 }
5564
5565 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
5566 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
5567 fset |= WIFI_FEATURE_INFRA_5G;
5568 }
5569
5570#ifdef WLAN_FEATURE_P2P
5571 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
5572 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
5573 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
5574 fset |= WIFI_FEATURE_P2P;
5575 }
5576#endif
5577
5578 /* Soft-AP is supported currently by default */
5579 fset |= WIFI_FEATURE_SOFT_AP;
5580
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05305581 /* HOTSPOT is a supplicant feature, enable it by default */
5582 fset |= WIFI_FEATURE_HOTSPOT;
5583
Dasari Srinivas7875a302014-09-26 17:50:57 +05305584#ifdef WLAN_FEATURE_EXTSCAN
5585 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305586 sme_IsFeatureSupportedByFW(EXTENDED_SCAN) &&
5587 sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)) {
5588 hddLog(LOG1, FL("Enhanced EXTScan is supported by firmware"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05305589 fset |= WIFI_FEATURE_EXTSCAN;
5590 }
5591#endif
5592
Dasari Srinivas7875a302014-09-26 17:50:57 +05305593 if (sme_IsFeatureSupportedByFW(NAN)) {
5594 hddLog(LOG1, FL("NAN is supported by firmware"));
5595 fset |= WIFI_FEATURE_NAN;
5596 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305597
5598 /* D2D RTT is not supported currently by default */
5599 if (sme_IsFeatureSupportedByFW(RTT)) {
5600 hddLog(LOG1, FL("RTT is supported by firmware"));
5601 fset |= WIFI_FEATURE_D2AP_RTT;
5602 }
5603
Padma, Santhosh Kumaraac4c4d2015-12-08 16:07:47 +05305604 if (sme_IsFeatureSupportedByFW(RTT3)) {
5605 hddLog(LOG1, FL("RTT3 is supported by firmware"));
5606 fset |= WIFI_FEATURE_RTT3;
5607 }
5608
Dasari Srinivas7875a302014-09-26 17:50:57 +05305609#ifdef FEATURE_WLAN_BATCH_SCAN
5610 if (fset & WIFI_FEATURE_EXTSCAN) {
5611 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
5612 fset &= ~WIFI_FEATURE_BATCH_SCAN;
5613 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
5614 hddLog(LOG1, FL("Batch scan is supported by firmware"));
5615 fset |= WIFI_FEATURE_BATCH_SCAN;
5616 }
5617#endif
5618
5619#ifdef FEATURE_WLAN_SCAN_PNO
5620 if (pHddCtx->cfg_ini->configPNOScanSupport &&
5621 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
5622 hddLog(LOG1, FL("PNO is supported by firmware"));
5623 fset |= WIFI_FEATURE_PNO;
5624 }
5625#endif
5626
5627 /* STA+STA is supported currently by default */
5628 fset |= WIFI_FEATURE_ADDITIONAL_STA;
5629
5630#ifdef FEATURE_WLAN_TDLS
5631 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
5632 sme_IsFeatureSupportedByFW(TDLS)) {
5633 hddLog(LOG1, FL("TDLS is supported by firmware"));
5634 fset |= WIFI_FEATURE_TDLS;
5635 }
5636
5637 /* TDLS_OFFCHANNEL is not supported currently by default */
5638#endif
5639
5640#ifdef WLAN_AP_STA_CONCURRENCY
5641 /* AP+STA concurrency is supported currently by default */
5642 fset |= WIFI_FEATURE_AP_STA;
5643#endif
5644
Mukul Sharma5add0532015-08-17 15:57:47 +05305645#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5646 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
5647 hddLog(LOG1, FL("Link layer stats is supported by driver"));
5648#endif
5649
Dasari Srinivas7875a302014-09-26 17:50:57 +05305650 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
5651 NLMSG_HDRLEN);
5652
5653 if (!skb) {
5654 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5655 return -EINVAL;
5656 }
5657 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
5658
5659 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
5660 hddLog(LOGE, FL("nla put fail"));
5661 goto nla_put_failure;
5662 }
5663
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305664 ret = cfg80211_vendor_cmd_reply(skb);
5665 EXIT();
5666 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305667
5668nla_put_failure:
5669 kfree_skb(skb);
5670 return -EINVAL;
5671}
5672
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305673static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305674wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
5675 struct wireless_dev *wdev,
5676 const void *data, int data_len)
5677{
5678 int ret = 0;
5679
5680 vos_ssr_protect(__func__);
5681 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
5682 vos_ssr_unprotect(__func__);
5683
5684 return ret;
5685}
5686
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305687
5688static const struct
5689nla_policy
5690qca_wlan_vendor_wifi_logger_get_ring_data_policy
5691[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1] = {
5692 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]
5693 = {.type = NLA_U32 },
5694};
5695
5696static int
5697 __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
5698 struct wireless_dev *wdev,
5699 const void *data,
5700 int data_len)
5701{
5702 int ret;
5703 VOS_STATUS status;
5704 uint32_t ring_id;
5705 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5706 struct nlattr *tb
5707 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1];
5708
5709 ENTER();
5710
5711 ret = wlan_hdd_validate_context(hdd_ctx);
5712 if (0 != ret) {
5713 return ret;
5714 }
5715
5716 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX,
5717 data, data_len,
5718 qca_wlan_vendor_wifi_logger_get_ring_data_policy)) {
5719 hddLog(LOGE, FL("Invalid attribute"));
5720 return -EINVAL;
5721 }
5722
5723 /* Parse and fetch ring id */
5724 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]) {
5725 hddLog(LOGE, FL("attr ATTR failed"));
5726 return -EINVAL;
5727 }
5728
5729 ring_id = nla_get_u32(
5730 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]);
5731
5732 hddLog(LOG1, FL("Bug report triggered by framework"));
5733
5734 status = vos_fatal_event_logs_req(WLAN_LOG_TYPE_NON_FATAL,
5735 WLAN_LOG_INDICATOR_FRAMEWORK,
5736 WLAN_LOG_REASON_CODE_FRAMEWORK,
Abhishek Singh837adf22015-10-01 17:37:37 +05305737 TRUE, TRUE
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305738 );
5739 if (VOS_STATUS_SUCCESS != status) {
5740 hddLog(LOGE, FL("Failed to trigger bug report"));
5741
5742 return -EINVAL;
5743 }
5744
5745 return 0;
5746
5747
5748}
5749
5750
5751static int
5752 wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
5753 struct wireless_dev *wdev,
5754 const void *data,
5755 int data_len)
5756{
5757 int ret = 0;
5758
5759 vos_ssr_protect(__func__);
5760 ret = __wlan_hdd_cfg80211_wifi_logger_get_ring_data(wiphy,
5761 wdev, data, data_len);
5762 vos_ssr_unprotect(__func__);
5763
5764 return ret;
5765
5766}
5767
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05305768#define MAX_CONCURRENT_MATRIX \
5769 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX
5770#define MATRIX_CONFIG_PARAM_SET_SIZE_MAX \
5771 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX
5772static const struct nla_policy
5773wlan_hdd_get_concurrency_matrix_policy[MAX_CONCURRENT_MATRIX + 1] = {
5774 [MATRIX_CONFIG_PARAM_SET_SIZE_MAX] = {.type = NLA_U32},
5775};
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305776
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305777static int
5778__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305779 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305780 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305781{
5782 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
5783 uint8_t i, feature_sets, max_feature_sets;
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05305784 struct nlattr *tb[MAX_CONCURRENT_MATRIX + 1];
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305785 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305786 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5787 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305788
5789 ENTER();
5790
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305791 ret = wlan_hdd_validate_context(pHddCtx);
5792 if (0 != ret)
5793 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305794 return ret;
5795 }
5796
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05305797 if (nla_parse(tb, MAX_CONCURRENT_MATRIX, data, data_len,
5798 wlan_hdd_get_concurrency_matrix_policy)) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305799 hddLog(LOGE, FL("Invalid ATTR"));
5800 return -EINVAL;
5801 }
5802
5803 /* Parse and fetch max feature set */
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05305804 if (!tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305805 hddLog(LOGE, FL("Attr max feature set size failed"));
5806 return -EINVAL;
5807 }
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05305808 max_feature_sets = nla_get_u32(tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305809 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
5810
5811 /* Fill feature combination matrix */
5812 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305813 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5814 WIFI_FEATURE_P2P;
5815
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305816 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5817 WIFI_FEATURE_SOFT_AP;
5818
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305819 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
5820 WIFI_FEATURE_SOFT_AP;
5821
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305822 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5823 WIFI_FEATURE_SOFT_AP |
5824 WIFI_FEATURE_P2P;
5825
5826 /* Add more feature combinations here */
5827
5828 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
5829 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
5830 hddLog(LOG1, "Feature set matrix");
5831 for (i = 0; i < feature_sets; i++)
5832 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
5833
5834 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
5835 sizeof(u32) * feature_sets +
5836 NLMSG_HDRLEN);
5837
5838 if (reply_skb) {
5839 if (nla_put_u32(reply_skb,
5840 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
5841 feature_sets) ||
5842 nla_put(reply_skb,
5843 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
5844 sizeof(u32) * feature_sets, feature_set_matrix)) {
5845 hddLog(LOGE, FL("nla put fail"));
5846 kfree_skb(reply_skb);
5847 return -EINVAL;
5848 }
5849
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305850 ret = cfg80211_vendor_cmd_reply(reply_skb);
5851 EXIT();
5852 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305853 }
5854 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
5855 return -ENOMEM;
5856
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305857}
5858
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05305859#undef MAX_CONCURRENT_MATRIX
5860#undef MATRIX_CONFIG_PARAM_SET_SIZE_MAX
5861
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305862static int
5863wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
5864 struct wireless_dev *wdev,
5865 const void *data, int data_len)
5866{
5867 int ret = 0;
5868
5869 vos_ssr_protect(__func__);
5870 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
5871 data_len);
5872 vos_ssr_unprotect(__func__);
5873
5874 return ret;
5875}
5876
c_manjeecfd1efb2015-09-25 19:32:34 +05305877
5878static int
5879__wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5880 struct wireless_dev *wdev,
5881 const void *data, int data_len)
5882{
5883 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5884 int ret;
5885 ENTER();
5886
5887 ret = wlan_hdd_validate_context(pHddCtx);
5888 if (0 != ret)
5889 {
5890 return ret;
5891 }
5892
5893 if( !pHddCtx->cfg_ini->enableFwrMemDump ||
5894 (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
5895 {
5896 hddLog(VOS_TRACE_LEVEL_INFO, FL("FW dump Logging not supported"));
5897 return -EINVAL;
5898 }
5899 /*call common API for FW mem dump req*/
5900 ret = wlan_hdd_fw_mem_dump_req(pHddCtx);
5901
Abhishek Singhc783fa72015-12-09 18:07:34 +05305902 if (!ret)
c_manjee04b4c5c2015-10-13 18:35:01 +05305903 {
5904 /*indicate to userspace the status of fw mem dump */
5905 wlan_indicate_mem_dump_complete(true);
5906 }
5907 else
5908 {
5909 /*else send failure to userspace */
5910 wlan_indicate_mem_dump_complete(false);
5911 }
c_manjeecfd1efb2015-09-25 19:32:34 +05305912 EXIT();
5913 return ret;
5914}
5915
5916/**
5917 * wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump
5918 * @wiphy: pointer to wireless wiphy structure.
5919 * @wdev: pointer to wireless_dev structure.
5920 * @data: Pointer to the NL data.
5921 * @data_len:Length of @data
5922 *
5923 * This is called when wlan driver needs to get the firmware memory dump
5924 * via vendor specific command.
5925 *
5926 * Return: 0 on success, error number otherwise.
5927 */
5928
5929static int
5930wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5931 struct wireless_dev *wdev,
5932 const void *data, int data_len)
Sushant Kaushik8e644982015-09-23 12:18:54 +05305933{
5934 int ret = 0;
5935 vos_ssr_protect(__func__);
5936 ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data,
5937 data_len);
5938 vos_ssr_unprotect(__func__);
5939 return ret;
5940}
c_manjeecfd1efb2015-09-25 19:32:34 +05305941
Sushant Kaushik8e644982015-09-23 12:18:54 +05305942static const struct
5943nla_policy
5944qca_wlan_vendor_wifi_logger_start_policy
5945[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
5946 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
5947 = {.type = NLA_U32 },
5948 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
5949 = {.type = NLA_U32 },
5950 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
5951 = {.type = NLA_U32 },
5952};
5953
5954/**
5955 * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
5956 * or disable the collection of packet statistics from the firmware
5957 * @wiphy: WIPHY structure pointer
5958 * @wdev: Wireless device structure pointer
5959 * @data: Pointer to the data received
5960 * @data_len: Length of the data received
5961 *
5962 * This function is used to enable or disable the collection of packet
5963 * statistics from the firmware
5964 *
5965 * Return: 0 on success and errno on failure
5966 */
5967static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
5968 struct wireless_dev *wdev,
5969 const void *data,
5970 int data_len)
5971{
5972 eHalStatus status;
5973 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5974 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
5975 tAniWifiStartLog start_log;
5976
5977 status = wlan_hdd_validate_context(hdd_ctx);
5978 if (0 != status) {
5979 return -EINVAL;
5980 }
5981
5982 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
5983 data, data_len,
5984 qca_wlan_vendor_wifi_logger_start_policy)) {
5985 hddLog(LOGE, FL("Invalid attribute"));
5986 return -EINVAL;
5987 }
5988
5989 /* Parse and fetch ring id */
5990 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
5991 hddLog(LOGE, FL("attr ATTR failed"));
5992 return -EINVAL;
5993 }
5994 start_log.ringId = nla_get_u32(
5995 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
5996 hddLog(LOG1, FL("Ring ID=%d"), start_log.ringId);
5997
5998 /* Parse and fetch verbose level */
5999 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
6000 hddLog(LOGE, FL("attr verbose_level failed"));
6001 return -EINVAL;
6002 }
6003 start_log.verboseLevel = nla_get_u32(
6004 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
6005 hddLog(LOG1, FL("verbose_level=%d"), start_log.verboseLevel);
6006
6007 /* Parse and fetch flag */
6008 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
6009 hddLog(LOGE, FL("attr flag failed"));
6010 return -EINVAL;
6011 }
6012 start_log.flag = nla_get_u32(
6013 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
6014 hddLog(LOG1, FL("flag=%d"), start_log.flag);
6015
6016 if ((RING_ID_PER_PACKET_STATS == start_log.ringId) &&
Sushant Kaushik33200572015-08-05 16:46:20 +05306017 (!hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable ||
6018 !vos_isPktStatsEnabled()))
6019
Sushant Kaushik8e644982015-09-23 12:18:54 +05306020 {
6021 hddLog(LOGE, FL("per pkt stats not enabled"));
6022 return -EINVAL;
6023 }
Sushant Kaushik8e644982015-09-23 12:18:54 +05306024
Sushant Kaushik33200572015-08-05 16:46:20 +05306025 vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306026 return 0;
6027}
6028
6029/**
6030 * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
6031 * or disable the collection of packet statistics from the firmware
6032 * @wiphy: WIPHY structure pointer
6033 * @wdev: Wireless device structure pointer
6034 * @data: Pointer to the data received
6035 * @data_len: Length of the data received
6036 *
6037 * This function is used to enable or disable the collection of packet
6038 * statistics from the firmware
6039 *
6040 * Return: 0 on success and errno on failure
6041 */
6042static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6043 struct wireless_dev *wdev,
6044 const void *data,
6045 int data_len)
c_manjeecfd1efb2015-09-25 19:32:34 +05306046{
6047 int ret = 0;
6048
6049 vos_ssr_protect(__func__);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306050
6051 ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
6052 wdev, data, data_len);
c_manjeecfd1efb2015-09-25 19:32:34 +05306053 vos_ssr_unprotect(__func__);
6054
6055 return ret;
c_manjeecfd1efb2015-09-25 19:32:34 +05306056}
6057
6058
Agarwal Ashish738843c2014-09-25 12:27:56 +05306059static const struct nla_policy
6060wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
6061 +1] =
6062{
6063 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
6064};
6065
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306066static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306067 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306068 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306069 int data_len)
6070{
6071 struct net_device *dev = wdev->netdev;
6072 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6073 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6074 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6075 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
6076 eHalStatus status;
6077 u32 dfsFlag = 0;
6078
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306079 ENTER();
6080
Agarwal Ashish738843c2014-09-25 12:27:56 +05306081 status = wlan_hdd_validate_context(pHddCtx);
6082 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05306083 return -EINVAL;
6084 }
6085 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
6086 data, data_len,
6087 wlan_hdd_set_no_dfs_flag_config_policy)) {
6088 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6089 return -EINVAL;
6090 }
6091
6092 /* Parse and fetch required bandwidth kbps */
6093 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
6094 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
6095 return -EINVAL;
6096 }
6097
6098 dfsFlag = nla_get_u32(
6099 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
6100 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
6101 dfsFlag);
6102
6103 pHddCtx->disable_dfs_flag = dfsFlag;
6104
6105 sme_disable_dfs_channel(hHal, dfsFlag);
6106 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306107
6108 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05306109 return 0;
6110}
Atul Mittal115287b2014-07-08 13:26:33 +05306111
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306112static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
6113 struct wireless_dev *wdev,
6114 const void *data,
6115 int data_len)
6116{
6117 int ret = 0;
6118
6119 vos_ssr_protect(__func__);
6120 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
6121 vos_ssr_unprotect(__func__);
6122
6123 return ret;
6124
6125}
6126
Mukul Sharma2a271632014-10-13 14:59:01 +05306127const struct
6128nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
6129{
6130 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
6131 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
6132};
6133
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306134static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05306135 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05306136{
6137
6138 u8 bssid[6] = {0};
6139 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6140 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6141 eHalStatus status = eHAL_STATUS_SUCCESS;
6142 v_U32_t isFwrRoamEnabled = FALSE;
6143 int ret;
6144
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306145 ENTER();
6146
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306147 ret = wlan_hdd_validate_context(pHddCtx);
6148 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306149 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05306150 }
6151
6152 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
6153 data, data_len,
6154 qca_wlan_vendor_attr);
6155 if (ret){
6156 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6157 return -EINVAL;
6158 }
6159
6160 /* Parse and fetch Enable flag */
6161 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
6162 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
6163 return -EINVAL;
6164 }
6165
6166 isFwrRoamEnabled = nla_get_u32(
6167 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
6168
6169 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
6170
6171 /* Parse and fetch bssid */
6172 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
6173 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
6174 return -EINVAL;
6175 }
6176
6177 memcpy(bssid, nla_data(
6178 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
6179 sizeof(bssid));
6180 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
6181
6182 //Update roaming
6183 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306184 if (!HAL_STATUS_SUCCESS(status)) {
6185 hddLog(LOGE,
6186 FL("sme_ConfigFwrRoaming failed (err=%d)"), status);
6187 return -EINVAL;
6188 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306189 EXIT();
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306190 return 0;
Mukul Sharma2a271632014-10-13 14:59:01 +05306191}
6192
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306193static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
6194 struct wireless_dev *wdev, const void *data, int data_len)
6195{
6196 int ret = 0;
6197
6198 vos_ssr_protect(__func__);
6199 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
6200 vos_ssr_unprotect(__func__);
6201
6202 return ret;
6203}
6204
Sushant Kaushik847890c2015-09-28 16:05:17 +05306205static const struct
6206nla_policy
6207qca_wlan_vendor_get_wifi_info_policy[
6208 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
6209 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
6210 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
6211};
6212
6213
6214/**
6215 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6216 * @wiphy: pointer to wireless wiphy structure.
6217 * @wdev: pointer to wireless_dev structure.
6218 * @data: Pointer to the data to be passed via vendor interface
6219 * @data_len:Length of the data to be passed
6220 *
6221 * This is called when wlan driver needs to send wifi driver related info
6222 * (driver/fw version) to the user space application upon request.
6223 *
6224 * Return: Return the Success or Failure code.
6225 */
6226static int __wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6227 struct wireless_dev *wdev,
6228 const void *data, int data_len)
6229{
6230 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6231 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
6232 tSirVersionString version;
6233 uint32 version_len;
6234 uint8 attr;
6235 int status;
6236 struct sk_buff *reply_skb = NULL;
6237
6238 if (VOS_FTM_MODE == hdd_get_conparam()) {
6239 hddLog(LOGE, FL("Command not allowed in FTM mode"));
6240 return -EINVAL;
6241 }
6242
6243 status = wlan_hdd_validate_context(hdd_ctx);
6244 if (0 != status) {
6245 hddLog(LOGE, FL("HDD context is not valid"));
6246 return -EINVAL;
6247 }
6248
6249 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
6250 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
6251 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
6252 return -EINVAL;
6253 }
6254
6255 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
6256 hddLog(LOG1, FL("Rcvd req for Driver version Driver version is %s"),
6257 QWLAN_VERSIONSTR);
6258 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
6259 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
6260 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
6261 hddLog(LOG1, FL("Rcvd req for FW version FW version is %s"),
6262 hdd_ctx->fw_Version);
6263 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
6264 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
6265 } else {
6266 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
6267 return -EINVAL;
6268 }
6269
6270 version_len = strlen(version);
6271 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
6272 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
6273 if (!reply_skb) {
6274 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6275 return -ENOMEM;
6276 }
6277
6278 if (nla_put(reply_skb, attr, version_len, version)) {
6279 hddLog(LOGE, FL("nla put fail"));
6280 kfree_skb(reply_skb);
6281 return -EINVAL;
6282 }
6283
6284 return cfg80211_vendor_cmd_reply(reply_skb);
6285}
6286
6287/**
6288 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6289 * @wiphy: pointer to wireless wiphy structure.
6290 * @wdev: pointer to wireless_dev structure.
6291 * @data: Pointer to the data to be passed via vendor interface
6292 * @data_len:Length of the data to be passed
6293 * @data_len: Length of the data received
6294 *
6295 * This function is used to enable or disable the collection of packet
6296 * statistics from the firmware
6297 *
6298 * Return: 0 on success and errno on failure
6299 */
6300
6301static int
6302wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6303 struct wireless_dev *wdev,
6304 const void *data, int data_len)
6305
6306
6307{
6308 int ret = 0;
6309
6310 vos_ssr_protect(__func__);
6311 ret = __wlan_hdd_cfg80211_get_wifi_info(wiphy,
6312 wdev, data, data_len);
6313 vos_ssr_unprotect(__func__);
6314
6315 return ret;
6316}
6317
6318
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306319/*
6320 * define short names for the global vendor params
6321 * used by __wlan_hdd_cfg80211_monitor_rssi()
6322 */
6323#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX
6324#define PARAM_REQUEST_ID QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID
6325#define PARAM_CONTROL QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL
6326#define PARAM_MIN_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI
6327#define PARAM_MAX_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI
6328
6329/**---------------------------------------------------------------------------
6330
6331 \brief hdd_rssi_monitor_start_done - callback to be executed when rssi
6332 monitor start is completed successfully.
6333
6334 \return - None
6335
6336 --------------------------------------------------------------------------*/
6337void hdd_rssi_monitor_start_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6338{
6339 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6340
6341 if (NULL == pHddCtx)
6342 {
6343 hddLog(VOS_TRACE_LEVEL_ERROR,
6344 "%s: HDD context is NULL",__func__);
6345 return;
6346 }
6347
6348 if (VOS_STATUS_SUCCESS == status)
6349 {
6350 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor start successful"));
6351 }
6352 else
6353 {
6354 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor start not successful"));
6355 }
6356
6357 return;
6358}
6359
6360/**---------------------------------------------------------------------------
6361
6362 \brief hdd_rssi_monitor_stop_done - callback to be executed when rssi monitor
6363 stop is completed successfully.
6364
6365 \return - None
6366
6367 --------------------------------------------------------------------------*/
6368void hdd_rssi_monitor_stop_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6369{
6370 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6371
6372 if (NULL == pHddCtx)
6373 {
6374 hddLog(VOS_TRACE_LEVEL_ERROR,
6375 "%s: HDD context is NULL",__func__);
6376 return;
6377 }
6378
6379 if (VOS_STATUS_SUCCESS == status)
6380 {
6381 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor stop successful"));
6382 }
6383 else
6384 {
6385 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor stop not successful"));
6386 }
6387
6388 return;
6389}
6390
6391/**
6392 * __wlan_hdd_cfg80211_monitor_rssi() - monitor rssi
6393 * @wiphy: Pointer to wireless phy
6394 * @wdev: Pointer to wireless device
6395 * @data: Pointer to data
6396 * @data_len: Data length
6397 *
6398 * Return: 0 on success, negative errno on failure
6399 */
6400
6401static int
6402__wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy,
6403 struct wireless_dev *wdev,
6404 const void *data,
6405 int data_len)
6406{
6407 struct net_device *dev = wdev->netdev;
6408 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6409 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6410 hdd_station_ctx_t *pHddStaCtx;
6411 struct nlattr *tb[PARAM_MAX + 1];
6412 tpSirRssiMonitorReq pReq;
6413 eHalStatus status;
6414 int ret;
6415 uint32_t control;
6416 static const struct nla_policy policy[PARAM_MAX + 1] = {
6417 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6418 [PARAM_CONTROL] = { .type = NLA_U32 },
6419 [PARAM_MIN_RSSI] = { .type = NLA_S8 },
6420 [PARAM_MAX_RSSI] = { .type = NLA_S8 },
6421 };
6422
6423 ENTER();
6424
6425 ret = wlan_hdd_validate_context(hdd_ctx);
6426 if (0 != ret) {
6427 return -EINVAL;
6428 }
6429
6430 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6431 hddLog(LOGE, FL("Not in Connected state!"));
6432 return -ENOTSUPP;
6433 }
6434
6435 if (nla_parse(tb, PARAM_MAX, data, data_len, policy)) {
6436 hddLog(LOGE, FL("Invalid ATTR"));
6437 return -EINVAL;
6438 }
6439
6440 if (!tb[PARAM_REQUEST_ID]) {
6441 hddLog(LOGE, FL("attr request id failed"));
6442 return -EINVAL;
6443 }
6444
6445 if (!tb[PARAM_CONTROL]) {
6446 hddLog(LOGE, FL("attr control failed"));
6447 return -EINVAL;
6448 }
6449
6450 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6451
6452 pReq = vos_mem_malloc(sizeof(tSirRssiMonitorReq));
6453 if(NULL == pReq)
6454 {
6455 hddLog(LOGE,
6456 FL("vos_mem_alloc failed "));
6457 return eHAL_STATUS_FAILED_ALLOC;
6458 }
6459 vos_mem_set(pReq, sizeof(tSirRssiMonitorReq), 0);
6460
6461 pReq->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]);
6462 pReq->sessionId = pAdapter->sessionId;
6463 pReq->rssiMonitorCbContext = hdd_ctx;
6464 control = nla_get_u32(tb[PARAM_CONTROL]);
6465 vos_mem_copy( &pReq->currentBssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
6466
6467 hddLog(LOG1, FL("Request Id: %u Session_id: %d Control: %d"),
6468 pReq->requestId, pReq->sessionId, control);
6469
6470 if (control == QCA_WLAN_RSSI_MONITORING_START) {
6471 if (!tb[PARAM_MIN_RSSI]) {
6472 hddLog(LOGE, FL("attr min rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306473 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306474 }
6475
6476 if (!tb[PARAM_MAX_RSSI]) {
6477 hddLog(LOGE, FL("attr max rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306478 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306479 }
6480
6481 pReq->minRssi = nla_get_s8(tb[PARAM_MIN_RSSI]);
6482 pReq->maxRssi = nla_get_s8(tb[PARAM_MAX_RSSI]);
6483 pReq->rssiMonitorCallback = hdd_rssi_monitor_start_done;
6484
6485 if (!(pReq->minRssi < pReq->maxRssi)) {
6486 hddLog(LOGW, FL("min_rssi: %d must be less than max_rssi: %d"),
6487 pReq->minRssi, pReq->maxRssi);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306488 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306489 }
6490 hddLog(LOG1, FL("Min_rssi: %d Max_rssi: %d"),
6491 pReq->minRssi, pReq->maxRssi);
6492 status = sme_StartRssiMonitoring(hdd_ctx->hHal, pReq);
6493
6494 }
6495 else if (control == QCA_WLAN_RSSI_MONITORING_STOP) {
6496 pReq->rssiMonitorCallback = hdd_rssi_monitor_stop_done;
6497 status = sme_StopRssiMonitoring(hdd_ctx->hHal, pReq);
6498 }
6499 else {
6500 hddLog(LOGE, FL("Invalid control cmd: %d"), control);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306501 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306502 }
6503
6504 if (!HAL_STATUS_SUCCESS(status)) {
6505 hddLog(LOGE,
6506 FL("sme_set_rssi_monitoring failed(err=%d)"), status);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306507 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306508 }
6509
6510 return 0;
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306511fail:
6512 vos_mem_free(pReq);
6513 return -EINVAL;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306514}
6515
6516/*
6517 * done with short names for the global vendor params
6518 * used by __wlan_hdd_cfg80211_monitor_rssi()
6519 */
6520#undef PARAM_MAX
6521#undef PARAM_CONTROL
6522#undef PARAM_REQUEST_ID
6523#undef PARAM_MAX_RSSI
6524#undef PARAM_MIN_RSSI
6525
6526/**
6527 * wlan_hdd_cfg80211_monitor_rssi() - SSR wrapper to rssi monitoring
6528 * @wiphy: wiphy structure pointer
6529 * @wdev: Wireless device structure pointer
6530 * @data: Pointer to the data received
6531 * @data_len: Length of @data
6532 *
6533 * Return: 0 on success; errno on failure
6534 */
6535static int
6536wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, struct wireless_dev *wdev,
6537 const void *data, int data_len)
6538{
6539 int ret;
6540
6541 vos_ssr_protect(__func__);
6542 ret = __wlan_hdd_cfg80211_monitor_rssi(wiphy, wdev, data, data_len);
6543 vos_ssr_unprotect(__func__);
6544
6545 return ret;
6546}
6547
6548/**
6549 * hdd_rssi_threshold_breached_cb() - rssi breached NL event
6550 * @hddctx: HDD context
6551 * @data: rssi breached event data
6552 *
6553 * This function reads the rssi breached event %data and fill in the skb with
6554 * NL attributes and send up the NL event.
6555 * This callback execute in atomic context and must not invoke any
6556 * blocking calls.
6557 *
6558 * Return: none
6559 */
6560void hdd_rssi_threshold_breached_cb(void *hddctx,
6561 struct rssi_breach_event *data)
6562{
6563 hdd_context_t *pHddCtx = (hdd_context_t *)hddctx;
6564 int status;
6565 struct sk_buff *skb;
6566
6567 ENTER();
6568 status = wlan_hdd_validate_context(pHddCtx);
6569
6570 if (0 != status) {
6571 return;
6572 }
6573
6574 if (!data) {
6575 hddLog(LOGE, FL("data is null"));
6576 return;
6577 }
6578
6579 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
6580#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
6581 NULL,
6582#endif
6583 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
6584 QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX,
6585 GFP_KERNEL);
6586
6587 if (!skb) {
6588 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
6589 return;
6590 }
6591
6592 hddLog(LOG1, "Req Id: %u Current rssi: %d",
6593 data->request_id, data->curr_rssi);
6594 hddLog(LOG1, "Current BSSID: "MAC_ADDRESS_STR,
6595 MAC_ADDR_ARRAY(data->curr_bssid.bytes));
6596
6597 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
6598 data->request_id) ||
6599 nla_put(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID,
6600 sizeof(data->curr_bssid), data->curr_bssid.bytes) ||
6601 nla_put_s8(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI,
6602 data->curr_rssi)) {
6603 hddLog(LOGE, FL("nla put fail"));
6604 goto fail;
6605 }
6606
6607 cfg80211_vendor_event(skb, GFP_KERNEL);
6608 return;
6609
6610fail:
6611 kfree_skb(skb);
6612 return;
6613}
6614
6615
6616
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306617/**
6618 * __wlan_hdd_cfg80211_setband() - set band
6619 * @wiphy: Pointer to wireless phy
6620 * @wdev: Pointer to wireless device
6621 * @data: Pointer to data
6622 * @data_len: Data length
6623 *
6624 * Return: 0 on success, negative errno on failure
6625 */
6626static int
6627__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6628 struct wireless_dev *wdev,
6629 const void *data,
6630 int data_len)
6631{
6632 struct net_device *dev = wdev->netdev;
6633 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6634 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6635 int ret;
6636 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
6637 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
6638
6639 ENTER();
6640
6641 ret = wlan_hdd_validate_context(hdd_ctx);
6642 if (0 != ret) {
6643 hddLog(LOGE, FL("HDD context is not valid"));
6644 return ret;
6645 }
6646
6647 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
6648 policy)) {
6649 hddLog(LOGE, FL("Invalid ATTR"));
6650 return -EINVAL;
6651 }
6652
6653 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
6654 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
6655 return -EINVAL;
6656 }
6657
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306658 hdd_ctx->isSetBandByNL = TRUE;
6659 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306660 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306661 hdd_ctx->isSetBandByNL = FALSE;
6662
6663 EXIT();
6664 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306665}
6666
6667/**
6668 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
6669 * @wiphy: wiphy structure pointer
6670 * @wdev: Wireless device structure pointer
6671 * @data: Pointer to the data received
6672 * @data_len: Length of @data
6673 *
6674 * Return: 0 on success; errno on failure
6675 */
6676static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6677 struct wireless_dev *wdev,
6678 const void *data,
6679 int data_len)
6680{
6681 int ret = 0;
6682
6683 vos_ssr_protect(__func__);
6684 ret = __wlan_hdd_cfg80211_setband(wiphy,
6685 wdev, data, data_len);
6686 vos_ssr_unprotect(__func__);
6687
6688 return ret;
6689}
6690
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05306691#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
6692/**
6693 * hdd_map_req_id_to_pattern_id() - map request id to pattern id
6694 * @hdd_ctx: HDD context
6695 * @request_id: [input] request id
6696 * @pattern_id: [output] pattern id
6697 *
6698 * This function loops through request id to pattern id array
6699 * if the slot is available, store the request id and return pattern id
6700 * if entry exists, return the pattern id
6701 *
6702 * Return: 0 on success and errno on failure
6703 */
6704static int hdd_map_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
6705 uint32_t request_id,
6706 uint8_t *pattern_id)
6707{
6708 uint32_t i;
6709
6710 mutex_lock(&hdd_ctx->op_ctx.op_lock);
6711 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
6712 {
6713 if (hdd_ctx->op_ctx.op_table[i].request_id == 0)
6714 {
6715 hdd_ctx->op_ctx.op_table[i].request_id = request_id;
6716 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6717 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6718 return 0;
6719 } else if (hdd_ctx->op_ctx.op_table[i].request_id ==
6720 request_id) {
6721 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6722 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6723 return 0;
6724 }
6725 }
6726 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6727 return -EINVAL;
6728}
6729
6730/**
6731 * hdd_unmap_req_id_to_pattern_id() - unmap request id to pattern id
6732 * @hdd_ctx: HDD context
6733 * @request_id: [input] request id
6734 * @pattern_id: [output] pattern id
6735 *
6736 * This function loops through request id to pattern id array
6737 * reset request id to 0 (slot available again) and
6738 * return pattern id
6739 *
6740 * Return: 0 on success and errno on failure
6741 */
6742static int hdd_unmap_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
6743 uint32_t request_id,
6744 uint8_t *pattern_id)
6745{
6746 uint32_t i;
6747
6748 mutex_lock(&hdd_ctx->op_ctx.op_lock);
6749 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
6750 {
6751 if (hdd_ctx->op_ctx.op_table[i].request_id == request_id)
6752 {
6753 hdd_ctx->op_ctx.op_table[i].request_id = 0;
6754 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6755 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6756 return 0;
6757 }
6758 }
6759 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6760 return -EINVAL;
6761}
6762
6763
6764/*
6765 * define short names for the global vendor params
6766 * used by __wlan_hdd_cfg80211_offloaded_packets()
6767 */
6768#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX
6769#define PARAM_REQUEST_ID \
6770 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID
6771#define PARAM_CONTROL \
6772 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL
6773#define PARAM_IP_PACKET \
6774 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA
6775#define PARAM_SRC_MAC_ADDR \
6776 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR
6777#define PARAM_DST_MAC_ADDR \
6778 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR
6779#define PARAM_PERIOD QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD
6780
6781/**
6782 * wlan_hdd_add_tx_ptrn() - add tx pattern
6783 * @adapter: adapter pointer
6784 * @hdd_ctx: hdd context
6785 * @tb: nl attributes
6786 *
6787 * This function reads the NL attributes and forms a AddTxPtrn message
6788 * posts it to SME.
6789 *
6790 */
6791static int
6792wlan_hdd_add_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
6793 struct nlattr **tb)
6794{
6795 struct sSirAddPeriodicTxPtrn *add_req;
6796 eHalStatus status;
6797 uint32_t request_id, ret, len;
6798 uint8_t pattern_id = 0;
6799 v_MACADDR_t dst_addr;
6800 uint16_t eth_type = htons(ETH_P_IP);
6801
6802 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(adapter)))
6803 {
6804 hddLog(LOGE, FL("Not in Connected state!"));
6805 return -ENOTSUPP;
6806 }
6807
6808 add_req = vos_mem_malloc(sizeof(*add_req));
6809 if (!add_req)
6810 {
6811 hddLog(LOGE, FL("memory allocation failed"));
6812 return -ENOMEM;
6813 }
6814
6815 /* Parse and fetch request Id */
6816 if (!tb[PARAM_REQUEST_ID])
6817 {
6818 hddLog(LOGE, FL("attr request id failed"));
6819 goto fail;
6820 }
6821
6822 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
6823 hddLog(LOG1, FL("Request Id: %u"), request_id);
6824 if (request_id == 0)
6825 {
6826 hddLog(LOGE, FL("request_id cannot be zero"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306827 goto fail;
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05306828 }
6829
6830 if (!tb[PARAM_PERIOD])
6831 {
6832 hddLog(LOGE, FL("attr period failed"));
6833 goto fail;
6834 }
6835 add_req->usPtrnIntervalMs = nla_get_u32(tb[PARAM_PERIOD]);
6836 hddLog(LOG1, FL("Period: %u ms"), add_req->usPtrnIntervalMs);
6837 if (add_req->usPtrnIntervalMs == 0)
6838 {
6839 hddLog(LOGE, FL("Invalid interval zero, return failure"));
6840 goto fail;
6841 }
6842
6843 if (!tb[PARAM_SRC_MAC_ADDR])
6844 {
6845 hddLog(LOGE, FL("attr source mac address failed"));
6846 goto fail;
6847 }
6848 nla_memcpy(add_req->macAddress, tb[PARAM_SRC_MAC_ADDR],
6849 VOS_MAC_ADDR_SIZE);
6850 hddLog(LOG1, "input src mac address: "MAC_ADDRESS_STR,
6851 MAC_ADDR_ARRAY(add_req->macAddress));
6852
6853 if (memcmp(add_req->macAddress, adapter->macAddressCurrent.bytes,
6854 VOS_MAC_ADDR_SIZE))
6855 {
6856 hddLog(LOGE,
6857 FL("input src mac address and connected ap bssid are different"));
6858 goto fail;
6859 }
6860
6861 if (!tb[PARAM_DST_MAC_ADDR])
6862 {
6863 hddLog(LOGE, FL("attr dst mac address failed"));
6864 goto fail;
6865 }
6866 nla_memcpy(dst_addr.bytes, tb[PARAM_DST_MAC_ADDR], VOS_MAC_ADDR_SIZE);
6867 hddLog(LOG1, "input dst mac address: "MAC_ADDRESS_STR,
6868 MAC_ADDR_ARRAY(dst_addr.bytes));
6869
6870 if (!tb[PARAM_IP_PACKET])
6871 {
6872 hddLog(LOGE, FL("attr ip packet failed"));
6873 goto fail;
6874 }
6875 add_req->ucPtrnSize = nla_len(tb[PARAM_IP_PACKET]);
6876 hddLog(LOG1, FL("IP packet len: %u"), add_req->ucPtrnSize);
6877
6878 if (add_req->ucPtrnSize < 0 ||
6879 add_req->ucPtrnSize > (PERIODIC_TX_PTRN_MAX_SIZE -
6880 HDD_ETH_HEADER_LEN))
6881 {
6882 hddLog(LOGE, FL("Invalid IP packet len: %d"),
6883 add_req->ucPtrnSize);
6884 goto fail;
6885 }
6886
6887 len = 0;
6888 vos_mem_copy(&add_req->ucPattern[0], dst_addr.bytes, VOS_MAC_ADDR_SIZE);
6889 len += VOS_MAC_ADDR_SIZE;
6890 vos_mem_copy(&add_req->ucPattern[len], add_req->macAddress,
6891 VOS_MAC_ADDR_SIZE);
6892 len += VOS_MAC_ADDR_SIZE;
6893 vos_mem_copy(&add_req->ucPattern[len], &eth_type, 2);
6894 len += 2;
6895
6896 /*
6897 * This is the IP packet, add 14 bytes Ethernet (802.3) header
6898 * ------------------------------------------------------------
6899 * | 14 bytes Ethernet (802.3) header | IP header and payload |
6900 * ------------------------------------------------------------
6901 */
6902 vos_mem_copy(&add_req->ucPattern[len],
6903 nla_data(tb[PARAM_IP_PACKET]),
6904 add_req->ucPtrnSize);
6905 add_req->ucPtrnSize += len;
6906
6907 VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6908 add_req->ucPattern, add_req->ucPtrnSize);
6909
6910 ret = hdd_map_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
6911 if (ret)
6912 {
6913 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
6914 goto fail;
6915 }
6916 add_req->ucPtrnId = pattern_id;
6917 hddLog(LOG1, FL("pattern id: %d"), add_req->ucPtrnId);
6918
6919 status = sme_AddPeriodicTxPtrn(hdd_ctx->hHal, add_req);
6920 if (!HAL_STATUS_SUCCESS(status))
6921 {
6922 hddLog(LOGE,
6923 FL("sme_AddPeriodicTxPtrn failed (err=%d)"), status);
6924 goto fail;
6925 }
6926
6927 EXIT();
6928 vos_mem_free(add_req);
6929 return 0;
6930
6931fail:
6932 vos_mem_free(add_req);
6933 return -EINVAL;
6934}
6935
6936/**
6937 * wlan_hdd_del_tx_ptrn() - delete tx pattern
6938 * @adapter: adapter pointer
6939 * @hdd_ctx: hdd context
6940 * @tb: nl attributes
6941 *
6942 * This function reads the NL attributes and forms a DelTxPtrn message
6943 * posts it to SME.
6944 *
6945 */
6946static int
6947wlan_hdd_del_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
6948 struct nlattr **tb)
6949{
6950 struct sSirDelPeriodicTxPtrn *del_req;
6951 eHalStatus status;
6952 uint32_t request_id, ret;
6953 uint8_t pattern_id = 0;
6954
6955 /* Parse and fetch request Id */
6956 if (!tb[PARAM_REQUEST_ID])
6957 {
6958 hddLog(LOGE, FL("attr request id failed"));
6959 return -EINVAL;
6960 }
6961 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
6962 if (request_id == 0)
6963 {
6964 hddLog(LOGE, FL("request_id cannot be zero"));
6965 return -EINVAL;
6966 }
6967
6968 ret = hdd_unmap_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
6969 if (ret)
6970 {
6971 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
6972 return -EINVAL;
6973 }
6974
6975 del_req = vos_mem_malloc(sizeof(*del_req));
6976 if (!del_req)
6977 {
6978 hddLog(LOGE, FL("memory allocation failed"));
6979 return -ENOMEM;
6980 }
6981
6982 vos_mem_set(del_req, sizeof(*del_req), 0);
6983 vos_mem_copy(del_req->macAddress, adapter->macAddressCurrent.bytes,
6984 VOS_MAC_ADDR_SIZE);
6985 hddLog(LOG1, MAC_ADDRESS_STR, MAC_ADDR_ARRAY(del_req->macAddress));
6986 del_req->ucPatternIdBitmap |= (0x1 << pattern_id);
6987 hddLog(LOG1, FL("Request Id: %u Pattern id: %d, bitmap %04x"),
6988 request_id, pattern_id, del_req->ucPatternIdBitmap);
6989
6990 status = sme_DelPeriodicTxPtrn(hdd_ctx->hHal, del_req);
6991 if (!HAL_STATUS_SUCCESS(status))
6992 {
6993 hddLog(LOGE,
6994 FL("sme_DelPeriodicTxPtrn failed (err=%d)"), status);
6995 goto fail;
6996 }
6997
6998 EXIT();
6999 vos_mem_free(del_req);
7000 return 0;
7001
7002fail:
7003 vos_mem_free(del_req);
7004 return -EINVAL;
7005}
7006
7007
7008/**
7009 * __wlan_hdd_cfg80211_offloaded_packets() - send offloaded packets
7010 * @wiphy: Pointer to wireless phy
7011 * @wdev: Pointer to wireless device
7012 * @data: Pointer to data
7013 * @data_len: Data length
7014 *
7015 * Return: 0 on success, negative errno on failure
7016 */
7017static int
7018__wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7019 struct wireless_dev *wdev,
7020 const void *data,
7021 int data_len)
7022{
7023 struct net_device *dev = wdev->netdev;
7024 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7025 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7026 struct nlattr *tb[PARAM_MAX + 1];
7027 uint8_t control;
7028 int ret;
7029 static const struct nla_policy policy[PARAM_MAX + 1] =
7030 {
7031 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
7032 [PARAM_CONTROL] = { .type = NLA_U32 },
7033 [PARAM_SRC_MAC_ADDR] = { .type = NLA_BINARY,
7034 .len = VOS_MAC_ADDR_SIZE },
7035 [PARAM_DST_MAC_ADDR] = { .type = NLA_BINARY,
7036 .len = VOS_MAC_ADDR_SIZE },
7037 [PARAM_PERIOD] = { .type = NLA_U32 },
7038 };
7039
7040 ENTER();
7041
7042 ret = wlan_hdd_validate_context(hdd_ctx);
7043 if (0 != ret)
7044 {
7045 hddLog(LOGE, FL("HDD context is not valid"));
7046 return ret;
7047 }
7048
7049 if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN))
7050 {
7051 hddLog(LOGE,
7052 FL("Periodic Tx Pattern Offload feature is not supported in FW!"));
7053 return -ENOTSUPP;
7054 }
7055
7056 if (nla_parse(tb, PARAM_MAX, data, data_len, policy))
7057 {
7058 hddLog(LOGE, FL("Invalid ATTR"));
7059 return -EINVAL;
7060 }
7061
7062 if (!tb[PARAM_CONTROL])
7063 {
7064 hddLog(LOGE, FL("attr control failed"));
7065 return -EINVAL;
7066 }
7067 control = nla_get_u32(tb[PARAM_CONTROL]);
7068 hddLog(LOG1, FL("Control: %d"), control);
7069
7070 if (control == WLAN_START_OFFLOADED_PACKETS)
7071 return wlan_hdd_add_tx_ptrn(adapter, hdd_ctx, tb);
7072 else if (control == WLAN_STOP_OFFLOADED_PACKETS)
7073 return wlan_hdd_del_tx_ptrn(adapter, hdd_ctx, tb);
7074 else
7075 {
7076 hddLog(LOGE, FL("Invalid control: %d"), control);
7077 return -EINVAL;
7078 }
7079}
7080
7081/*
7082 * done with short names for the global vendor params
7083 * used by __wlan_hdd_cfg80211_offloaded_packets()
7084 */
7085#undef PARAM_MAX
7086#undef PARAM_REQUEST_ID
7087#undef PARAM_CONTROL
7088#undef PARAM_IP_PACKET
7089#undef PARAM_SRC_MAC_ADDR
7090#undef PARAM_DST_MAC_ADDR
7091#undef PARAM_PERIOD
7092
7093/**
7094 * wlan_hdd_cfg80211_offloaded_packets() - Wrapper to offload packets
7095 * @wiphy: wiphy structure pointer
7096 * @wdev: Wireless device structure pointer
7097 * @data: Pointer to the data received
7098 * @data_len: Length of @data
7099 *
7100 * Return: 0 on success; errno on failure
7101 */
7102static int wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7103 struct wireless_dev *wdev,
7104 const void *data,
7105 int data_len)
7106{
7107 int ret = 0;
7108
7109 vos_ssr_protect(__func__);
7110 ret = __wlan_hdd_cfg80211_offloaded_packets(wiphy,
7111 wdev, data, data_len);
7112 vos_ssr_unprotect(__func__);
7113
7114 return ret;
7115}
7116#endif
7117
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307118static const struct
7119nla_policy
7120qca_wlan_vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
7121 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
7122};
7123
7124/**
7125 * wlan_hdd_cfg80211_get_link_properties() - This function is used to
7126 * get link properties like nss, rate flags and operating frequency for
7127 * the connection with the given peer.
7128 * @wiphy: WIPHY structure pointer
7129 * @wdev: Wireless device structure pointer
7130 * @data: Pointer to the data received
7131 * @data_len: Length of the data received
7132 *
7133 * This function return the above link properties on success.
7134 *
7135 * Return: 0 on success and errno on failure
7136 */
7137static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
7138 struct wireless_dev *wdev,
7139 const void *data,
7140 int data_len)
7141{
7142 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7143 struct net_device *dev = wdev->netdev;
7144 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7145 hdd_station_ctx_t *hdd_sta_ctx;
7146 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX+1];
7147 uint8_t peer_mac[VOS_MAC_ADDR_SIZE];
7148 uint32_t sta_id;
7149 struct sk_buff *reply_skb;
7150 uint32_t rate_flags = 0;
7151 uint8_t nss;
7152 uint8_t final_rate_flags = 0;
7153 uint32_t freq;
7154 v_CONTEXT_t pVosContext = NULL;
7155 ptSapContext pSapCtx = NULL;
7156
7157 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
7158 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
7159 return -EINVAL;
7160 }
7161
7162 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7163 qca_wlan_vendor_attr_policy)) {
7164 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid attribute"));
7165 return -EINVAL;
7166 }
7167
7168 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
7169 hddLog(VOS_TRACE_LEVEL_ERROR,
7170 FL("Attribute peerMac not provided for mode=%d"),
7171 adapter->device_mode);
7172 return -EINVAL;
7173 }
7174
7175 memcpy(peer_mac, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
7176 sizeof(peer_mac));
7177 hddLog(VOS_TRACE_LEVEL_INFO,
7178 FL("peerMac="MAC_ADDRESS_STR" for device_mode:%d"),
7179 MAC_ADDR_ARRAY(peer_mac), adapter->device_mode);
7180
7181 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
7182 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
7183 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
7184 if ((hdd_sta_ctx->conn_info.connState !=
7185 eConnectionState_Associated) ||
7186 !vos_mem_compare(hdd_sta_ctx->conn_info.bssId, peer_mac,
7187 VOS_MAC_ADDRESS_LEN)) {
7188 hddLog(VOS_TRACE_LEVEL_ERROR,
7189 FL("Not Associated to mac "MAC_ADDRESS_STR),
7190 MAC_ADDR_ARRAY(peer_mac));
7191 return -EINVAL;
7192 }
7193
7194 nss = 1; //pronto supports only one spatial stream
7195 freq = vos_chan_to_freq(
7196 hdd_sta_ctx->conn_info.operationChannel);
7197 rate_flags = hdd_sta_ctx->conn_info.rate_flags;
7198
7199 } else if (adapter->device_mode == WLAN_HDD_P2P_GO ||
7200 adapter->device_mode == WLAN_HDD_SOFTAP) {
7201
7202 pVosContext = ( WLAN_HDD_GET_CTX(adapter))->pvosContext;
7203 pSapCtx = VOS_GET_SAP_CB(pVosContext);
7204 if(pSapCtx == NULL){
7205 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7206 FL("psapCtx is NULL"));
7207 return -ENOENT;
7208 }
7209
7210
7211 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
7212 if (pSapCtx->aStaInfo[sta_id].isUsed &&
7213 !vos_is_macaddr_broadcast(
7214 &pSapCtx->aStaInfo[sta_id].macAddrSTA) &&
7215 vos_mem_compare(
7216 &pSapCtx->aStaInfo[sta_id].macAddrSTA,
7217 peer_mac, VOS_MAC_ADDRESS_LEN))
7218 break;
7219 }
7220
7221 if (WLAN_MAX_STA_COUNT == sta_id) {
7222 hddLog(VOS_TRACE_LEVEL_ERROR,
7223 FL("No active peer with mac="MAC_ADDRESS_STR),
7224 MAC_ADDR_ARRAY(peer_mac));
7225 return -EINVAL;
7226 }
7227
7228 nss = 1; //pronto supports only one spatial stream
7229 freq = vos_chan_to_freq(
7230 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operatingChannel);
7231 rate_flags = pSapCtx->aStaInfo[sta_id].rate_flags;
7232 } else {
7233 hddLog(VOS_TRACE_LEVEL_ERROR,
7234 FL("Not Associated! with mac"MAC_ADDRESS_STR),
7235 MAC_ADDR_ARRAY(peer_mac));
7236 return -EINVAL;
7237 }
7238
7239 if (!(rate_flags & eHAL_TX_RATE_LEGACY)) {
7240 if (rate_flags & eHAL_TX_RATE_VHT80) {
7241 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7242 final_rate_flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
7243 } else if (rate_flags & eHAL_TX_RATE_VHT40) {
7244 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7245 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7246 } else if (rate_flags & eHAL_TX_RATE_VHT20) {
7247 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7248 } else if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40)) {
7249 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7250 if (rate_flags & eHAL_TX_RATE_HT40)
7251 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7252 }
7253
7254 if (rate_flags & eHAL_TX_RATE_SGI) {
7255 if (!(final_rate_flags & RATE_INFO_FLAGS_VHT_MCS))
7256 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7257 final_rate_flags |= RATE_INFO_FLAGS_SHORT_GI;
7258 }
7259 }
7260
7261 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7262 sizeof(u8) + sizeof(u8) + sizeof(u32) + NLMSG_HDRLEN);
7263
7264 if (NULL == reply_skb) {
7265 hddLog(VOS_TRACE_LEVEL_ERROR,
7266 FL("getLinkProperties: skb alloc failed"));
7267 return -EINVAL;
7268 }
7269
7270 if (nla_put_u8(reply_skb,
7271 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS,
7272 nss) ||
7273 nla_put_u8(reply_skb,
7274 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS,
7275 final_rate_flags) ||
7276 nla_put_u32(reply_skb,
7277 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ,
7278 freq)) {
7279 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_put failed"));
7280 kfree_skb(reply_skb);
7281 return -EINVAL;
7282 }
7283
7284 return cfg80211_vendor_cmd_reply(reply_skb);
7285}
7286
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307287#define BEACON_MISS_THRESH_2_4 \
7288 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24
7289#define BEACON_MISS_THRESH_5_0 \
7290 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307291#define PARAM_WIFICONFIG_MAX QCA_WLAN_VENDOR_ATTR_CONFIG_MAX
7292#define PARAM_MODULATED_DTIM QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM
7293#define PARAM_STATS_AVG_FACTOR QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR
7294#define PARAM_GUARD_TIME QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307295#define PARAM_BCNMISS_PENALTY_PARAM_COUNT \
7296 QCA_WLAN_VENDOR_ATTR_CONFIG_PENALIZE_AFTER_NCONS_BEACON_MISS
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307297
7298/**
7299 * __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7300 * vendor command
7301 *
7302 * @wiphy: wiphy device pointer
7303 * @wdev: wireless device pointer
7304 * @data: Vendor command data buffer
7305 * @data_len: Buffer length
7306 *
7307 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7308 *
7309 * Return: EOK or other error codes.
7310 */
7311
7312static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7313 struct wireless_dev *wdev,
7314 const void *data,
7315 int data_len)
7316{
7317 struct net_device *dev = wdev->netdev;
7318 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7319 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7320 hdd_station_ctx_t *pHddStaCtx;
7321 struct nlattr *tb[PARAM_WIFICONFIG_MAX + 1];
7322 tpSetWifiConfigParams pReq;
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307323 tModifyRoamParamsReqParams modifyRoamParamsReq;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307324 eHalStatus status;
7325 int ret_val;
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307326 uint8_t hb_thresh_val;
7327
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307328 static const struct nla_policy policy[PARAM_WIFICONFIG_MAX + 1] = {
7329 [PARAM_STATS_AVG_FACTOR] = { .type = NLA_U16 },
7330 [PARAM_MODULATED_DTIM] = { .type = NLA_U32 },
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307331 [PARAM_GUARD_TIME] = { .type = NLA_U32},
7332 [PARAM_BCNMISS_PENALTY_PARAM_COUNT] =
7333 { .type = NLA_U32},
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307334 [BEACON_MISS_THRESH_2_4] = { .type = NLA_U8 },
7335 [BEACON_MISS_THRESH_5_0] = { .type = NLA_U8 },
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307336 };
7337
7338 ENTER();
7339
7340 if (VOS_FTM_MODE == hdd_get_conparam()) {
7341 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7342 return -EINVAL;
7343 }
7344
7345 ret_val = wlan_hdd_validate_context(pHddCtx);
7346 if (ret_val) {
7347 return ret_val;
7348 }
7349
7350 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7351
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307352 if (nla_parse(tb, PARAM_WIFICONFIG_MAX, data, data_len, policy)) {
7353 hddLog(LOGE, FL("Invalid ATTR"));
7354 return -EINVAL;
7355 }
7356
7357 /* check the Wifi Capability */
7358 if ( (TRUE != pHddCtx->cfg_ini->fEnableWifiConfig) &&
7359 (TRUE != sme_IsFeatureSupportedByFW(WIFI_CONFIG)))
7360 {
7361 hddLog(VOS_TRACE_LEVEL_ERROR,
7362 FL("WIFICONFIG not supported by Firmware"));
7363 return -EINVAL;
7364 }
7365
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307366 if (tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]) {
7367 modifyRoamParamsReq.param = WIFI_CONFIG_SET_BCNMISS_PENALTY_COUNT;
7368 modifyRoamParamsReq.value =
7369 nla_get_u32(tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]);
7370
7371 if (eHAL_STATUS_SUCCESS !=
7372 sme_setBcnMissPenaltyCount(pHddCtx->hHal,&modifyRoamParamsReq))
7373 {
7374 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed", __func__);
7375 ret_val = -EINVAL;
7376 }
7377 return ret_val;
7378 }
7379
7380 /* Moved this down in order to provide provision to set beacon
7381 * miss penalty count irrespective of connection state.
7382 */
7383 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
7384 hddLog(LOGE, FL("Not in Connected state!"));
7385 return -ENOTSUPP;
7386 }
7387
7388 pReq = vos_mem_malloc(sizeof(tSetWifiConfigParams));
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307389
7390 if (!pReq) {
7391 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7392 "%s: Not able to allocate memory for tSetWifiConfigParams",
7393 __func__);
7394 return eHAL_STATUS_E_MALLOC_FAILED;
7395 }
7396
7397 vos_mem_set(pReq, sizeof(tSetWifiConfigParams), 0);
7398
7399 pReq->sessionId = pAdapter->sessionId;
7400 vos_mem_copy( &pReq->bssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
7401
7402 if (tb[PARAM_MODULATED_DTIM]) {
7403 pReq->paramValue = nla_get_u32(
7404 tb[PARAM_MODULATED_DTIM]);
7405 hddLog(LOG1, FL("Modulated DTIM: pReq->paramValue:%d "),
7406 pReq->paramValue);
Arun Khandavalli876886f2015-11-23 11:42:27 +05307407 pHddCtx->cfg_ini->enableDynamicDTIM = pReq->paramValue;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307408 hdd_set_pwrparams(pHddCtx);
7409 if (BMPS == pmcGetPmcState(pHddCtx->hHal)) {
7410 hddLog( LOG1, FL("WifiConfig: Requesting FullPower!"));
7411
7412 sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
7413 iw_full_power_cbfn, pAdapter,
7414 eSME_FULL_PWR_NEEDED_BY_HDD);
7415 }
7416 else
7417 {
7418 hddLog( LOG1, FL("WifiConfig Not in BMPS state"));
7419 }
7420 }
7421
7422 if (tb[PARAM_STATS_AVG_FACTOR]) {
7423 pReq->paramType = WIFI_CONFIG_SET_AVG_STATS_FACTOR;
7424 pReq->paramValue = nla_get_u16(
7425 tb[PARAM_STATS_AVG_FACTOR]);
7426 hddLog(LOG1, FL("AVG_STATS_FACTOR pReq->paramType:%d,pReq->paramValue:%d "),
7427 pReq->paramType, pReq->paramValue);
7428 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7429
7430 if (eHAL_STATUS_SUCCESS != status)
7431 {
7432 vos_mem_free(pReq);
7433 pReq = NULL;
7434 ret_val = -EPERM;
7435 return ret_val;
7436 }
7437 }
7438
7439
7440 if (tb[PARAM_GUARD_TIME]) {
7441 pReq->paramType = WIFI_CONFIG_SET_GUARD_TIME;
7442 pReq->paramValue = nla_get_u32(
7443 tb[PARAM_GUARD_TIME]);
7444 hddLog(LOG1, FL("GUARD_TIME pReq->paramType:%d,pReq->paramValue:%d "),
7445 pReq->paramType, pReq->paramValue);
7446 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7447
7448 if (eHAL_STATUS_SUCCESS != status)
7449 {
7450 vos_mem_free(pReq);
7451 pReq = NULL;
7452 ret_val = -EPERM;
7453 return ret_val;
7454 }
7455
7456 }
7457
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307458 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]) {
7459 hb_thresh_val = nla_get_u8(
7460 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]);
7461
7462 hddLog(LOG1, "WLAN set heartbeat threshold for 2.4Ghz %d",
7463 hb_thresh_val);
7464 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7465 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
7466 NULL, eANI_BOOLEAN_FALSE);
7467
7468 status = sme_update_hb_threshold(
7469 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
7470 WNI_CFG_HEART_BEAT_THRESHOLD,
7471 hb_thresh_val, eCSR_BAND_24);
7472 if (eHAL_STATUS_SUCCESS != status) {
7473 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
7474 vos_mem_free(pReq);
7475 pReq = NULL;
7476 return -EPERM;
7477 }
7478 }
7479
7480 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]) {
7481 hb_thresh_val = nla_get_u8(
7482 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]);
7483
7484 hddLog(LOG1, "WLAN set heartbeat threshold for 5Ghz %d",
7485 hb_thresh_val);
7486 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7487 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
7488 NULL, eANI_BOOLEAN_FALSE);
7489
7490 status = sme_update_hb_threshold(
7491 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
7492 WNI_CFG_HEART_BEAT_THRESHOLD,
7493 hb_thresh_val, eCSR_BAND_5G);
7494 if (eHAL_STATUS_SUCCESS != status) {
7495 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
7496 vos_mem_free(pReq);
7497 pReq = NULL;
7498 return -EPERM;
7499 }
7500 }
7501
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307502 EXIT();
7503 return ret_val;
7504}
7505
7506/**
7507 * wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7508 * vendor command
7509 *
7510 * @wiphy: wiphy device pointer
7511 * @wdev: wireless device pointer
7512 * @data: Vendor command data buffer
7513 * @data_len: Buffer length
7514 *
7515 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7516 *
7517 * Return: EOK or other error codes.
7518 */
7519static int wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7520 struct wireless_dev *wdev,
7521 const void *data,
7522 int data_len)
7523{
7524 int ret;
7525
7526 vos_ssr_protect(__func__);
7527 ret = __wlan_hdd_cfg80211_wifi_configuration_set(wiphy, wdev,
7528 data, data_len);
7529 vos_ssr_unprotect(__func__);
7530
7531 return ret;
7532}
Anurag Chouhan6ee81542017-02-09 18:09:27 +05307533
7534/*
7535 * define short names for the global vendor params
7536 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
7537 */
7538#define STATS_SET_INVALID \
7539 QCA_ATTR_NUD_STATS_SET_INVALID
7540#define STATS_SET_START \
7541 QCA_ATTR_NUD_STATS_SET_START
7542#define STATS_GW_IPV4 \
7543 QCA_ATTR_NUD_STATS_GW_IPV4
7544#define STATS_SET_MAX \
7545 QCA_ATTR_NUD_STATS_SET_MAX
7546
7547const struct nla_policy
7548qca_wlan_vendor_set_nud_stats[STATS_SET_MAX +1] =
7549{
7550 [STATS_SET_START] = {.type = NLA_FLAG },
7551 [STATS_GW_IPV4] = {.type = NLA_U32 },
7552};
7553
7554/**
7555 * hdd_set_nud_stats_cb() - hdd callback api to get status
7556 * @data: pointer to adapter
7557 * @rsp: status
7558 *
7559 * Return: None
7560 */
7561static void hdd_set_nud_stats_cb(void *data, VOS_STATUS rsp)
7562{
7563
7564 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
7565
7566 if (NULL == adapter)
7567 return;
7568
7569 if (VOS_STATUS_SUCCESS == rsp) {
7570 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7571 "%s success received STATS_SET_START", __func__);
7572 } else {
7573 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7574 "%s STATS_SET_START Failed!!", __func__);
7575 }
7576 return;
7577}
7578
7579/**
7580 * __wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
7581 * @wiphy: pointer to wireless wiphy structure.
7582 * @wdev: pointer to wireless_dev structure.
7583 * @data: pointer to apfind configuration data.
7584 * @data_len: the length in byte of apfind data.
7585 *
7586 * This is called when wlan driver needs to send arp stats to
7587 * firmware.
7588 *
7589 * Return: An error code or 0 on success.
7590 */
7591static int __wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
7592 struct wireless_dev *wdev,
7593 const void *data, int data_len)
7594{
7595 struct nlattr *tb[STATS_SET_MAX + 1];
7596 struct net_device *dev = wdev->netdev;
7597 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7598 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05307599 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
Anurag Chouhan6ee81542017-02-09 18:09:27 +05307600 setArpStatsParams arp_stats_params;
7601 int err = 0;
7602
7603 ENTER();
7604
7605 err = wlan_hdd_validate_context(hdd_ctx);
7606 if (0 != err)
7607 return err;
7608
7609 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
7610 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7611 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
7612 return -EINVAL;
7613 }
7614
7615 err = nla_parse(tb, STATS_SET_MAX, data, data_len,
7616 qca_wlan_vendor_set_nud_stats);
7617 if (err)
7618 {
7619 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7620 "%s STATS_SET_START ATTR", __func__);
7621 return err;
7622 }
7623
7624 if (tb[STATS_SET_START])
7625 {
7626 if (!tb[STATS_GW_IPV4]) {
7627 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7628 "%s STATS_SET_START CMD", __func__);
7629 return -EINVAL;
7630 }
7631 arp_stats_params.flag = true;
7632 arp_stats_params.ip_addr = nla_get_u32(tb[STATS_GW_IPV4]);
7633 } else {
7634 arp_stats_params.flag = false;
7635 }
Anurag Chouhan630c5562017-03-23 14:51:47 +05307636 if (arp_stats_params.flag)
Anurag Chouhan6ee81542017-02-09 18:09:27 +05307637 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7638 "%s STATS_SET_START Cleared!!", __func__);
Anurag Chouhan630c5562017-03-23 14:51:47 +05307639 vos_mem_zero(&adapter->hdd_stats.hddArpStats,
7640 sizeof(adapter->hdd_stats.hddArpStats));
Anurag Chouhan6ee81542017-02-09 18:09:27 +05307641
7642 arp_stats_params.pkt_type = 1; // ARP packet type
7643
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05307644 if (arp_stats_params.flag) {
7645 hdd_ctx->track_arp_ip = arp_stats_params.ip_addr;
7646 WLANTL_SetARPFWDatapath(pVosContext, true);
7647 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7648 "%s Set FW in data path for ARP with tgt IP :%d",
7649 __func__, hdd_ctx->track_arp_ip);
7650 }
7651 else {
7652 WLANTL_SetARPFWDatapath(pVosContext, false);
7653 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7654 "%s Remove FW from data path", __func__);
7655 }
7656
Anurag Chouhan6ee81542017-02-09 18:09:27 +05307657 arp_stats_params.rsp_cb_fn = hdd_set_nud_stats_cb;
7658 arp_stats_params.data_ctx = adapter;
7659
7660 if (eHAL_STATUS_SUCCESS !=
7661 sme_set_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
7662 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7663 "%s STATS_SET_START CMD Failed!!", __func__);
7664 return -EINVAL;
7665 }
7666
7667 EXIT();
7668
7669 return err;
7670}
7671
7672/**
7673 * wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
7674 * @wiphy: pointer to wireless wiphy structure.
7675 * @wdev: pointer to wireless_dev structure.
7676 * @data: pointer to apfind configuration data.
7677 * @data_len: the length in byte of apfind data.
7678 *
7679 * This is called when wlan driver needs to send arp stats to
7680 * firmware.
7681 *
7682 * Return: An error code or 0 on success.
7683 */
7684static int wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
7685 struct wireless_dev *wdev,
7686 const void *data, int data_len)
7687{
7688 int ret;
7689
7690 vos_ssr_protect(__func__);
7691 ret = __wlan_hdd_cfg80211_set_nud_stats(wiphy, wdev, data, data_len);
7692 vos_ssr_unprotect(__func__);
7693
7694 return ret;
7695}
7696#undef STATS_SET_INVALID
7697#undef STATS_SET_START
7698#undef STATS_GW_IPV4
7699#undef STATS_SET_MAX
7700
7701/*
7702 * define short names for the global vendor params
7703 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
7704 */
7705#define STATS_GET_INVALID \
7706 QCA_ATTR_NUD_STATS_SET_INVALID
7707#define COUNT_FROM_NETDEV \
7708 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
7709#define COUNT_TO_LOWER_MAC \
7710 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
7711#define RX_COUNT_BY_LOWER_MAC \
7712 QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
7713#define COUNT_TX_SUCCESS \
7714 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
7715#define RSP_RX_COUNT_BY_LOWER_MAC \
7716 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
7717#define RSP_RX_COUNT_BY_UPPER_MAC \
7718 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
7719#define RSP_COUNT_TO_NETDEV \
7720 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
7721#define RSP_COUNT_OUT_OF_ORDER_DROP \
7722 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
7723#define AP_LINK_ACTIVE \
7724 QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
7725#define AP_LINK_DAD \
7726 QCA_ATTR_NUD_STATS_AP_LINK_DAD
7727#define STATS_GET_MAX \
7728 QCA_ATTR_NUD_STATS_GET_MAX
7729
7730const struct nla_policy
7731qca_wlan_vendor_get_nud_stats[STATS_GET_MAX +1] =
7732{
7733 [COUNT_FROM_NETDEV] = {.type = NLA_U16 },
7734 [COUNT_TO_LOWER_MAC] = {.type = NLA_U16 },
7735 [RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
7736 [COUNT_TX_SUCCESS] = {.type = NLA_U16 },
7737 [RSP_RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
7738 [RSP_RX_COUNT_BY_UPPER_MAC] = {.type = NLA_U16 },
7739 [RSP_COUNT_TO_NETDEV] = {.type = NLA_U16 },
7740 [RSP_COUNT_OUT_OF_ORDER_DROP] = {.type = NLA_U16 },
7741 [AP_LINK_ACTIVE] = {.type = NLA_FLAG },
7742 [AP_LINK_DAD] = {.type = NLA_FLAG },
7743};
7744
7745static void hdd_get_nud_stats_cb(void *data, rsp_stats *rsp)
7746{
7747
7748 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
7749 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
7750 struct hdd_nud_stats_context *context;
7751 int status;
7752
7753 ENTER();
7754
7755 if (NULL == adapter)
7756 return;
7757
7758 status = wlan_hdd_validate_context(hdd_ctx);
7759 if (0 != status) {
7760 return;
7761 }
7762
7763 if (!rsp) {
7764 hddLog(LOGE, FL("data is null"));
7765 return;
7766 }
7767
7768 adapter->hdd_stats.hddArpStats.tx_fw_cnt = rsp->tx_fw_cnt;
7769 adapter->hdd_stats.hddArpStats.rx_fw_cnt = rsp->rx_fw_cnt;
7770 adapter->hdd_stats.hddArpStats.tx_ack_cnt = rsp->tx_ack_cnt;
7771 adapter->dad |= rsp->dad;
7772
7773 spin_lock(&hdd_context_lock);
7774 context = &hdd_ctx->nud_stats_context;
7775 complete(&context->response_event);
7776 spin_unlock(&hdd_context_lock);
7777
7778 return;
7779}
7780static int __wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
7781 struct wireless_dev *wdev,
7782 const void *data, int data_len)
7783{
7784 int err = 0;
7785 unsigned long rc;
7786 struct hdd_nud_stats_context *context;
7787 struct net_device *dev = wdev->netdev;
7788 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7789 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7790 getArpStatsParams arp_stats_params;
7791 struct sk_buff *skb;
7792
7793 ENTER();
7794
7795 err = wlan_hdd_validate_context(hdd_ctx);
7796 if (0 != err)
7797 return err;
7798
7799 arp_stats_params.pkt_type = WLAN_NUD_STATS_ARP_PKT_TYPE;
7800 arp_stats_params.get_rsp_cb_fn = hdd_get_nud_stats_cb;
7801 arp_stats_params.data_ctx = adapter;
7802
7803 spin_lock(&hdd_context_lock);
7804 context = &hdd_ctx->nud_stats_context;
7805 INIT_COMPLETION(context->response_event);
7806 spin_unlock(&hdd_context_lock);
7807
7808 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
7809 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7810 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
7811 return -EINVAL;
7812 }
7813
7814 if (eHAL_STATUS_SUCCESS !=
7815 sme_get_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
7816 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7817 "%s STATS_SET_START CMD Failed!!", __func__);
7818 return -EINVAL;
7819 }
7820
7821 rc = wait_for_completion_timeout(&context->response_event,
7822 msecs_to_jiffies(WLAN_WAIT_TIME_NUD_STATS));
7823 if (!rc)
7824 {
7825 hddLog(LOGE,
7826 FL("Target response timed out request "));
7827 return -ETIMEDOUT;
7828 }
7829
7830 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7831 WLAN_NUD_STATS_LEN);
7832 if (!skb)
7833 {
7834 hddLog(VOS_TRACE_LEVEL_ERROR,
7835 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
7836 __func__);
7837 return -ENOMEM;
7838 }
7839
7840 if (nla_put_u16(skb, COUNT_FROM_NETDEV,
7841 adapter->hdd_stats.hddArpStats.txCount) ||
7842 nla_put_u16(skb, COUNT_TO_LOWER_MAC,
7843 adapter->hdd_stats.hddArpStats.tx_host_fw_sent) ||
7844 nla_put_u16(skb, RX_COUNT_BY_LOWER_MAC,
7845 adapter->hdd_stats.hddArpStats.tx_fw_cnt) ||
7846 nla_put_u16(skb, COUNT_TX_SUCCESS,
7847 adapter->hdd_stats.hddArpStats.tx_ack_cnt) ||
7848 nla_put_u16(skb, RSP_RX_COUNT_BY_LOWER_MAC,
7849 adapter->hdd_stats.hddArpStats.rx_fw_cnt) ||
7850 nla_put_u16(skb, RSP_RX_COUNT_BY_UPPER_MAC,
7851 adapter->hdd_stats.hddArpStats.rxCount) ||
7852 nla_put_u16(skb, RSP_COUNT_TO_NETDEV,
7853 adapter->hdd_stats.hddArpStats.rxDelivered) ||
7854 nla_put_u16(skb, RSP_COUNT_OUT_OF_ORDER_DROP,
7855 adapter->hdd_stats.hddArpStats.rx_host_drop_reorder)) {
7856 hddLog(LOGE, FL("nla put fail"));
7857 kfree_skb(skb);
7858 return -EINVAL;
7859 }
7860 if (adapter->con_status)
7861 nla_put_flag(skb, AP_LINK_ACTIVE);
7862 if (adapter->dad)
7863 nla_put_flag(skb, AP_LINK_DAD);
7864
7865 cfg80211_vendor_cmd_reply(skb);
7866 return err;
7867}
7868
7869static int wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
7870 struct wireless_dev *wdev,
7871 const void *data, int data_len)
7872{
7873 int ret;
7874
7875 vos_ssr_protect(__func__);
7876 ret = __wlan_hdd_cfg80211_get_nud_stats(wiphy, wdev, data, data_len);
7877 vos_ssr_unprotect(__func__);
7878
7879 return ret;
7880}
7881
7882#undef QCA_ATTR_NUD_STATS_SET_INVALID
7883#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
7884#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
7885#undef QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
7886#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
7887#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
7888#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
7889#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
7890#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
7891#undef QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
7892#undef QCA_ATTR_NUD_STATS_GET_MAX
7893
7894
7895
Kapil Guptaee33bf12016-12-20 18:27:37 +05307896#ifdef WLAN_FEATURE_APFIND
7897/**
7898 * __wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
7899 * @wiphy: pointer to wireless wiphy structure.
7900 * @wdev: pointer to wireless_dev structure.
7901 * @data: pointer to apfind configuration data.
7902 * @data_len: the length in byte of apfind data.
7903 *
7904 * This is called when wlan driver needs to send APFIND configurations to
7905 * firmware.
7906 *
7907 * Return: An error code or 0 on success.
7908 */
7909static int __wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
7910 struct wireless_dev *wdev,
7911 const void *data, int data_len)
7912{
7913 struct sme_ap_find_request_req apfind_req;
7914 VOS_STATUS status;
7915 int ret_val;
7916 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7917
7918 ENTER();
7919
7920 ret_val = wlan_hdd_validate_context(hdd_ctx);
7921 if (ret_val)
7922 return ret_val;
7923
7924 if (VOS_FTM_MODE == hdd_get_conparam()) {
7925 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7926 return -EPERM;
7927 }
7928
7929 apfind_req.request_data_len = data_len;
7930 apfind_req.request_data = data;
7931
7932 status = sme_apfind_set_cmd(&apfind_req);
7933 if (VOS_STATUS_SUCCESS != status) {
7934 ret_val = -EIO;
7935 }
7936 return ret_val;
7937}
7938
7939/**
7940 * wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
7941 * @wiphy: pointer to wireless wiphy structure.
7942 * @wdev: pointer to wireless_dev structure.
7943 * @data: pointer to apfind configuration data.
7944 * @data_len: the length in byte of apfind data.
7945 *
7946 * This is called when wlan driver needs to send APFIND configurations to
7947 * firmware.
7948 *
7949 * Return: An error code or 0 on success.
7950 */
7951static int wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
7952 struct wireless_dev *wdev,
7953 const void *data, int data_len)
7954{
7955 int ret;
7956
7957 vos_ssr_protect(__func__);
7958 ret = __wlan_hdd_cfg80211_apfind_cmd(wiphy, wdev, data, data_len);
7959 vos_ssr_unprotect(__func__);
7960
7961 return ret;
7962}
7963#endif /* WLAN_FEATURE_APFIND */
Sunil Duttc69bccb2014-05-26 21:30:20 +05307964const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
7965{
Mukul Sharma2a271632014-10-13 14:59:01 +05307966 {
7967 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7968 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
7969 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7970 WIPHY_VENDOR_CMD_NEED_NETDEV |
7971 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307972 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05307973 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05307974
7975 {
7976 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7977 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
7978 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7979 WIPHY_VENDOR_CMD_NEED_NETDEV |
7980 WIPHY_VENDOR_CMD_NEED_RUNNING,
7981 .doit = wlan_hdd_cfg80211_nan_request
7982 },
7983
Sunil Duttc69bccb2014-05-26 21:30:20 +05307984#ifdef WLAN_FEATURE_LINK_LAYER_STATS
7985 {
7986 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7987 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
7988 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7989 WIPHY_VENDOR_CMD_NEED_NETDEV |
7990 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307991 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05307992 },
7993
7994 {
7995 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7996 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
7997 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7998 WIPHY_VENDOR_CMD_NEED_NETDEV |
7999 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308000 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05308001 },
8002
8003 {
8004 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8005 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
8006 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8007 WIPHY_VENDOR_CMD_NEED_NETDEV |
8008 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308009 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05308010 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308011#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308012#ifdef WLAN_FEATURE_EXTSCAN
8013 {
8014 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8015 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
8016 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8017 WIPHY_VENDOR_CMD_NEED_NETDEV |
8018 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308019 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05308020 },
8021 {
8022 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8023 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
8024 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8025 WIPHY_VENDOR_CMD_NEED_NETDEV |
8026 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308027 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05308028 },
8029 {
8030 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8031 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
8032 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8033 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308034 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05308035 },
8036 {
8037 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8038 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
8039 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8040 WIPHY_VENDOR_CMD_NEED_NETDEV |
8041 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308042 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05308043 },
8044 {
8045 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8046 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
8047 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8048 WIPHY_VENDOR_CMD_NEED_NETDEV |
8049 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308050 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05308051 },
8052 {
8053 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8054 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
8055 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8056 WIPHY_VENDOR_CMD_NEED_NETDEV |
8057 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308058 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308059 },
8060 {
8061 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8062 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
8063 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8064 WIPHY_VENDOR_CMD_NEED_NETDEV |
8065 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308066 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308067 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05308068 {
8069 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8070 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST,
8071 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8072 WIPHY_VENDOR_CMD_NEED_NETDEV |
8073 WIPHY_VENDOR_CMD_NEED_RUNNING,
8074 .doit = wlan_hdd_cfg80211_extscan_set_ssid_hotlist
8075 },
8076 {
8077 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8078 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST,
8079 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8080 WIPHY_VENDOR_CMD_NEED_NETDEV |
8081 WIPHY_VENDOR_CMD_NEED_RUNNING,
8082 .doit = wlan_hdd_cfg80211_extscan_reset_ssid_hotlist
8083 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308084#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308085/*EXT TDLS*/
8086 {
8087 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8088 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
8089 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8090 WIPHY_VENDOR_CMD_NEED_NETDEV |
8091 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308092 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05308093 },
8094 {
8095 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8096 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
8097 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8098 WIPHY_VENDOR_CMD_NEED_NETDEV |
8099 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308100 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05308101 },
8102 {
8103 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8104 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
8105 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8106 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308107 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05308108 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05308109 {
8110 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8111 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
8112 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8113 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308114 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05308115 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05308116 {
8117 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8118 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
8119 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8120 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308121 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05308122 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308123 {
8124 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8125 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
8126 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8127 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308128 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308129 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308130 {
8131 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8132 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
8133 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8134 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308135 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308136 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308137 {
8138 .info.vendor_id = QCA_NL80211_VENDOR_ID,
c_manjeecfd1efb2015-09-25 19:32:34 +05308139 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
8140 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8141 WIPHY_VENDOR_CMD_NEED_NETDEV |
8142 WIPHY_VENDOR_CMD_NEED_RUNNING,
8143 .doit = wlan_hdd_cfg80211_get_fw_mem_dump
8144 },
8145 {
8146 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308147 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
8148 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8149 WIPHY_VENDOR_CMD_NEED_NETDEV |
8150 WIPHY_VENDOR_CMD_NEED_RUNNING,
8151 .doit = wlan_hdd_cfg80211_setband
Sushant Kaushik8e644982015-09-23 12:18:54 +05308152 },
8153 {
8154 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8155 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
8156 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8157 WIPHY_VENDOR_CMD_NEED_NETDEV,
8158 .doit = wlan_hdd_cfg80211_wifi_logger_start
8159 },
Sushant Kaushik847890c2015-09-28 16:05:17 +05308160 {
8161 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8162 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
8163 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8164 WIPHY_VENDOR_CMD_NEED_NETDEV|
8165 WIPHY_VENDOR_CMD_NEED_RUNNING,
8166 .doit = wlan_hdd_cfg80211_get_wifi_info
Sachin Ahujac08f72a2015-09-22 15:25:47 +05308167 },
8168 {
8169 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8170 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
8171 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8172 WIPHY_VENDOR_CMD_NEED_NETDEV |
8173 WIPHY_VENDOR_CMD_NEED_RUNNING,
8174 .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308175 },
8176 {
8177 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8178 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,
8179 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8180 WIPHY_VENDOR_CMD_NEED_NETDEV |
8181 WIPHY_VENDOR_CMD_NEED_RUNNING,
8182 .doit = wlan_hdd_cfg80211_monitor_rssi
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308183 },
8184#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
8185 {
8186 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8187 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS,
8188 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8189 WIPHY_VENDOR_CMD_NEED_NETDEV |
8190 WIPHY_VENDOR_CMD_NEED_RUNNING,
8191 .doit = wlan_hdd_cfg80211_offloaded_packets
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308192 },
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308193#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308194 {
8195 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8196 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
8197 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8198 WIPHY_VENDOR_CMD_NEED_NETDEV |
8199 WIPHY_VENDOR_CMD_NEED_RUNNING,
8200 .doit = wlan_hdd_cfg80211_get_link_properties
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05308201 },
8202 {
8203 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8204 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION,
8205 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8206 WIPHY_VENDOR_CMD_NEED_NETDEV |
8207 WIPHY_VENDOR_CMD_NEED_RUNNING,
8208 .doit = wlan_hdd_cfg80211_wifi_configuration_set
Kapil Guptaee33bf12016-12-20 18:27:37 +05308209 },
8210#ifdef WLAN_FEATURE_APFIND
8211 {
8212 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8213 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_APFIND,
8214 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8215 WIPHY_VENDOR_CMD_NEED_NETDEV,
8216 .doit = wlan_hdd_cfg80211_apfind_cmd
8217 },
8218#endif /* WLAN_FEATURE_APFIND */
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308219 {
8220 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8221 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET,
8222 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8223 WIPHY_VENDOR_CMD_NEED_NETDEV |
8224 WIPHY_VENDOR_CMD_NEED_RUNNING,
8225 .doit = wlan_hdd_cfg80211_set_nud_stats
8226 },
8227 {
8228 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8229 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8230 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8231 WIPHY_VENDOR_CMD_NEED_NETDEV |
8232 WIPHY_VENDOR_CMD_NEED_RUNNING,
8233 .doit = wlan_hdd_cfg80211_get_nud_stats
8234 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308235};
8236
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008237/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05308238static const
8239struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008240{
8241#ifdef FEATURE_WLAN_CH_AVOID
8242 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05308243 .vendor_id = QCA_NL80211_VENDOR_ID,
8244 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008245 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308246#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
8247#ifdef WLAN_FEATURE_LINK_LAYER_STATS
8248 {
8249 /* Index = 1*/
8250 .vendor_id = QCA_NL80211_VENDOR_ID,
8251 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
8252 },
8253 {
8254 /* Index = 2*/
8255 .vendor_id = QCA_NL80211_VENDOR_ID,
8256 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
8257 },
8258 {
8259 /* Index = 3*/
8260 .vendor_id = QCA_NL80211_VENDOR_ID,
8261 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
8262 },
8263 {
8264 /* Index = 4*/
8265 .vendor_id = QCA_NL80211_VENDOR_ID,
8266 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
8267 },
8268 {
8269 /* Index = 5*/
8270 .vendor_id = QCA_NL80211_VENDOR_ID,
8271 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
8272 },
8273 {
8274 /* Index = 6*/
8275 .vendor_id = QCA_NL80211_VENDOR_ID,
8276 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
8277 },
8278#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308279#ifdef WLAN_FEATURE_EXTSCAN
8280 {
8281 .vendor_id = QCA_NL80211_VENDOR_ID,
8282 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
8283 },
8284 {
8285 .vendor_id = QCA_NL80211_VENDOR_ID,
8286 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
8287 },
8288 {
8289 .vendor_id = QCA_NL80211_VENDOR_ID,
8290 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
8291 },
8292 {
8293 .vendor_id = QCA_NL80211_VENDOR_ID,
8294 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
8295 },
8296 {
8297 .vendor_id = QCA_NL80211_VENDOR_ID,
8298 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
8299 },
8300 {
8301 .vendor_id = QCA_NL80211_VENDOR_ID,
8302 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
8303 },
8304 {
8305 .vendor_id = QCA_NL80211_VENDOR_ID,
8306 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
8307 },
8308 {
8309 .vendor_id = QCA_NL80211_VENDOR_ID,
8310 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
8311 },
8312 {
8313 .vendor_id = QCA_NL80211_VENDOR_ID,
8314 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
8315 },
8316 {
8317 .vendor_id = QCA_NL80211_VENDOR_ID,
8318 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
8319 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05308320 {
8321 .vendor_id = QCA_NL80211_VENDOR_ID,
8322 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST
8323 },
8324 {
8325 .vendor_id = QCA_NL80211_VENDOR_ID,
8326 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST
8327 },
8328 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND_INDEX] = {
8329 .vendor_id = QCA_NL80211_VENDOR_ID,
8330 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND
8331 },
8332 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST_INDEX] = {
8333 .vendor_id = QCA_NL80211_VENDOR_ID,
8334 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST
8335 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308336#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308337/*EXT TDLS*/
8338 {
8339 .vendor_id = QCA_NL80211_VENDOR_ID,
8340 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
8341 },
c_manjeecfd1efb2015-09-25 19:32:34 +05308342 [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
8343 .vendor_id = QCA_NL80211_VENDOR_ID,
8344 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
8345 },
8346
Srinivas Dasari030bad32015-02-18 23:23:54 +05308347
Srinivas Dasaribd1cf642017-01-23 14:54:41 +05308348 [QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX] = {
Srinivas Dasari030bad32015-02-18 23:23:54 +05308349 .vendor_id = QCA_NL80211_VENDOR_ID,
8350 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
8351 },
8352
Sushant Kaushik084f6592015-09-10 13:11:56 +05308353 {
8354 .vendor_id = QCA_NL80211_VENDOR_ID,
8355 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308356 },
8357 [QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = {
8358 .vendor_id = QCA_NL80211_VENDOR_ID,
8359 .subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI
8360 },
Padma, Santhosh Kumar7bbc7d92015-12-08 20:23:19 +05308361 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX] = {
8362 .vendor_id = QCA_NL80211_VENDOR_ID,
8363 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST
8364 },
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308365 [QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET_INDEX] = {
8366 .vendor_id = QCA_NL80211_VENDOR_ID,
8367 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8368 },
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008369};
8370
Jeff Johnson295189b2012-06-20 16:38:30 -07008371/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308372 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308373 * This function is called by hdd_wlan_startup()
8374 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308375 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07008376 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308377struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07008378{
8379 struct wiphy *wiphy;
8380 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308381 /*
8382 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07008383 */
8384 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
8385
8386 if (!wiphy)
8387 {
8388 /* Print error and jump into err label and free the memory */
8389 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
8390 return NULL;
8391 }
8392
Sunil Duttc69bccb2014-05-26 21:30:20 +05308393
Jeff Johnson295189b2012-06-20 16:38:30 -07008394 return wiphy;
8395}
8396
Anurag Chouhan343af7e2016-12-16 13:11:19 +05308397#if (LINUX_VERSION_CODE > KERNEL_VERSION(4,4,0)) || \
8398 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
8399/**
8400 * hdd_config_sched_scan_plans_to_wiphy() - configure sched scan plans to wiphy
8401 * @wiphy: pointer to wiphy
8402 * @config: pointer to config
8403 *
8404 * Return: None
8405 */
8406static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
8407 hdd_config_t *config)
8408{
8409 wiphy->max_sched_scan_plans = MAX_SCHED_SCAN_PLANS;
8410 if (config->max_sched_scan_plan_interval)
8411 wiphy->max_sched_scan_plan_interval =
8412 config->max_sched_scan_plan_interval;
8413 if (config->max_sched_scan_plan_iterations)
8414 wiphy->max_sched_scan_plan_iterations =
8415 config->max_sched_scan_plan_iterations;
8416}
8417#else
8418static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
8419 hdd_config_t *config)
8420{
8421}
8422#endif
8423
Jeff Johnson295189b2012-06-20 16:38:30 -07008424/*
8425 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308426 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07008427 * private ioctl to change the band value
8428 */
8429int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
8430{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308431 int i, j;
8432 eNVChannelEnabledType channelEnabledState;
8433
Jeff Johnsone7245742012-09-05 17:12:55 -07008434 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308435
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308436 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07008437 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308438
8439 if (NULL == wiphy->bands[i])
8440 {
8441 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
8442 __func__, i);
8443 continue;
8444 }
8445
8446 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
8447 {
8448 struct ieee80211_supported_band *band = wiphy->bands[i];
8449
8450 channelEnabledState = vos_nv_getChannelEnabledState(
8451 band->channels[j].hw_value);
8452
8453 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
8454 {
Abhishek Singh678227a2014-11-04 10:52:38 +05308455 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308456 continue;
8457 }
8458 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
8459 {
8460 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8461 continue;
8462 }
8463
8464 if (NV_CHANNEL_DISABLE == channelEnabledState ||
8465 NV_CHANNEL_INVALID == channelEnabledState)
8466 {
8467 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8468 }
8469 else if (NV_CHANNEL_DFS == channelEnabledState)
8470 {
8471 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
8472 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
8473 }
8474 else
8475 {
8476 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
8477 |IEEE80211_CHAN_RADAR);
8478 }
8479 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008480 }
8481 return 0;
8482}
8483/*
8484 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308485 * This function is called by hdd_wlan_startup()
8486 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07008487 * This function is used to initialize and register wiphy structure.
8488 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308489int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07008490 struct wiphy *wiphy,
8491 hdd_config_t *pCfg
8492 )
8493{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308494 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05308495 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
8496
Jeff Johnsone7245742012-09-05 17:12:55 -07008497 ENTER();
8498
Jeff Johnson295189b2012-06-20 16:38:30 -07008499 /* Now bind the underlying wlan device with wiphy */
8500 set_wiphy_dev(wiphy, dev);
8501
8502 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07008503
Kiet Lam6c583332013-10-14 05:37:09 +05308504#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07008505 /* the flag for the other case would be initialzed in
8506 vos_init_wiphy_from_nv_bin */
Manjeet Singh9e19de62016-08-18 18:26:41 +05308507#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
8508 wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
8509#else
Amar Singhal0a402232013-10-11 20:57:16 -07008510 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05308511#endif
Manjeet Singh9e19de62016-08-18 18:26:41 +05308512#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07008513
Amar Singhalfddc28c2013-09-05 13:03:40 -07008514 /* This will disable updating of NL channels from passive to
8515 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308516#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
8517 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
8518#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07008519 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308520#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07008521
Amar Singhala49cbc52013-10-08 18:37:44 -07008522
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008523#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07008524 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
8525 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
8526 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07008527 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308528#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Rajeev Kumar Sirasanagandla0d6dd752016-08-17 15:01:39 +05308529 wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308530#else
8531 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
8532#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008533#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07008534
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08008535#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07008536 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08008537#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07008538 || pCfg->isFastRoamIniFeatureEnabled
8539#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08008540#ifdef FEATURE_WLAN_ESE
8541 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07008542#endif
8543 )
8544 {
8545 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
8546 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08008547#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008548#ifdef FEATURE_WLAN_TDLS
8549 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
8550 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
8551#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308552#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05308553 if (pCfg->configPNOScanSupport)
8554 {
8555 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
8556 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
8557 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
8558 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
8559 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308560#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008561
Abhishek Singh10d85972015-04-17 10:27:23 +05308562#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
8563 wiphy->features |= NL80211_FEATURE_HT_IBSS;
8564#endif
8565
Amar Singhalfddc28c2013-09-05 13:03:40 -07008566#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07008567 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
8568 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07008569 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07008570 driver need to determine what to do with both
8571 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07008572
8573 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07008574#else
8575 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07008576#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008577
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308578 wiphy->max_scan_ssids = MAX_SCAN_SSID;
8579
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05308580 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07008581
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308582 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
8583
Jeff Johnson295189b2012-06-20 16:38:30 -07008584 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05308585 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
8586 | BIT(NL80211_IFTYPE_ADHOC)
8587 | BIT(NL80211_IFTYPE_P2P_CLIENT)
8588 | BIT(NL80211_IFTYPE_P2P_GO)
8589 | BIT(NL80211_IFTYPE_AP);
8590
8591 if (VOS_MONITOR_MODE == hdd_get_conparam())
8592 {
8593 wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
8594 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008595
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308596 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008597 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308598#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
8599 if( pCfg->enableMCC )
8600 {
8601 /* Currently, supports up to two channels */
8602 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008603
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308604 if( !pCfg->allowMCCGODiffBI )
8605 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008606
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308607 }
8608 wiphy->iface_combinations = &wlan_hdd_iface_combination;
8609 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008610#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308611 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008612
Jeff Johnson295189b2012-06-20 16:38:30 -07008613 /* Before registering we need to update the ht capabilitied based
8614 * on ini values*/
8615 if( !pCfg->ShortGI20MhzEnable )
8616 {
8617 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
8618 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
Jeff Johnson295189b2012-06-20 16:38:30 -07008619 }
8620
8621 if( !pCfg->ShortGI40MhzEnable )
8622 {
8623 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
8624 }
8625
8626 if( !pCfg->nChannelBondingMode5GHz )
8627 {
8628 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
8629 }
Agrawal Ashish97dec502015-11-26 20:20:58 +05308630 /*
8631 * In case of static linked driver at the time of driver unload,
8632 * module exit doesn't happens. Module cleanup helps in cleaning
8633 * of static memory.
8634 * If driver load happens statically, at the time of driver unload,
8635 * wiphy flags don't get reset because of static memory.
8636 * It's better not to store channel in static memory.
8637 */
8638 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
8639 wiphy->bands[IEEE80211_BAND_2GHZ]->channels =
8640 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_2_4_GHZ));
8641 if (wiphy->bands[IEEE80211_BAND_2GHZ]->channels == NULL)
8642 {
8643 hddLog(VOS_TRACE_LEVEL_ERROR,
8644 FL("Not enough memory to allocate channels"));
8645 return -ENOMEM;
8646 }
8647 vos_mem_copy(wiphy->bands[IEEE80211_BAND_2GHZ]->channels,
8648 &hdd_channels_2_4_GHZ[0],
8649 sizeof(hdd_channels_2_4_GHZ));
Jeff Johnson295189b2012-06-20 16:38:30 -07008650
Agrawal Ashish97dec502015-11-26 20:20:58 +05308651 if (true == hdd_is_5g_supported(pHddCtx))
8652 {
8653 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
8654 wiphy->bands[IEEE80211_BAND_5GHZ]->channels =
8655 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_5_GHZ));
8656 if (wiphy->bands[IEEE80211_BAND_5GHZ]->channels == NULL)
8657 {
8658 hddLog(VOS_TRACE_LEVEL_ERROR,
8659 FL("Not enough memory to allocate channels"));
8660 vos_mem_free(wiphy->bands[IEEE80211_BAND_2GHZ]->channels);
8661 wiphy->bands[IEEE80211_BAND_2GHZ]->channels = NULL;
8662 return -ENOMEM;
8663 }
8664 vos_mem_copy(wiphy->bands[IEEE80211_BAND_5GHZ]->channels,
8665 &hdd_channels_5_GHZ[0],
8666 sizeof(hdd_channels_5_GHZ));
8667 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308668
8669 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
8670 {
8671
8672 if (NULL == wiphy->bands[i])
8673 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05308674 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308675 __func__, i);
8676 continue;
8677 }
8678
8679 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
8680 {
8681 struct ieee80211_supported_band *band = wiphy->bands[i];
8682
8683 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
8684 {
8685 // Enable social channels for P2P
8686 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
8687 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
8688 else
8689 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8690 continue;
8691 }
8692 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
8693 {
8694 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8695 continue;
8696 }
8697 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008698 }
8699 /*Initialise the supported cipher suite details*/
8700 wiphy->cipher_suites = hdd_cipher_suites;
8701 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
8702
8703 /*signal strength in mBm (100*dBm) */
8704 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
8705
8706#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05308707 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07008708#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008709
Sunil Duttc69bccb2014-05-26 21:30:20 +05308710 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
8711 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008712 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
8713 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
8714
Anurag Chouhan343af7e2016-12-16 13:11:19 +05308715 hdd_config_sched_scan_plans_to_wiphy(wiphy, pCfg);
8716
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308717 EXIT();
8718 return 0;
8719}
8720
8721/* In this function we are registering wiphy. */
8722int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
8723{
8724 ENTER();
8725 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008726 if (0 > wiphy_register(wiphy))
8727 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308728 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07008729 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8730 return -EIO;
8731 }
8732
8733 EXIT();
8734 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308735}
Jeff Johnson295189b2012-06-20 16:38:30 -07008736
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308737/* In this function we are updating channel list when,
8738 regulatory domain is FCC and country code is US.
8739 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
8740 As per FCC smart phone is not a indoor device.
8741 GO should not opeate on indoor channels */
8742void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
8743{
8744 int j;
8745 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
8746 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
8747 //Default counrtycode from NV at the time of wiphy initialization.
8748 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
8749 &defaultCountryCode[0]))
8750 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008751 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308752 }
8753 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
8754 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308755 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
8756 {
8757 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
8758 return;
8759 }
8760 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
8761 {
8762 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
8763 // Mark UNII -1 band channel as passive
8764 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
8765 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
8766 }
8767 }
8768}
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05308769/* This function registers for all frame which supplicant is interested in */
8770void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008771{
Jeff Johnson295189b2012-06-20 16:38:30 -07008772 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8773 /* Register for all P2P action, public action etc frames */
8774 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
Jeff Johnsone7245742012-09-05 17:12:55 -07008775 ENTER();
Abhishek Singh16e05762015-11-30 14:29:27 +05308776 /* Register frame indication call back */
8777 sme_register_mgmt_frame_ind_callback(hHal, hdd_indicate_mgmt_frame);
Jeff Johnson295189b2012-06-20 16:38:30 -07008778 /* Right now we are registering these frame when driver is getting
8779 initialized. Once we will move to 2.6.37 kernel, in which we have
8780 frame register ops, we will move this code as a part of that */
8781 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308782 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07008783 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
8784
8785 /* GAS Initial Response */
8786 sme_RegisterMgmtFrame(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_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8791 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
8792
8793 /* GAS Comeback Response */
8794 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8795 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
8796
8797 /* P2P Public Action */
8798 sme_RegisterMgmtFrame(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_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8804 (v_U8_t*)P2P_ACTION_FRAME,
8805 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07008806
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05308807 /* WNM BSS Transition Request frame */
8808 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8809 (v_U8_t*)WNM_BSS_ACTION_FRAME,
8810 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07008811
8812 /* WNM-Notification */
8813 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8814 (v_U8_t*)WNM_NOTIFICATION_FRAME,
8815 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008816}
8817
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05308818void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008819{
Jeff Johnson295189b2012-06-20 16:38:30 -07008820 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8821 /* Register for all P2P action, public action etc frames */
8822 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
8823
Jeff Johnsone7245742012-09-05 17:12:55 -07008824 ENTER();
8825
Jeff Johnson295189b2012-06-20 16:38:30 -07008826 /* Right now we are registering these frame when driver is getting
8827 initialized. Once we will move to 2.6.37 kernel, in which we have
8828 frame register ops, we will move this code as a part of that */
8829 /* GAS Initial Request */
8830
8831 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8832 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
8833
8834 /* GAS Initial Response */
8835 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8836 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308837
Jeff Johnson295189b2012-06-20 16:38:30 -07008838 /* GAS Comeback Request */
8839 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8840 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
8841
8842 /* GAS Comeback Response */
8843 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8844 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
8845
8846 /* P2P Public Action */
8847 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308848 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07008849 P2P_PUBLIC_ACTION_FRAME_SIZE );
8850
8851 /* P2P Action */
8852 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8853 (v_U8_t*)P2P_ACTION_FRAME,
8854 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07008855 /* WNM-Notification */
8856 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8857 (v_U8_t*)WNM_NOTIFICATION_FRAME,
8858 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008859}
8860
8861#ifdef FEATURE_WLAN_WAPI
8862void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05308863 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07008864{
8865 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8866 tCsrRoamSetKey setKey;
8867 v_BOOL_t isConnected = TRUE;
8868 int status = 0;
8869 v_U32_t roamId= 0xFF;
8870 tANI_U8 *pKeyPtr = NULL;
8871 int n = 0;
8872
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308873 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
8874 __func__, hdd_device_modetoString(pAdapter->device_mode),
8875 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008876
Gopichand Nakkalae7480202013-02-11 15:24:22 +05308877 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07008878 setKey.keyId = key_index; // Store Key ID
8879 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
8880 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
8881 setKey.paeRole = 0 ; // the PAE role
8882 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
8883 {
8884 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
8885 }
8886 else
8887 {
8888 isConnected = hdd_connIsConnected(pHddStaCtx);
8889 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
8890 }
8891 setKey.keyLength = key_Len;
8892 pKeyPtr = setKey.Key;
8893 memcpy( pKeyPtr, key, key_Len);
8894
Arif Hussain6d2a3322013-11-17 19:50:10 -08008895 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07008896 __func__, key_Len);
8897 for (n = 0 ; n < key_Len; n++)
8898 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
8899 __func__,n,setKey.Key[n]);
8900
8901 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8902 if ( isConnected )
8903 {
8904 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8905 pAdapter->sessionId, &setKey, &roamId );
8906 }
8907 if ( status != 0 )
8908 {
8909 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8910 "[%4d] sme_RoamSetKey returned ERROR status= %d",
8911 __LINE__, status );
8912 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8913 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308914 /* Need to clear any trace of key value in the memory.
8915 * Thus zero out the memory even though it is local
8916 * variable.
8917 */
8918 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07008919}
8920#endif /* FEATURE_WLAN_WAPI*/
8921
8922#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308923int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07008924 beacon_data_t **ppBeacon,
8925 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008926#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308927int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008928 beacon_data_t **ppBeacon,
8929 struct cfg80211_beacon_data *params,
8930 int dtim_period)
8931#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308932{
Jeff Johnson295189b2012-06-20 16:38:30 -07008933 int size;
8934 beacon_data_t *beacon = NULL;
8935 beacon_data_t *old = NULL;
Kapil Gupta137ef892016-12-13 19:38:00 +05308936 int head_len, tail_len, proberesp_ies_len, assocresp_ies_len;
8937 const u8 *head, *tail, *proberesp_ies, *assocresp_ies;
Jeff Johnson295189b2012-06-20 16:38:30 -07008938
Jeff Johnsone7245742012-09-05 17:12:55 -07008939 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008940 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308941 {
8942 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8943 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008944 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308945 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008946
8947 old = pAdapter->sessionCtx.ap.beacon;
8948
8949 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308950 {
8951 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8952 FL("session(%d) old and new heads points to NULL"),
8953 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008954 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308955 }
8956
8957 if (params->tail && !params->tail_len)
8958 {
8959 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8960 FL("tail_len is zero but tail is not NULL"));
8961 return -EINVAL;
8962 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008963
Jeff Johnson295189b2012-06-20 16:38:30 -07008964#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
8965 /* Kernel 3.0 is not updating dtim_period for set beacon */
8966 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308967 {
8968 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8969 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008970 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308971 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008972#endif
8973
Kapil Gupta137ef892016-12-13 19:38:00 +05308974 if (params->head)
8975 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008976 head_len = params->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05308977 head = params->head;
8978 } else
8979 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008980 head_len = old->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05308981 head = old->head;
8982 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008983
Kapil Gupta137ef892016-12-13 19:38:00 +05308984 if (params->tail || !old)
8985 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008986 tail_len = params->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05308987 tail = params->tail;
8988 } else
8989 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008990 tail_len = old->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05308991 tail = old->tail;
8992 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008993
Kapil Gupta137ef892016-12-13 19:38:00 +05308994 if (params->proberesp_ies || !old)
8995 {
8996 proberesp_ies_len = params->proberesp_ies_len;
8997 proberesp_ies = params->proberesp_ies;
8998 } else
8999 {
9000 proberesp_ies_len = old->proberesp_ies_len;
9001 proberesp_ies = old->proberesp_ies;
9002 }
9003
9004 if (params->assocresp_ies || !old)
9005 {
9006 assocresp_ies_len = params->assocresp_ies_len;
9007 assocresp_ies = params->assocresp_ies;
9008 } else
9009 {
9010 assocresp_ies_len = old->assocresp_ies_len;
9011 assocresp_ies = old->assocresp_ies;
9012 }
9013
9014 size = sizeof(beacon_data_t) + head_len + tail_len +
9015 proberesp_ies_len + assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009016
9017 beacon = kzalloc(size, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009018 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309019 {
9020 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9021 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009022 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309023 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009024
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009025#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Kapil Gupta137ef892016-12-13 19:38:00 +05309026 if (params->dtim_period)
Jeff Johnson295189b2012-06-20 16:38:30 -07009027 beacon->dtim_period = params->dtim_period;
9028 else
9029 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009030#else
Kapil Gupta137ef892016-12-13 19:38:00 +05309031 if (dtim_period)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009032 beacon->dtim_period = dtim_period;
9033 else
9034 beacon->dtim_period = old->dtim_period;
9035#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309036
Jeff Johnson295189b2012-06-20 16:38:30 -07009037 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
9038 beacon->tail = beacon->head + head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309039 beacon->proberesp_ies = beacon->tail + tail_len;
9040 beacon->assocresp_ies = beacon->proberesp_ies + proberesp_ies_len;
9041
Jeff Johnson295189b2012-06-20 16:38:30 -07009042 beacon->head_len = head_len;
9043 beacon->tail_len = tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309044 beacon->proberesp_ies_len = proberesp_ies_len;
9045 beacon->assocresp_ies_len= assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009046
c_manjee527ecac2017-01-25 12:25:27 +05309047 if (head && head_len)
9048 memcpy(beacon->head, head, head_len);
9049 if (tail && tail_len)
9050 memcpy(beacon->tail, tail, tail_len);
9051 if (proberesp_ies && proberesp_ies_len)
9052 memcpy(beacon->proberesp_ies, proberesp_ies, proberesp_ies_len);
9053 if (assocresp_ies && assocresp_ies_len)
9054 memcpy(beacon->assocresp_ies, assocresp_ies, assocresp_ies_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009055
9056 *ppBeacon = beacon;
9057
9058 kfree(old);
9059
9060 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009061}
Jeff Johnson295189b2012-06-20 16:38:30 -07009062
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309063v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
9064#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
9065 const v_U8_t *pIes,
9066#else
9067 v_U8_t *pIes,
9068#endif
9069 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009070{
9071 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309072 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07009073 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309074
Jeff Johnson295189b2012-06-20 16:38:30 -07009075 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309076 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009077 elem_id = ptr[0];
9078 elem_len = ptr[1];
9079 left -= 2;
9080 if(elem_len > left)
9081 {
9082 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07009083 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009084 eid,elem_len,left);
9085 return NULL;
9086 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309087 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009088 {
9089 return ptr;
9090 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309091
Jeff Johnson295189b2012-06-20 16:38:30 -07009092 left -= elem_len;
9093 ptr += (elem_len + 2);
9094 }
9095 return NULL;
9096}
9097
Jeff Johnson295189b2012-06-20 16:38:30 -07009098/* Check if rate is 11g rate or not */
9099static int wlan_hdd_rate_is_11g(u8 rate)
9100{
Sanjay Devnani28322e22013-06-21 16:13:40 -07009101 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009102 u8 i;
9103 for (i = 0; i < 8; i++)
9104 {
9105 if(rate == gRateArray[i])
9106 return TRUE;
9107 }
9108 return FALSE;
9109}
9110
9111/* Check for 11g rate and set proper 11g only mode */
9112static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
9113 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
9114{
9115 u8 i, num_rates = pIe[0];
9116
9117 pIe += 1;
9118 for ( i = 0; i < num_rates; i++)
9119 {
9120 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
9121 {
9122 /* If rate set have 11g rate than change the mode to 11G */
9123 *pSapHw_mode = eSAP_DOT11_MODE_11g;
9124 if (pIe[i] & BASIC_RATE_MASK)
9125 {
9126 /* If we have 11g rate as basic rate, it means mode
9127 is 11g only mode.
9128 */
9129 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
9130 *pCheckRatesfor11g = FALSE;
9131 }
9132 }
9133 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
9134 {
9135 *require_ht = TRUE;
9136 }
9137 }
9138 return;
9139}
9140
9141static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
9142{
9143 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9144 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9145 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9146 u8 checkRatesfor11g = TRUE;
9147 u8 require_ht = FALSE;
9148 u8 *pIe=NULL;
9149
9150 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
9151
9152 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
9153 pBeacon->head_len, WLAN_EID_SUPP_RATES);
9154 if (pIe != NULL)
9155 {
9156 pIe += 1;
9157 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9158 &pConfig->SapHw_mode);
9159 }
9160
9161 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9162 WLAN_EID_EXT_SUPP_RATES);
9163 if (pIe != NULL)
9164 {
9165
9166 pIe += 1;
9167 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9168 &pConfig->SapHw_mode);
9169 }
9170
9171 if( pConfig->channel > 14 )
9172 {
9173 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
9174 }
9175
9176 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9177 WLAN_EID_HT_CAPABILITY);
9178
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309179 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009180 {
9181 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
9182 if(require_ht)
9183 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
9184 }
9185}
9186
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309187static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
9188 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
9189{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009190 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309191 v_U8_t *pIe = NULL;
9192 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9193
9194 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
9195 pBeacon->tail, pBeacon->tail_len);
9196
9197 if (pIe)
9198 {
9199 ielen = pIe[1] + 2;
9200 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9201 {
9202 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
9203 }
9204 else
9205 {
9206 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
9207 return -EINVAL;
9208 }
9209 *total_ielen += ielen;
9210 }
9211 return 0;
9212}
9213
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009214static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
9215 v_U8_t *genie, v_U8_t *total_ielen)
9216{
9217 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9218 int left = pBeacon->tail_len;
9219 v_U8_t *ptr = pBeacon->tail;
9220 v_U8_t elem_id, elem_len;
9221 v_U16_t ielen = 0;
9222
9223 if ( NULL == ptr || 0 == left )
9224 return;
9225
9226 while (left >= 2)
9227 {
9228 elem_id = ptr[0];
9229 elem_len = ptr[1];
9230 left -= 2;
9231 if (elem_len > left)
9232 {
9233 hddLog( VOS_TRACE_LEVEL_ERROR,
9234 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
9235 elem_id, elem_len, left);
9236 return;
9237 }
9238 if (IE_EID_VENDOR == elem_id)
9239 {
9240 /* skipping the VSIE's which we don't want to include or
9241 * it will be included by existing code
9242 */
9243 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
9244#ifdef WLAN_FEATURE_WFD
9245 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
9246#endif
9247 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9248 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9249 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
9250 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9251 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
9252 {
9253 ielen = ptr[1] + 2;
9254 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9255 {
9256 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
9257 *total_ielen += ielen;
9258 }
9259 else
9260 {
9261 hddLog( VOS_TRACE_LEVEL_ERROR,
9262 "IE Length is too big "
9263 "IEs eid=%d elem_len=%d total_ie_lent=%d",
9264 elem_id, elem_len, *total_ielen);
9265 }
9266 }
9267 }
9268
9269 left -= elem_len;
9270 ptr += (elem_len + 2);
9271 }
9272 return;
9273}
9274
Kapil Gupta137ef892016-12-13 19:38:00 +05309275int wlan_hdd_cfg80211_update_apies(hdd_adapter_t *pHostapdAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009276{
9277 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309278 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009279 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07009280 int ret = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +05309281 beacon_data_t *pBeacon = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009282
9283 genie = vos_mem_malloc(MAX_GENIE_LEN);
9284
9285 if(genie == NULL) {
9286
9287 return -ENOMEM;
9288 }
9289
Kapil Gupta137ef892016-12-13 19:38:00 +05309290 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309291 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9292 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009293 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309294 hddLog(LOGE,
9295 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309296 ret = -EINVAL;
9297 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009298 }
9299
9300#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309301 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9302 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
9303 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309304 hddLog(LOGE,
9305 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309306 ret = -EINVAL;
9307 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009308 }
9309#endif
9310
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309311 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9312 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009313 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309314 hddLog(LOGE,
9315 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309316 ret = -EINVAL;
9317 goto done;
9318 }
9319
9320 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
9321 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009322 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07009323 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009324
9325 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9326 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
9327 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
9328 {
9329 hddLog(LOGE,
9330 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009331 ret = -EINVAL;
9332 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009333 }
9334
9335 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9336 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
9337 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9338 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9339 ==eHAL_STATUS_FAILURE)
9340 {
9341 hddLog(LOGE,
9342 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009343 ret = -EINVAL;
9344 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009345 }
9346
9347 // Added for ProResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +05309348 if ((pBeacon->proberesp_ies != NULL) && (pBeacon->proberesp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009349 {
Kapil Gupta137ef892016-12-13 19:38:00 +05309350 u16 rem_probe_resp_ie_len = pBeacon->proberesp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009351 u8 probe_rsp_ie_len[3] = {0};
9352 u8 counter = 0;
9353 /* Check Probe Resp Length if it is greater then 255 then Store
9354 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
9355 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
9356 Store More then 255 bytes into One Variable.
9357 */
9358 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
9359 {
9360 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
9361 {
9362 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
9363 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
9364 }
9365 else
9366 {
9367 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
9368 rem_probe_resp_ie_len = 0;
9369 }
9370 }
9371
9372 rem_probe_resp_ie_len = 0;
9373
9374 if (probe_rsp_ie_len[0] > 0)
9375 {
9376 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9377 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
Kapil Gupta137ef892016-12-13 19:38:00 +05309378 (tANI_U8*)&pBeacon->
9379 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07009380 probe_rsp_ie_len[0], NULL,
9381 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9382 {
9383 hddLog(LOGE,
9384 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009385 ret = -EINVAL;
9386 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009387 }
9388 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
9389 }
9390
9391 if (probe_rsp_ie_len[1] > 0)
9392 {
9393 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9394 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
Kapil Gupta137ef892016-12-13 19:38:00 +05309395 (tANI_U8*)&pBeacon->
9396 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07009397 probe_rsp_ie_len[1], NULL,
9398 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9399 {
9400 hddLog(LOGE,
9401 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009402 ret = -EINVAL;
9403 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009404 }
9405 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
9406 }
9407
9408 if (probe_rsp_ie_len[2] > 0)
9409 {
9410 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9411 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
Kapil Gupta137ef892016-12-13 19:38:00 +05309412 (tANI_U8*)&pBeacon->
9413 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07009414 probe_rsp_ie_len[2], NULL,
9415 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9416 {
9417 hddLog(LOGE,
9418 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009419 ret = -EINVAL;
9420 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009421 }
9422 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
9423 }
9424
9425 if (probe_rsp_ie_len[1] == 0 )
9426 {
9427 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9428 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
9429 eANI_BOOLEAN_FALSE) )
9430 {
9431 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009432 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009433 }
9434 }
9435
9436 if (probe_rsp_ie_len[2] == 0 )
9437 {
9438 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9439 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
9440 eANI_BOOLEAN_FALSE) )
9441 {
9442 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009443 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009444 }
9445 }
9446
9447 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9448 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
9449 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9450 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9451 == eHAL_STATUS_FAILURE)
9452 {
9453 hddLog(LOGE,
9454 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009455 ret = -EINVAL;
9456 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009457 }
9458 }
9459 else
9460 {
9461 // Reset WNI_CFG_PROBE_RSP Flags
9462 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
9463
9464 hddLog(VOS_TRACE_LEVEL_INFO,
9465 "%s: No Probe Response IE received in set beacon",
9466 __func__);
9467 }
9468
9469 // Added for AssocResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +05309470 if ((pBeacon->assocresp_ies != NULL) && (pBeacon->assocresp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009471 {
9472 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
Kapil Gupta137ef892016-12-13 19:38:00 +05309473 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)pBeacon->assocresp_ies,
9474 pBeacon->assocresp_ies_len, NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -07009475 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9476 {
9477 hddLog(LOGE,
9478 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009479 ret = -EINVAL;
9480 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009481 }
9482
9483 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9484 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
9485 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9486 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9487 == eHAL_STATUS_FAILURE)
9488 {
9489 hddLog(LOGE,
9490 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009491 ret = -EINVAL;
9492 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009493 }
9494 }
9495 else
9496 {
9497 hddLog(VOS_TRACE_LEVEL_INFO,
9498 "%s: No Assoc Response IE received in set beacon",
9499 __func__);
9500
9501 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9502 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
9503 eANI_BOOLEAN_FALSE) )
9504 {
9505 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009506 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009507 }
9508 }
9509
Jeff Johnsone7245742012-09-05 17:12:55 -07009510done:
Jeff Johnson295189b2012-06-20 16:38:30 -07009511 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309512 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009513}
Jeff Johnson295189b2012-06-20 16:38:30 -07009514
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309515/*
Jeff Johnson295189b2012-06-20 16:38:30 -07009516 * FUNCTION: wlan_hdd_validate_operation_channel
9517 * called by wlan_hdd_cfg80211_start_bss() and
9518 * wlan_hdd_cfg80211_set_channel()
9519 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309520 * channel list.
9521 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07009522VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07009523{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309524
Jeff Johnson295189b2012-06-20 16:38:30 -07009525 v_U32_t num_ch = 0;
9526 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
9527 u32 indx = 0;
9528 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309529 v_U8_t fValidChannel = FALSE, count = 0;
9530 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309531
Jeff Johnson295189b2012-06-20 16:38:30 -07009532 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
9533
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309534 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07009535 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309536 /* Validate the channel */
9537 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07009538 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309539 if ( channel == rfChannels[count].channelNum )
9540 {
9541 fValidChannel = TRUE;
9542 break;
9543 }
9544 }
9545 if (fValidChannel != TRUE)
9546 {
9547 hddLog(VOS_TRACE_LEVEL_ERROR,
9548 "%s: Invalid Channel [%d]", __func__, channel);
9549 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009550 }
9551 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309552 else
Jeff Johnson295189b2012-06-20 16:38:30 -07009553 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309554 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
9555 valid_ch, &num_ch))
9556 {
9557 hddLog(VOS_TRACE_LEVEL_ERROR,
9558 "%s: failed to get valid channel list", __func__);
9559 return VOS_STATUS_E_FAILURE;
9560 }
9561 for (indx = 0; indx < num_ch; indx++)
9562 {
9563 if (channel == valid_ch[indx])
9564 {
9565 break;
9566 }
9567 }
9568
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05309569 if (indx >= num_ch)
9570 {
9571 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
9572 {
9573 eCsrBand band;
9574 unsigned int freq;
9575
9576 sme_GetFreqBand(hHal, &band);
9577
9578 if (eCSR_BAND_5G == band)
9579 {
9580#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
9581 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
9582 {
9583 freq = ieee80211_channel_to_frequency(channel,
9584 IEEE80211_BAND_2GHZ);
9585 }
9586 else
9587 {
9588 freq = ieee80211_channel_to_frequency(channel,
9589 IEEE80211_BAND_5GHZ);
9590 }
9591#else
9592 freq = ieee80211_channel_to_frequency(channel);
9593#endif
9594 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
9595 return VOS_STATUS_SUCCESS;
9596 }
9597 }
9598
9599 hddLog(VOS_TRACE_LEVEL_ERROR,
9600 "%s: Invalid Channel [%d]", __func__, channel);
9601 return VOS_STATUS_E_FAILURE;
9602 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009603 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05309604
Jeff Johnson295189b2012-06-20 16:38:30 -07009605 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309606
Jeff Johnson295189b2012-06-20 16:38:30 -07009607}
9608
Viral Modi3a32cc52013-02-08 11:14:52 -08009609/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309610 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08009611 * This function is used to set the channel number
9612 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309613static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08009614 struct ieee80211_channel *chan,
9615 enum nl80211_channel_type channel_type
9616 )
9617{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309618 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08009619 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07009620 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08009621 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309622 hdd_context_t *pHddCtx;
9623 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009624
9625 ENTER();
9626
9627 if( NULL == dev )
9628 {
9629 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009630 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08009631 return -ENODEV;
9632 }
9633 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309634
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309635 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9636 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
9637 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08009638 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309639 "%s: device_mode = %s (%d) freq = %d", __func__,
9640 hdd_device_modetoString(pAdapter->device_mode),
9641 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309642
9643 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9644 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309645 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08009646 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309647 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009648 }
9649
9650 /*
9651 * Do freq to chan conversion
9652 * TODO: for 11a
9653 */
9654
9655 channel = ieee80211_frequency_to_channel(freq);
9656
9657 /* Check freq range */
9658 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
9659 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
9660 {
9661 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009662 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08009663 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
9664 WNI_CFG_CURRENT_CHANNEL_STAMAX);
9665 return -EINVAL;
9666 }
9667
9668 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
9669
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05309670 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
9671 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08009672 {
9673 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
9674 {
9675 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009676 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08009677 return -EINVAL;
9678 }
9679 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
9680 "%s: set channel to [%d] for device mode =%d",
9681 __func__, channel,pAdapter->device_mode);
9682 }
9683 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08009684 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08009685 )
9686 {
9687 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9688 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
9689 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9690
9691 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
9692 {
9693 /* Link is up then return cant set channel*/
9694 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009695 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08009696 return -EINVAL;
9697 }
9698
9699 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
9700 pHddStaCtx->conn_info.operationChannel = channel;
9701 pRoamProfile->ChannelInfo.ChannelList =
9702 &pHddStaCtx->conn_info.operationChannel;
9703 }
9704 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08009705 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08009706 )
9707 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309708 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
9709 {
9710 if(VOS_STATUS_SUCCESS !=
9711 wlan_hdd_validate_operation_channel(pAdapter,channel))
9712 {
9713 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009714 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309715 return -EINVAL;
9716 }
9717 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
9718 }
9719 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08009720 {
9721 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
9722
9723 /* If auto channel selection is configured as enable/ 1 then ignore
9724 channel set by supplicant
9725 */
9726 if ( cfg_param->apAutoChannelSelection )
9727 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309728 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
9729 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08009730 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309731 "%s: set channel to auto channel (0) for device mode =%s (%d)",
9732 __func__, hdd_device_modetoString(pAdapter->device_mode),
9733 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08009734 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309735 else
9736 {
9737 if(VOS_STATUS_SUCCESS !=
9738 wlan_hdd_validate_operation_channel(pAdapter,channel))
9739 {
9740 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009741 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309742 return -EINVAL;
9743 }
9744 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
9745 }
Viral Modi3a32cc52013-02-08 11:14:52 -08009746 }
9747 }
9748 else
9749 {
9750 hddLog(VOS_TRACE_LEVEL_FATAL,
9751 "%s: Invalid device mode failed to set valid channel", __func__);
9752 return -EINVAL;
9753 }
9754 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309755 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009756}
9757
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309758static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
9759 struct net_device *dev,
9760 struct ieee80211_channel *chan,
9761 enum nl80211_channel_type channel_type
9762 )
9763{
9764 int ret;
9765
9766 vos_ssr_protect(__func__);
9767 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
9768 vos_ssr_unprotect(__func__);
9769
9770 return ret;
9771}
9772
Anurag Chouhan83026002016-12-13 22:46:21 +05309773#ifdef DHCP_SERVER_OFFLOAD
9774void hdd_dhcp_server_offload_done(void *fw_dhcp_srv_offload_cb_context,
9775 VOS_STATUS status)
9776{
9777 hdd_adapter_t* adapter = (hdd_adapter_t*)fw_dhcp_srv_offload_cb_context;
9778
9779 ENTER();
9780
9781 if (NULL == adapter)
9782 {
9783 hddLog(VOS_TRACE_LEVEL_ERROR,
9784 "%s: adapter is NULL",__func__);
9785 return;
9786 }
9787
9788 adapter->dhcp_status.dhcp_offload_status = status;
9789 vos_event_set(&adapter->dhcp_status.vos_event);
9790 return;
9791}
9792
9793/**
9794 * wlan_hdd_set_dhcp_server_offload() - set dhcp server offload
9795 * @hostapd_adapter: pointer to hostapd adapter.
Anurag Chouhan638f5e22017-03-06 12:28:43 +05309796 * @re_init: flag set if api called post ssr
Anurag Chouhan83026002016-12-13 22:46:21 +05309797 *
9798 * Return: None
9799 */
Anurag Chouhan638f5e22017-03-06 12:28:43 +05309800VOS_STATUS wlan_hdd_set_dhcp_server_offload(hdd_adapter_t *hostapd_adapter,
9801 bool re_init)
Anurag Chouhan83026002016-12-13 22:46:21 +05309802{
9803 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter);
9804 sir_dhcp_srv_offload_info dhcp_srv_info;
9805 tANI_U8 num_entries = 0;
9806 tANI_U8 srv_ip[IPADDR_NUM_ENTRIES];
9807 tANI_U8 num;
9808 tANI_U32 temp;
9809 VOS_STATUS ret;
9810
9811 ENTER();
9812
Anurag Chouhan638f5e22017-03-06 12:28:43 +05309813 if (!re_init) {
9814 ret = wlan_hdd_validate_context(hdd_ctx);
9815 if (0 != ret)
9816 return VOS_STATUS_E_INVAL;
9817 }
Anurag Chouhan83026002016-12-13 22:46:21 +05309818
9819 /* Prepare the request to send to SME */
9820 dhcp_srv_info = vos_mem_malloc(sizeof(*dhcp_srv_info));
9821 if (NULL == dhcp_srv_info) {
9822 hddLog(VOS_TRACE_LEVEL_ERROR,
9823 "%s: could not allocate tDhcpSrvOffloadInfo!", __func__);
9824 return VOS_STATUS_E_NOMEM;
9825 }
9826
9827 vos_mem_zero(dhcp_srv_info, sizeof(*dhcp_srv_info));
9828
9829 dhcp_srv_info->bssidx = hostapd_adapter->sessionId;
9830 dhcp_srv_info->dhcp_srv_offload_enabled = TRUE;
9831 dhcp_srv_info->dhcp_client_num = hdd_ctx->cfg_ini->dhcp_max_num_clients;
9832 dhcp_srv_info->start_lsb = hdd_ctx->cfg_ini->dhcp_start_lsb;
9833 dhcp_srv_info->dhcp_offload_callback = hdd_dhcp_server_offload_done;
9834 dhcp_srv_info->dhcp_server_offload_cb_context = hostapd_adapter;
9835
9836 hdd_string_to_u8_array(hdd_ctx->cfg_ini->dhcp_srv_ip,
9837 srv_ip,
9838 &num_entries,
Anurag Chouhanac145c22016-11-22 16:51:47 +05309839 IPADDR_NUM_ENTRIES, ".");
Anurag Chouhan83026002016-12-13 22:46:21 +05309840 if (num_entries != IPADDR_NUM_ENTRIES) {
9841 hddLog(VOS_TRACE_LEVEL_ERROR,
9842 "%s: incorrect IP address (%s) assigned for DHCP server!",
9843 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
9844 vos_mem_free(dhcp_srv_info);
9845 return VOS_STATUS_E_FAILURE;
9846 }
9847
9848 if ((srv_ip[0] >= 224) && (srv_ip[0] <= 239)) {
9849 hddLog(VOS_TRACE_LEVEL_ERROR,
9850 "%s: invalid IP address (%s)! It could NOT be multicast IP address!",
9851 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
9852 vos_mem_free(dhcp_srv_info);
9853 return VOS_STATUS_E_FAILURE;
9854 }
9855
9856 if (srv_ip[IPADDR_NUM_ENTRIES-1] >= DHCP_START_POOL_ADDRESS) {
9857 hddLog(VOS_TRACE_LEVEL_ERROR,
9858 "%s: invalid IP address (%s)! The last field must be less than 100!",
9859 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
9860 vos_mem_free(dhcp_srv_info);
9861 return VOS_STATUS_E_FAILURE;
9862 }
9863
9864 for (num = 0; num < num_entries; num++) {
9865 temp = srv_ip[num];
9866 dhcp_srv_info->dhcp_srv_ip |= (temp << (8 * num));
9867 }
9868
9869 if (eHAL_STATUS_SUCCESS !=
9870 sme_set_dhcp_srv_offload(hdd_ctx->hHal, dhcp_srv_info)) {
9871 hddLog(VOS_TRACE_LEVEL_ERROR,
9872 "%s: sme_set_dhcp_srv_offload fail!", __func__);
9873 vos_mem_free(dhcp_srv_info);
9874 return VOS_STATUS_E_FAILURE;
9875 }
9876
9877 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
9878 "%s: enable DHCP Server offload successfully!", __func__);
9879
9880 vos_mem_free(dhcp_srv_info);
9881 return 0;
9882}
9883#endif /* DHCP_SERVER_OFFLOAD */
9884
Jeff Johnson295189b2012-06-20 16:38:30 -07009885#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9886static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
9887 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009888#else
9889static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
9890 struct cfg80211_beacon_data *params,
9891 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309892 enum nl80211_hidden_ssid hidden_ssid,
9893 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009894#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009895{
9896 tsap_Config_t *pConfig;
9897 beacon_data_t *pBeacon = NULL;
9898 struct ieee80211_mgmt *pMgmt_frame;
9899 v_U8_t *pIe=NULL;
9900 v_U16_t capab_info;
9901 eCsrAuthType RSNAuthType;
9902 eCsrEncryptionType RSNEncryptType;
9903 eCsrEncryptionType mcRSNEncryptType;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +05309904 int status = VOS_STATUS_SUCCESS, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009905 tpWLAN_SAPEventCB pSapEventCallback;
9906 hdd_hostapd_state_t *pHostapdState;
Jeff Johnson295189b2012-06-20 16:38:30 -07009907 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309908 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009909 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309910 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07009911 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08009912 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05309913 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07009914 v_BOOL_t MFPCapable = VOS_FALSE;
9915 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309916 v_BOOL_t sapEnable11AC =
9917 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Kapil Gupta137ef892016-12-13 19:38:00 +05309918 u_int16_t prev_rsn_length = 0;
9919
Jeff Johnson295189b2012-06-20 16:38:30 -07009920 ENTER();
9921
Nitesh Shah9b066282017-06-06 18:05:52 +05309922 wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309923 iniConfig = pHddCtx->cfg_ini;
9924
Jeff Johnson295189b2012-06-20 16:38:30 -07009925 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
9926
9927 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9928
9929 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9930
9931 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9932
9933 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
9934
9935 //channel is already set in the set_channel Call back
9936 //pConfig->channel = pCommitConfig->channel;
9937
9938 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309939 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07009940 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
9941
9942 pConfig->dtim_period = pBeacon->dtim_period;
9943
Arif Hussain6d2a3322013-11-17 19:50:10 -08009944 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07009945 pConfig->dtim_period);
9946
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08009947 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07009948 {
9949 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07009950 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05309951 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
9952 {
9953 tANI_BOOLEAN restartNeeded;
9954 pConfig->ieee80211d = 1;
9955 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
9956 sme_setRegInfo(hHal, pConfig->countryCode);
9957 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
9958 }
9959 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009960 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07009961 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07009962 pConfig->ieee80211d = 1;
9963 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
9964 sme_setRegInfo(hHal, pConfig->countryCode);
9965 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07009966 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07009967 else
9968 {
9969 pConfig->ieee80211d = 0;
9970 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309971 /*
9972 * If auto channel is configured i.e. channel is 0,
9973 * so skip channel validation.
9974 */
9975 if( AUTO_CHANNEL_SELECT != pConfig->channel )
9976 {
9977 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
9978 {
9979 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009980 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309981 return -EINVAL;
9982 }
9983 }
9984 else
9985 {
9986 if(1 != pHddCtx->is_dynamic_channel_range_set)
9987 {
9988 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
9989 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
9990 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
9991 }
9992 pHddCtx->is_dynamic_channel_range_set = 0;
9993 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009994 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07009995 else
Jeff Johnson295189b2012-06-20 16:38:30 -07009996 {
9997 pConfig->ieee80211d = 0;
9998 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309999
10000#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10001 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
10002 pConfig->authType = eSAP_OPEN_SYSTEM;
10003 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
10004 pConfig->authType = eSAP_SHARED_KEY;
10005 else
10006 pConfig->authType = eSAP_AUTO_SWITCH;
10007#else
10008 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
10009 pConfig->authType = eSAP_OPEN_SYSTEM;
10010 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
10011 pConfig->authType = eSAP_SHARED_KEY;
10012 else
10013 pConfig->authType = eSAP_AUTO_SWITCH;
10014#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010015
10016 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010017
10018 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -070010019 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
Agrawal Ashisha8e8a722016-10-18 19:07:45 +053010020#ifdef SAP_AUTH_OFFLOAD
10021 /* In case of sap offload, hostapd.conf is configuted with open mode and
10022 * security is configured from ini file. Due to open mode in hostapd.conf
10023 * privacy bit is set to false which will result in not sending,
10024 * data packets as encrypted.
10025 * If enable_sap_auth_offload is enabled in ini and
10026 * sap_auth_offload_sec_type is type of WPA2-PSK,
10027 * driver will set privacy bit to 1.
10028 */
10029 if (pHddCtx->cfg_ini->enable_sap_auth_offload &&
10030 pHddCtx->cfg_ini->sap_auth_offload_sec_type)
10031 pConfig->privacy = VOS_TRUE;
10032#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010033
10034 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
10035
10036 /*Set wps station to configured*/
10037 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
10038
10039 if(pIe)
10040 {
10041 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
10042 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010043 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -070010044 return -EINVAL;
10045 }
10046 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
10047 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -070010048 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -070010049 /* Check 15 bit of WPS IE as it contain information for wps state
10050 * WPS state
10051 */
10052 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
10053 {
10054 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
10055 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
10056 {
10057 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
10058 }
10059 }
10060 }
10061 else
10062 {
10063 pConfig->wps_state = SAP_WPS_DISABLED;
10064 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010065 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -070010066
c_hpothufe599e92014-06-16 11:38:55 +053010067 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
10068 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
10069 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
10070 eCSR_ENCRYPT_TYPE_NONE;
10071
Jeff Johnson295189b2012-06-20 16:38:30 -070010072 pConfig->RSNWPAReqIELength = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +053010073 memset(&pConfig->RSNWPAReqIE[0], 0, sizeof(pConfig->RSNWPAReqIE));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010074 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070010075 WLAN_EID_RSN);
10076 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010077 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010078 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053010079 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
10080 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
10081 pConfig->RSNWPAReqIELength);
10082 else
10083 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
10084 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010085 /* The actual processing may eventually be more extensive than
10086 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -070010087 * by the app.
10088 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010089 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070010090 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
10091 &RSNEncryptType,
10092 &mcRSNEncryptType,
10093 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080010094 &MFPCapable,
10095 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053010096 pConfig->RSNWPAReqIE[1]+2,
10097 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010098
10099 if( VOS_STATUS_SUCCESS == status )
10100 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010101 /* Now copy over all the security attributes you have
10102 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070010103 * */
10104 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
10105 pConfig->mcRSNEncryptType = mcRSNEncryptType;
10106 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
10107 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010108 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080010109 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070010110 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
10111 }
10112 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010113
Jeff Johnson295189b2012-06-20 16:38:30 -070010114 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
10115 pBeacon->tail, pBeacon->tail_len);
10116
10117 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
10118 {
Kapil Gupta137ef892016-12-13 19:38:00 +053010119 if (pConfig->RSNWPAReqIE[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070010120 {
10121 /*Mixed mode WPA/WPA2*/
Kapil Gupta137ef892016-12-13 19:38:00 +053010122 prev_rsn_length = pConfig->RSNWPAReqIELength;
Jeff Johnson295189b2012-06-20 16:38:30 -070010123 pConfig->RSNWPAReqIELength += pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053010124 if (pConfig->RSNWPAReqIELength <=
10125 (sizeof(pConfig->RSNWPAReqIE) - prev_rsn_length))
10126 memcpy(&pConfig->RSNWPAReqIE[0] + prev_rsn_length, pIe,
10127 pIe[1] + 2);
10128 else
10129 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
10130 pConfig->RSNWPAReqIELength);
10131
Jeff Johnson295189b2012-06-20 16:38:30 -070010132 }
10133 else
10134 {
10135 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053010136 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
10137 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
10138 pConfig->RSNWPAReqIELength);
10139 else
10140 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
10141 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010142 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070010143 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
10144 &RSNEncryptType,
10145 &mcRSNEncryptType,
10146 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080010147 &MFPCapable,
10148 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053010149 pConfig->RSNWPAReqIE[1]+2,
10150 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010151
10152 if( VOS_STATUS_SUCCESS == status )
10153 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010154 /* Now copy over all the security attributes you have
10155 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070010156 * */
10157 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
10158 pConfig->mcRSNEncryptType = mcRSNEncryptType;
10159 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
10160 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010161 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080010162 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070010163 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
10164 }
10165 }
10166 }
10167
Kapil Gupta137ef892016-12-13 19:38:00 +053010168 if (pConfig->RSNWPAReqIELength > sizeof(pConfig->RSNWPAReqIE)) {
Jeff Johnson4416a782013-03-25 14:17:50 -070010169 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
10170 return -EINVAL;
10171 }
10172
Jeff Johnson295189b2012-06-20 16:38:30 -070010173 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
10174
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010175#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010176 if (params->ssid != NULL)
10177 {
10178 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
10179 pConfig->SSIDinfo.ssid.length = params->ssid_len;
10180 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
10181 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
10182 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010183#else
10184 if (ssid != NULL)
10185 {
10186 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
10187 pConfig->SSIDinfo.ssid.length = ssid_len;
10188 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
10189 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
10190 }
10191#endif
10192
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010193 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -070010194 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010195
Jeff Johnson295189b2012-06-20 16:38:30 -070010196 /* default value */
10197 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
10198 pConfig->num_accept_mac = 0;
10199 pConfig->num_deny_mac = 0;
10200
10201 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
10202 pBeacon->tail, pBeacon->tail_len);
10203
10204 /* pIe for black list is following form:
10205 type : 1 byte
10206 length : 1 byte
10207 OUI : 4 bytes
10208 acl type : 1 byte
10209 no of mac addr in black list: 1 byte
10210 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010211 */
10212 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010213 {
10214 pConfig->SapMacaddr_acl = pIe[6];
10215 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080010216 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010217 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053010218 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
10219 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010220 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
10221 for (i = 0; i < pConfig->num_deny_mac; i++)
10222 {
10223 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
10224 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010225 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010226 }
10227 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
10228 pBeacon->tail, pBeacon->tail_len);
10229
10230 /* pIe for white list is following form:
10231 type : 1 byte
10232 length : 1 byte
10233 OUI : 4 bytes
10234 acl type : 1 byte
10235 no of mac addr in white list: 1 byte
10236 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010237 */
10238 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010239 {
10240 pConfig->SapMacaddr_acl = pIe[6];
10241 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080010242 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010243 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053010244 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
10245 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010246 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
10247 for (i = 0; i < pConfig->num_accept_mac; i++)
10248 {
10249 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
10250 acl_entry++;
10251 }
10252 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053010253
Jeff Johnson295189b2012-06-20 16:38:30 -070010254 wlan_hdd_set_sapHwmode(pHostapdAdapter);
10255
Jeff Johnsone7245742012-09-05 17:12:55 -070010256#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080010257 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +053010258 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
10259 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +053010260 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
10261 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080010262 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
10263 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +053010264 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
10265 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -070010266 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053010267 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -070010268 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +053010269 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070010270
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010271 /* If ACS disable and selected channel <= 14
10272 * OR
10273 * ACS enabled and ACS operating band is choosen as 2.4
10274 * AND
10275 * VHT in 2.4G Disabled
10276 * THEN
10277 * Fallback to 11N mode
10278 */
10279 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
10280 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +053010281 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010282 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -070010283 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053010284 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
10285 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070010286 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
10287 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010288 }
10289#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010290
Jeff Johnson295189b2012-06-20 16:38:30 -070010291 // ht_capab is not what the name conveys,this is used for protection bitmap
10292 pConfig->ht_capab =
10293 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
10294
Kapil Gupta137ef892016-12-13 19:38:00 +053010295 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -070010296 {
10297 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
10298 return -EINVAL;
10299 }
10300
10301 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010302 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -070010303 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
10304 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010305 pConfig->obssProtEnabled =
10306 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -070010307
Chet Lanctot8cecea22014-02-11 19:09:36 -080010308#ifdef WLAN_FEATURE_11W
10309 pConfig->mfpCapable = MFPCapable;
10310 pConfig->mfpRequired = MFPRequired;
10311 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
10312 pConfig->mfpCapable, pConfig->mfpRequired);
10313#endif
10314
Arif Hussain6d2a3322013-11-17 19:50:10 -080010315 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -070010316 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -080010317 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
10318 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
10319 (int)pConfig->channel);
10320 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
10321 pConfig->SapHw_mode, pConfig->privacy,
10322 pConfig->authType);
10323 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
10324 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
10325 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
10326 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -070010327
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010328 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -070010329 {
10330 //Bss already started. just return.
10331 //TODO Probably it should update some beacon params.
10332 hddLog( LOGE, "Bss Already started...Ignore the request");
10333 EXIT();
10334 return 0;
10335 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010336
Agarwal Ashish51325b52014-06-16 16:50:49 +053010337 if (vos_max_concurrent_connections_reached()) {
10338 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10339 return -EINVAL;
10340 }
10341
Jeff Johnson295189b2012-06-20 16:38:30 -070010342 pConfig->persona = pHostapdAdapter->device_mode;
10343
Peng Xu2446a892014-09-05 17:21:18 +053010344 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
10345 if ( NULL != psmeConfig)
10346 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053010347 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +053010348 sme_GetConfigParam(hHal, psmeConfig);
10349 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053010350#ifdef WLAN_FEATURE_AP_HT40_24G
10351 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
10352 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
10353 && pHddCtx->cfg_ini->apHT40_24GEnabled)
10354 {
10355 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
10356 sme_UpdateConfig (hHal, psmeConfig);
10357 }
10358#endif
Peng Xu2446a892014-09-05 17:21:18 +053010359 vos_mem_free(psmeConfig);
10360 }
Peng Xuafc34e32014-09-25 13:23:55 +053010361 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +053010362
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010363 set_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
10364
Jeff Johnson295189b2012-06-20 16:38:30 -070010365 pSapEventCallback = hdd_hostapd_SAPEventCB;
10366 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
10367 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
10368 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010369 hddLog(LOGE,FL("SAP Start Bss fail"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010370 ret = -EINVAL;
10371 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070010372 }
10373
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010374 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -070010375 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
10376
10377 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010378
Jeff Johnson295189b2012-06-20 16:38:30 -070010379 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010380 {
10381 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010382 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -070010383 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070010384 VOS_ASSERT(0);
10385 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010386
Jeff Johnson295189b2012-06-20 16:38:30 -070010387 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053010388 if (WLANSAP_get_sessionId(pVosContext, &pHostapdAdapter->sessionId) !=
10389 VOS_STATUS_SUCCESS)
10390 {
10391 hddLog(LOGE,FL("Fail to get Softap sessionID"));
10392 VOS_ASSERT(0);
10393 }
Kaushik, Sushantf6070802014-10-15 15:09:23 +053010394 /* Initialize WMM configuation */
10395 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010396 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010397
Anurag Chouhan83026002016-12-13 22:46:21 +053010398#ifdef DHCP_SERVER_OFFLOAD
10399 /* set dhcp server offload */
10400 if (iniConfig->enable_dhcp_srv_offload &&
10401 sme_IsFeatureSupportedByFW(SAP_OFFLOADS)) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010402 vos_event_reset(&pHostapdAdapter->dhcp_status.vos_event);
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010403 status = wlan_hdd_set_dhcp_server_offload(pHostapdAdapter, false);
Anurag Chouhan83026002016-12-13 22:46:21 +053010404 if (!VOS_IS_STATUS_SUCCESS(status))
10405 {
10406 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10407 ("HDD DHCP Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010408 vos_event_reset(&pHostapdState->vosEvent);
10409 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
10410 status = vos_wait_single_event(&pHostapdState->vosEvent,
10411 10000);
10412 if (!VOS_IS_STATUS_SUCCESS(status)) {
10413 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010414 ret = -EINVAL;
10415 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010416 }
10417 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010418 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010419 status = vos_wait_single_event(&pHostapdAdapter->dhcp_status.vos_event, 2000);
10420 if (!VOS_IS_STATUS_SUCCESS(status) || pHostapdAdapter->dhcp_status.dhcp_offload_status)
10421 {
10422 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10423 ("ERROR: DHCP HDD vos wait for single_event failed!! %d"),
10424 pHostapdAdapter->dhcp_status.dhcp_offload_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010425 vos_event_reset(&pHostapdState->vosEvent);
10426 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
10427 status = vos_wait_single_event(&pHostapdState->vosEvent,
10428 10000);
10429 if (!VOS_IS_STATUS_SUCCESS(status)) {
10430 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010431 ret = -EINVAL;
10432 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010433 }
10434 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010435 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010436#ifdef MDNS_OFFLOAD
10437 if (iniConfig->enable_mdns_offload) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010438 vos_event_reset(&pHostapdAdapter->mdns_status.vos_event);
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010439 status = wlan_hdd_set_mdns_offload(pHostapdAdapter);
10440 if (VOS_IS_STATUS_SUCCESS(status))
10441 {
10442 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10443 ("HDD MDNS Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010444 vos_event_reset(&pHostapdState->vosEvent);
10445 if (VOS_STATUS_SUCCESS ==
10446 WLANSAP_StopBss(pHddCtx->pvosContext)) {
10447 status = vos_wait_single_event(&pHostapdState->vosEvent,
10448 10000);
10449 if (!VOS_IS_STATUS_SUCCESS(status)) {
10450 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010451 ret = -EINVAL;
10452 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010453 }
10454 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010455 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010456 status = vos_wait_single_event(&pHostapdAdapter->
10457 mdns_status.vos_event, 2000);
10458 if (!VOS_IS_STATUS_SUCCESS(status) ||
10459 pHostapdAdapter->mdns_status.mdns_enable_status ||
10460 pHostapdAdapter->mdns_status.mdns_fqdn_status ||
10461 pHostapdAdapter->mdns_status.mdns_resp_status)
10462 {
10463 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10464 ("MDNS HDD vos wait for single_event failed!! enable %d fqdn %d resp %d"),
10465 pHostapdAdapter->mdns_status.mdns_enable_status,
10466 pHostapdAdapter->mdns_status.mdns_fqdn_status,
10467 pHostapdAdapter->mdns_status.mdns_resp_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010468 vos_event_reset(&pHostapdState->vosEvent);
10469 if (VOS_STATUS_SUCCESS ==
10470 WLANSAP_StopBss(pHddCtx->pvosContext)) {
10471 status = vos_wait_single_event(&pHostapdState->vosEvent,
10472 10000);
10473 if (!VOS_IS_STATUS_SUCCESS(status)) {
10474 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010475 ret = -EINVAL;
10476 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010477 }
10478 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010479 }
10480 }
10481#endif /* MDNS_OFFLOAD */
10482 } else {
10483 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10484 ("DHCP Disabled ini %d, FW %d"),
10485 iniConfig->enable_dhcp_srv_offload,
10486 sme_IsFeatureSupportedByFW(SAP_OFFLOADS));
Anurag Chouhan83026002016-12-13 22:46:21 +053010487 }
10488#endif /* DHCP_SERVER_OFFLOAD */
10489
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010490#ifdef WLAN_FEATURE_P2P_DEBUG
10491 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
10492 {
10493 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
10494 {
10495 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
10496 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -080010497 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010498 }
10499 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
10500 {
10501 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
10502 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -080010503 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010504 }
10505 }
10506#endif
Ashish Kumar Dhanotiya42aa5152017-01-03 20:25:57 +053010507 /* Check and restart SAP if it is on Unsafe channel */
10508 hdd_check_for_unsafe_ch(pHostapdAdapter, pHddCtx);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010509
Jeff Johnson295189b2012-06-20 16:38:30 -070010510 pHostapdState->bCommit = TRUE;
10511 EXIT();
10512
10513 return 0;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010514error:
10515 clear_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
10516 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010517}
10518
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010519#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010520static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010521 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070010522 struct beacon_parameters *params)
10523{
10524 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010525 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010526 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010527
10528 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010529
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010530 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10531 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
10532 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010533 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
10534 hdd_device_modetoString(pAdapter->device_mode),
10535 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010536
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010537 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10538 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010539 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010540 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010541 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010542 }
10543
Agarwal Ashish51325b52014-06-16 16:50:49 +053010544 if (vos_max_concurrent_connections_reached()) {
10545 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10546 return -EINVAL;
10547 }
10548
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010549 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010550 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070010551 )
10552 {
10553 beacon_data_t *old,*new;
10554
10555 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010556
Jeff Johnson295189b2012-06-20 16:38:30 -070010557 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010558 {
10559 hddLog(VOS_TRACE_LEVEL_WARN,
10560 FL("already beacon info added to session(%d)"),
10561 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070010562 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010563 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010564
10565 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
10566
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010567 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -070010568 {
10569 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010570 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010571 return -EINVAL;
10572 }
10573
10574 pAdapter->sessionCtx.ap.beacon = new;
10575
10576 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
10577 }
10578
10579 EXIT();
10580 return status;
10581}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010582
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010583static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
10584 struct net_device *dev,
10585 struct beacon_parameters *params)
10586{
10587 int ret;
10588
10589 vos_ssr_protect(__func__);
10590 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
10591 vos_ssr_unprotect(__func__);
10592
10593 return ret;
10594}
10595
10596static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010597 struct net_device *dev,
10598 struct beacon_parameters *params)
10599{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010600 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010601 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10602 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010603 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010604
10605 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010606
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010607 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10608 TRACE_CODE_HDD_CFG80211_SET_BEACON,
10609 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
10610 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10611 __func__, hdd_device_modetoString(pAdapter->device_mode),
10612 pAdapter->device_mode);
10613
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010614 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10615 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010616 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010617 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010618 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010619 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010620
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010621 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010622 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010623 )
Jeff Johnson295189b2012-06-20 16:38:30 -070010624 {
10625 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010626
Jeff Johnson295189b2012-06-20 16:38:30 -070010627 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010628
Jeff Johnson295189b2012-06-20 16:38:30 -070010629 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010630 {
10631 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10632 FL("session(%d) old and new heads points to NULL"),
10633 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070010634 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010635 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010636
10637 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
10638
10639 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010640 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010641 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010642 return -EINVAL;
10643 }
10644
10645 pAdapter->sessionCtx.ap.beacon = new;
10646
10647 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
10648 }
10649
10650 EXIT();
10651 return status;
10652}
10653
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010654static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
10655 struct net_device *dev,
10656 struct beacon_parameters *params)
10657{
10658 int ret;
10659
10660 vos_ssr_protect(__func__);
10661 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
10662 vos_ssr_unprotect(__func__);
10663
10664 return ret;
10665}
10666
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010667#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10668
10669#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010670static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010671 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010672#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010673static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010674 struct net_device *dev)
10675#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010676{
10677 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -070010678 hdd_context_t *pHddCtx = NULL;
10679 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010680 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010681 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010682
10683 ENTER();
10684
10685 if (NULL == pAdapter)
10686 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010687 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010688 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010689 return -ENODEV;
10690 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010691
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010692 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10693 TRACE_CODE_HDD_CFG80211_STOP_AP,
10694 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010695 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10696 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010697 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010698 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010699 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -070010700 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010701
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010702 pScanInfo = &pHddCtx->scan_info;
10703
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010704 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10705 __func__, hdd_device_modetoString(pAdapter->device_mode),
10706 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010707
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010708 ret = wlan_hdd_scan_abort(pAdapter);
10709
Girish Gowli4bf7a632014-06-12 13:42:11 +053010710 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -070010711 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010712 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10713 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010714
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010715 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -070010716 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010717 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10718 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -080010719
Jeff Johnsone7245742012-09-05 17:12:55 -070010720 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010721 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -070010722 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010723 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070010724 }
10725
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010726 /* Delete all associated STAs before stopping AP/P2P GO */
10727 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +053010728 hdd_hostapd_stop(dev);
10729
Jeff Johnson295189b2012-06-20 16:38:30 -070010730 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010731 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070010732 )
10733 {
10734 beacon_data_t *old;
10735
10736 old = pAdapter->sessionCtx.ap.beacon;
10737
10738 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010739 {
10740 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10741 FL("session(%d) beacon data points to NULL"),
10742 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070010743 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010744 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010745
Jeff Johnson295189b2012-06-20 16:38:30 -070010746 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010747
10748 mutex_lock(&pHddCtx->sap_lock);
10749 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
10750 {
Jeff Johnson4416a782013-03-25 14:17:50 -070010751 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -070010752 {
10753 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
10754
10755 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
10756
10757 if (!VOS_IS_STATUS_SUCCESS(status))
10758 {
10759 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010760 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -070010761 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010762 }
10763 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010764 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010765 /* BSS stopped, clear the active sessions for this device mode */
10766 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010767 }
10768 mutex_unlock(&pHddCtx->sap_lock);
10769
10770 if(status != VOS_STATUS_SUCCESS)
10771 {
10772 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010773 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010774 return -EINVAL;
10775 }
10776
Jeff Johnson4416a782013-03-25 14:17:50 -070010777 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070010778 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
10779 ==eHAL_STATUS_FAILURE)
10780 {
10781 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010782 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010783 }
10784
Jeff Johnson4416a782013-03-25 14:17:50 -070010785 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070010786 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
10787 eANI_BOOLEAN_FALSE) )
10788 {
10789 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010790 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010791 }
10792
10793 // Reset WNI_CFG_PROBE_RSP Flags
10794 wlan_hdd_reset_prob_rspies(pAdapter);
10795
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010796 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
10797
Jeff Johnson295189b2012-06-20 16:38:30 -070010798 pAdapter->sessionCtx.ap.beacon = NULL;
10799 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010800#ifdef WLAN_FEATURE_P2P_DEBUG
10801 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
10802 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
10803 {
10804 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
10805 "GO got removed");
10806 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
10807 }
10808#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010809 }
10810 EXIT();
10811 return status;
10812}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010813
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010814#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10815static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
10816 struct net_device *dev)
10817{
10818 int ret;
10819
10820 vos_ssr_protect(__func__);
10821 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
10822 vos_ssr_unprotect(__func__);
10823
10824 return ret;
10825}
10826#else
10827static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
10828 struct net_device *dev)
10829{
10830 int ret;
10831
10832 vos_ssr_protect(__func__);
10833 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
10834 vos_ssr_unprotect(__func__);
10835
10836 return ret;
10837}
10838#endif
10839
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010840#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
10841
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010842static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010843 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010844 struct cfg80211_ap_settings *params)
10845{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010846 hdd_adapter_t *pAdapter;
10847 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010848 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010849
10850 ENTER();
10851
Girish Gowlib143d7a2015-02-18 19:39:55 +053010852 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010853 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010854 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +053010855 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010856 return -ENODEV;
10857 }
10858
10859 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
10860 if (NULL == pAdapter)
10861 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010862 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010863 "%s: HDD adapter is Null", __func__);
10864 return -ENODEV;
10865 }
10866
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010867 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10868 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
10869 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010870 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
10871 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010872 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010873 "%s: HDD adapter magic is invalid", __func__);
10874 return -ENODEV;
10875 }
10876
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010877 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
10878
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010879 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010880 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010881 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010882 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010883 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010884 }
10885
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010886 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
10887 __func__, hdd_device_modetoString(pAdapter->device_mode),
10888 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010889
10890 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010891 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010892 )
10893 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010894 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010895
10896 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010897
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010898 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010899 {
10900 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
10901 FL("already beacon info added to session(%d)"),
10902 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010903 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010904 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010905
Girish Gowlib143d7a2015-02-18 19:39:55 +053010906#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10907 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
10908 &new,
10909 &params->beacon);
10910#else
10911 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
10912 &new,
10913 &params->beacon,
10914 params->dtim_period);
10915#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010916
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010917 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010918 {
10919 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010920 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010921 return -EINVAL;
10922 }
10923 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -080010924#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -070010925 wlan_hdd_cfg80211_set_channel(wiphy, dev,
10926#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
10927 params->channel, params->channel_type);
10928#else
10929 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
10930#endif
Viral Modi3a32cc52013-02-08 11:14:52 -080010931#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010932 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010933 params->ssid_len, params->hidden_ssid,
10934 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010935 }
10936
10937 EXIT();
10938 return status;
10939}
10940
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010941static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
10942 struct net_device *dev,
10943 struct cfg80211_ap_settings *params)
10944{
10945 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010946
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010947 vos_ssr_protect(__func__);
10948 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
10949 vos_ssr_unprotect(__func__);
10950
10951 return ret;
10952}
10953
10954static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010955 struct net_device *dev,
10956 struct cfg80211_beacon_data *params)
10957{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010958 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010959 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010960 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010961
10962 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010963
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010964 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10965 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
10966 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -080010967 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010968 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010969
10970 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10971 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010972 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010973 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010974 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010975 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010976
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010977 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010978 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010979 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010980 {
10981 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010982
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010983 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010984
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010985 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010986 {
10987 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10988 FL("session(%d) beacon data points to NULL"),
10989 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010990 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010991 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010992
10993 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
10994
10995 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010996 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010997 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010998 return -EINVAL;
10999 }
11000
11001 pAdapter->sessionCtx.ap.beacon = new;
11002
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053011003 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
11004 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011005 }
11006
11007 EXIT();
11008 return status;
11009}
11010
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011011static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
11012 struct net_device *dev,
11013 struct cfg80211_beacon_data *params)
11014{
11015 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011016
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011017 vos_ssr_protect(__func__);
11018 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
11019 vos_ssr_unprotect(__func__);
11020
11021 return ret;
11022}
11023
11024#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011025
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011026static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011027 struct net_device *dev,
11028 struct bss_parameters *params)
11029{
11030 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011031 hdd_context_t *pHddCtx;
11032 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011033
11034 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011035
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011036 if (NULL == pAdapter)
11037 {
11038 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11039 "%s: HDD adapter is Null", __func__);
11040 return -ENODEV;
11041 }
11042 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011043 ret = wlan_hdd_validate_context(pHddCtx);
11044 if (0 != ret)
11045 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011046 return ret;
11047 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011048 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11049 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
11050 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011051 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11052 __func__, hdd_device_modetoString(pAdapter->device_mode),
11053 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011054
11055 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011056 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011057 )
Jeff Johnson295189b2012-06-20 16:38:30 -070011058 {
11059 /* ap_isolate == -1 means that in change bss, upper layer doesn't
11060 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011061 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -070011062 {
11063 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011064 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011065 }
11066
11067 EXIT();
11068 return 0;
11069}
11070
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011071static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
11072 struct net_device *dev,
11073 struct bss_parameters *params)
11074{
11075 int ret;
11076
11077 vos_ssr_protect(__func__);
11078 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
11079 vos_ssr_unprotect(__func__);
11080
11081 return ret;
11082}
Kiet Lam10841362013-11-01 11:36:50 +053011083/* FUNCTION: wlan_hdd_change_country_code_cd
11084* to wait for contry code completion
11085*/
11086void* wlan_hdd_change_country_code_cb(void *pAdapter)
11087{
11088 hdd_adapter_t *call_back_pAdapter = pAdapter;
11089 complete(&call_back_pAdapter->change_country_code);
11090 return NULL;
11091}
11092
Jeff Johnson295189b2012-06-20 16:38:30 -070011093/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053011094 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -070011095 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
11096 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053011097int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011098 struct net_device *ndev,
11099 enum nl80211_iftype type,
11100 u32 *flags,
11101 struct vif_params *params
11102 )
11103{
11104 struct wireless_dev *wdev;
11105 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011106 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -070011107 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011108 tCsrRoamProfile *pRoamProfile = NULL;
11109 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011110 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011111 eMib_dot11DesiredBssType connectedBssType;
11112 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011113 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011114
11115 ENTER();
11116
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011117 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011118 {
11119 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11120 "%s: Adapter context is null", __func__);
11121 return VOS_STATUS_E_FAILURE;
11122 }
11123
11124 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11125 if (!pHddCtx)
11126 {
11127 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11128 "%s: HDD context is null", __func__);
11129 return VOS_STATUS_E_FAILURE;
11130 }
11131
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011132 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11133 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
11134 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011135 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011136 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011137 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011138 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011139 }
11140
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011141 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11142 __func__, hdd_device_modetoString(pAdapter->device_mode),
11143 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011144
Agarwal Ashish51325b52014-06-16 16:50:49 +053011145 if (vos_max_concurrent_connections_reached()) {
11146 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11147 return -EINVAL;
11148 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011149 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070011150 wdev = ndev->ieee80211_ptr;
11151
11152#ifdef WLAN_BTAMP_FEATURE
11153 if((NL80211_IFTYPE_P2P_CLIENT == type)||
11154 (NL80211_IFTYPE_ADHOC == type)||
11155 (NL80211_IFTYPE_AP == type)||
11156 (NL80211_IFTYPE_P2P_GO == type))
11157 {
11158 pHddCtx->isAmpAllowed = VOS_FALSE;
11159 // stop AMP traffic
11160 status = WLANBAP_StopAmp();
11161 if(VOS_STATUS_SUCCESS != status )
11162 {
11163 pHddCtx->isAmpAllowed = VOS_TRUE;
11164 hddLog(VOS_TRACE_LEVEL_FATAL,
11165 "%s: Failed to stop AMP", __func__);
11166 return -EINVAL;
11167 }
11168 }
11169#endif //WLAN_BTAMP_FEATURE
11170 /* Reset the current device mode bit mask*/
11171 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
11172
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +053011173 if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
11174 ((type == NL80211_IFTYPE_P2P_CLIENT) ||
11175 (type == NL80211_IFTYPE_P2P_GO)))
11176 {
11177 /* Notify Mode change in case of concurrency.
11178 * Below function invokes TDLS teardown Functionality Since TDLS is
11179 * not Supported in case of concurrency i.e Once P2P session
11180 * is detected disable offchannel and teardown TDLS links
11181 */
11182 hddLog(LOG1,
11183 FL("Device mode = %d Interface type = %d"),
11184 pAdapter->device_mode, type);
11185 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
11186 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +053011187
Jeff Johnson295189b2012-06-20 16:38:30 -070011188 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070011189 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -070011190 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -070011191 )
11192 {
11193 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011194 if (!pWextState)
11195 {
11196 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11197 "%s: pWextState is null", __func__);
11198 return VOS_STATUS_E_FAILURE;
11199 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011200 pRoamProfile = &pWextState->roamProfile;
11201 LastBSSType = pRoamProfile->BSSType;
11202
11203 switch (type)
11204 {
11205 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070011206 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070011207 hddLog(VOS_TRACE_LEVEL_INFO,
11208 "%s: setting interface Type to INFRASTRUCTURE", __func__);
11209 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -070011210#ifdef WLAN_FEATURE_11AC
11211 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
11212 {
11213 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
11214 }
11215#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011216 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -070011217 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011218 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080011219 //Check for sub-string p2p to confirm its a p2p interface
11220 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011221 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +053011222#ifdef FEATURE_WLAN_TDLS
11223 mutex_lock(&pHddCtx->tdls_lock);
11224 wlan_hdd_tdls_exit(pAdapter, TRUE);
11225 mutex_unlock(&pHddCtx->tdls_lock);
11226#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -080011227 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
11228 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
11229 }
11230 else
11231 {
11232 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070011233 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080011234 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011235 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +053011236
Jeff Johnson295189b2012-06-20 16:38:30 -070011237 case NL80211_IFTYPE_ADHOC:
11238 hddLog(VOS_TRACE_LEVEL_INFO,
11239 "%s: setting interface Type to ADHOC", __func__);
11240 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
11241 pRoamProfile->phyMode =
11242 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -070011243 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011244 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +053011245 hdd_set_ibss_ops( pAdapter );
11246 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +053011247
11248 status = hdd_sta_id_hash_attach(pAdapter);
11249 if (VOS_STATUS_SUCCESS != status) {
11250 hddLog(VOS_TRACE_LEVEL_ERROR,
11251 FL("Failed to initialize hash for IBSS"));
11252 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011253 break;
11254
11255 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070011256 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070011257 {
11258 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
11259 "%s: setting interface Type to %s", __func__,
11260 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
11261
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080011262 //Cancel any remain on channel for GO mode
11263 if (NL80211_IFTYPE_P2P_GO == type)
11264 {
11265 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
11266 }
Mohit Khanna0f232092012-09-11 14:46:08 -070011267 if (NL80211_IFTYPE_AP == type)
11268 {
11269 /* As Loading WLAN Driver one interface being created for p2p device
11270 * address. This will take one HW STA and the max number of clients
11271 * that can connect to softAP will be reduced by one. so while changing
11272 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
11273 * interface as it is not required in SoftAP mode.
11274 */
11275
11276 // Get P2P Adapter
11277 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
11278
11279 if (pP2pAdapter)
11280 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053011281 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +053011282 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -070011283 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
11284 }
11285 }
Swaroop Goltia2e32212014-04-09 23:37:33 +053011286 //Disable IMPS & BMPS for SAP/GO
11287 if(VOS_STATUS_E_FAILURE ==
11288 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
11289 {
11290 //Fail to Exit BMPS
11291 VOS_ASSERT(0);
11292 }
Deepthi Gowri500fc472014-08-11 19:53:10 +053011293
11294 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
11295
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011296#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -070011297
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011298 /* A Mutex Lock is introduced while changing the mode to
11299 * protect the concurrent access for the Adapters by TDLS
11300 * module.
11301 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011302 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011303#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011304 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +053011305 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011306 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -070011307 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
11308 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011309#ifdef FEATURE_WLAN_TDLS
11310 mutex_unlock(&pHddCtx->tdls_lock);
11311#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070011312 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
11313 (pConfig->apRandomBssidEnabled))
11314 {
11315 /* To meet Android requirements create a randomized
11316 MAC address of the form 02:1A:11:Fx:xx:xx */
11317 get_random_bytes(&ndev->dev_addr[3], 3);
11318 ndev->dev_addr[0] = 0x02;
11319 ndev->dev_addr[1] = 0x1A;
11320 ndev->dev_addr[2] = 0x11;
11321 ndev->dev_addr[3] |= 0xF0;
11322 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
11323 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -080011324 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
11325 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070011326 }
11327
Jeff Johnson295189b2012-06-20 16:38:30 -070011328 hdd_set_ap_ops( pAdapter->dev );
11329
Kiet Lam10841362013-11-01 11:36:50 +053011330 /* This is for only SAP mode where users can
11331 * control country through ini.
11332 * P2P GO follows station country code
11333 * acquired during the STA scanning. */
11334 if((NL80211_IFTYPE_AP == type) &&
11335 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
11336 {
11337 int status = 0;
11338 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
11339 "%s: setting country code from INI ", __func__);
11340 init_completion(&pAdapter->change_country_code);
11341 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
11342 (void *)(tSmeChangeCountryCallback)
11343 wlan_hdd_change_country_code_cb,
11344 pConfig->apCntryCode, pAdapter,
11345 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053011346 eSIR_FALSE,
11347 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +053011348 if (eHAL_STATUS_SUCCESS == status)
11349 {
11350 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011351 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +053011352 &pAdapter->change_country_code,
11353 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011354 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +053011355 {
11356 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011357 FL("SME Timed out while setting country code %ld"),
11358 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -080011359
11360 if (pHddCtx->isLogpInProgress)
11361 {
11362 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11363 "%s: LOGP in Progress. Ignore!!!", __func__);
11364 return -EAGAIN;
11365 }
Kiet Lam10841362013-11-01 11:36:50 +053011366 }
11367 }
11368 else
11369 {
11370 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011371 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +053011372 return -EINVAL;
11373 }
11374 }
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +053011375 status = hdd_init_ap_mode(pAdapter, false);
Jeff Johnson295189b2012-06-20 16:38:30 -070011376 if(status != VOS_STATUS_SUCCESS)
11377 {
11378 hddLog(VOS_TRACE_LEVEL_FATAL,
11379 "%s: Error initializing the ap mode", __func__);
11380 return -EINVAL;
11381 }
11382 hdd_set_conparam(1);
11383
Nirav Shah7e3c8132015-06-22 23:51:42 +053011384 status = hdd_sta_id_hash_attach(pAdapter);
11385 if (VOS_STATUS_SUCCESS != status)
11386 {
11387 hddLog(VOS_TRACE_LEVEL_ERROR,
11388 FL("Failed to initialize hash for AP"));
11389 return -EINVAL;
11390 }
11391
Jeff Johnson295189b2012-06-20 16:38:30 -070011392 /*interface type changed update in wiphy structure*/
11393 if(wdev)
11394 {
11395 wdev->iftype = type;
11396 pHddCtx->change_iface = type;
11397 }
11398 else
11399 {
11400 hddLog(VOS_TRACE_LEVEL_ERROR,
11401 "%s: ERROR !!!! Wireless dev is NULL", __func__);
11402 return -EINVAL;
11403 }
11404 goto done;
11405 }
11406
11407 default:
11408 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
11409 __func__);
11410 return -EOPNOTSUPP;
11411 }
11412 }
11413 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011414 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011415 )
11416 {
11417 switch(type)
11418 {
11419 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070011420 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070011421 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +053011422
11423 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011424#ifdef FEATURE_WLAN_TDLS
11425
11426 /* A Mutex Lock is introduced while changing the mode to
11427 * protect the concurrent access for the Adapters by TDLS
11428 * module.
11429 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011430 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011431#endif
c_hpothu002231a2015-02-05 14:58:51 +053011432 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011433 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080011434 //Check for sub-string p2p to confirm its a p2p interface
11435 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -080011436 {
11437 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
11438 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
11439 }
11440 else
11441 {
11442 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070011443 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080011444 }
Agrawal Ashishcfe83282016-09-29 13:03:45 +053011445
11446 /* set con_mode to STA only when no SAP concurrency mode */
11447 if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO)))
11448 hdd_set_conparam(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070011449 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070011450 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
11451 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011452#ifdef FEATURE_WLAN_TDLS
11453 mutex_unlock(&pHddCtx->tdls_lock);
11454#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +053011455 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -070011456 if( VOS_STATUS_SUCCESS != status )
11457 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -070011458 /* In case of JB, for P2P-GO, only change interface will be called,
11459 * This is the right place to enable back bmps_imps()
11460 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053011461 if (pHddCtx->hdd_wlan_suspended)
11462 {
11463 hdd_set_pwrparams(pHddCtx);
11464 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011465 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070011466 goto done;
11467 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070011468 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070011469 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070011470 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
11471 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -070011472 goto done;
11473 default:
11474 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
11475 __func__);
11476 return -EOPNOTSUPP;
11477
11478 }
11479
11480 }
11481 else
11482 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011483 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
11484 __func__, hdd_device_modetoString(pAdapter->device_mode),
11485 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011486 return -EOPNOTSUPP;
11487 }
11488
11489
11490 if(pRoamProfile)
11491 {
11492 if ( LastBSSType != pRoamProfile->BSSType )
11493 {
11494 /*interface type changed update in wiphy structure*/
11495 wdev->iftype = type;
11496
11497 /*the BSS mode changed, We need to issue disconnect
11498 if connected or in IBSS disconnect state*/
11499 if ( hdd_connGetConnectedBssType(
11500 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
11501 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
11502 {
11503 /*need to issue a disconnect to CSR.*/
11504 INIT_COMPLETION(pAdapter->disconnect_comp_var);
11505 if( eHAL_STATUS_SUCCESS ==
11506 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
11507 pAdapter->sessionId,
11508 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
11509 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011510 ret = wait_for_completion_interruptible_timeout(
11511 &pAdapter->disconnect_comp_var,
11512 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
11513 if (ret <= 0)
11514 {
11515 hddLog(VOS_TRACE_LEVEL_ERROR,
11516 FL("wait on disconnect_comp_var failed %ld"), ret);
11517 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011518 }
11519 }
11520 }
11521 }
11522
11523done:
11524 /*set bitmask based on updated value*/
11525 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -070011526
11527 /* Only STA mode support TM now
11528 * all other mode, TM feature should be disabled */
11529 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
11530 (~VOS_STA & pHddCtx->concurrency_mode) )
11531 {
11532 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
11533 }
11534
Jeff Johnson295189b2012-06-20 16:38:30 -070011535#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011536 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053011537 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -070011538 {
11539 //we are ok to do AMP
11540 pHddCtx->isAmpAllowed = VOS_TRUE;
11541 }
11542#endif //WLAN_BTAMP_FEATURE
11543 EXIT();
11544 return 0;
11545}
11546
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053011547/*
11548 * FUNCTION: wlan_hdd_cfg80211_change_iface
11549 * wrapper function to protect the actual implementation from SSR.
11550 */
11551int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
11552 struct net_device *ndev,
11553 enum nl80211_iftype type,
11554 u32 *flags,
11555 struct vif_params *params
11556 )
11557{
11558 int ret;
11559
11560 vos_ssr_protect(__func__);
11561 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
11562 vos_ssr_unprotect(__func__);
11563
11564 return ret;
11565}
11566
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011567#ifdef FEATURE_WLAN_TDLS
11568static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011569 struct net_device *dev,
11570#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
11571 const u8 *mac,
11572#else
11573 u8 *mac,
11574#endif
11575 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011576{
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011577 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011578 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011579 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011580 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053011581 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053011582 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011583
11584 ENTER();
11585
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053011586 if (!dev) {
11587 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
11588 return -EINVAL;
11589 }
11590
11591 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
11592 if (!pAdapter) {
11593 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
11594 return -EINVAL;
11595 }
11596
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053011597 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011598 {
11599 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11600 "Invalid arguments");
11601 return -EINVAL;
11602 }
Hoonki Lee27511902013-03-14 18:19:06 -070011603
11604 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
11605 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
11606 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011607 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070011608 "%s: TDLS mode is disabled OR not enabled in FW."
11609 MAC_ADDRESS_STR " Request declined.",
11610 __func__, MAC_ADDR_ARRAY(mac));
11611 return -ENOTSUPP;
11612 }
11613
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011614 if (pHddCtx->isLogpInProgress)
11615 {
11616 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11617 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053011618 wlan_hdd_tdls_set_link_status(pAdapter,
11619 mac,
11620 eTDLS_LINK_IDLE,
11621 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011622 return -EBUSY;
11623 }
11624
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053011625 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +053011626 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011627
11628 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011629 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011630 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
11631 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053011632 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011633 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070011634 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011635
11636 /* in add station, we accept existing valid staId if there is */
11637 if ((0 == update) &&
11638 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
11639 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011640 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011641 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011642 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011643 " link_status %d. staId %d. add station ignored.",
11644 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011645 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011646 return 0;
11647 }
11648 /* in change station, we accept only when staId is valid */
11649 if ((1 == update) &&
11650 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
11651 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
11652 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011653 tANI_U16 staId = pTdlsPeer->staId;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011654 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011655 "%s: " MAC_ADDRESS_STR
11656 " link status %d. staId %d. change station %s.",
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011657 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, staId,
11658 (TDLS_STA_INDEX_VALID(staId)) ? "ignored" : "declined");
11659 mutex_unlock(&pHddCtx->tdls_lock);
11660 return (TDLS_STA_INDEX_VALID(staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011661 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011662 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070011663
11664 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053011665 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011666 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011667 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11668 "%s: " MAC_ADDRESS_STR
11669 " TDLS setup is ongoing. Request declined.",
11670 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -070011671 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011672 }
11673
11674 /* first to check if we reached to maximum supported TDLS peer.
11675 TODO: for now, return -EPERM looks working fine,
11676 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011677 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
11678 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011679 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011680 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11681 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011682 " TDLS Max peer already connected. Request declined."
11683 " Num of peers (%d), Max allowed (%d).",
11684 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
11685 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070011686 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011687 }
11688 else
11689 {
11690 hddTdlsPeer_t *pTdlsPeer;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011691 mutex_lock(&pHddCtx->tdls_lock);
11692 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011693 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011694 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011695 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011696 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11697 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
11698 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011699 return -EPERM;
11700 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011701 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011702 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011703 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +053011704 wlan_hdd_tdls_set_link_status(pAdapter,
11705 mac,
11706 eTDLS_LINK_CONNECTING,
11707 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011708
Jeff Johnsond75fe012013-04-06 10:53:06 -070011709 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053011710 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011711 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011712 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011713 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -070011714 if(StaParams->htcap_present)
11715 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011716 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070011717 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011718 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070011719 "ht_capa->extended_capabilities: %0x",
11720 StaParams->HTCap.extendedHtCapInfo);
11721 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011722 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011723 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011724 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011725 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -070011726 if(StaParams->vhtcap_present)
11727 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011728 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070011729 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
11730 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
11731 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
11732 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011733 {
11734 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011735 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011736 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011737 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011738 "[%d]: %x ", i, StaParams->supported_rates[i]);
11739 }
Jeff Johnsond75fe012013-04-06 10:53:06 -070011740 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053011741 else if ((1 == update) && (NULL == StaParams))
11742 {
11743 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11744 "%s : update is true, but staParams is NULL. Error!", __func__);
11745 return -EPERM;
11746 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011747
11748 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
11749
11750 if (!update)
11751 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053011752 /*Before adding sta make sure that device exited from BMPS*/
11753 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
11754 {
11755 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11756 "%s: Adding tdls peer sta. Disable BMPS", __func__);
11757 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
11758 if (status != VOS_STATUS_SUCCESS) {
11759 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
11760 }
11761 }
11762
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011763 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011764 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011765 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053011766 hddLog(VOS_TRACE_LEVEL_ERROR,
11767 FL("Failed to add TDLS peer STA. Enable Bmps"));
11768 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011769 return -EPERM;
11770 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011771 }
11772 else
11773 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011774 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011775 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011776 if (ret != eHAL_STATUS_SUCCESS) {
11777 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
11778 return -EPERM;
11779 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011780 }
11781
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011782 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011783 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
11784
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053011785 mutex_lock(&pHddCtx->tdls_lock);
11786 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
11787
Masti, Narayanraddi07262462016-01-19 12:40:06 +053011788 if ((pTdlsPeer != NULL) &&
11789 (pTdlsPeer->link_status == eTDLS_LINK_TEARING))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011790 {
Masti, Narayanraddi07262462016-01-19 12:40:06 +053011791 hddLog(VOS_TRACE_LEVEL_ERROR,
11792 FL("peer link status %u"), pTdlsPeer->link_status);
11793 mutex_unlock(&pHddCtx->tdls_lock);
11794 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011795 }
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053011796 mutex_unlock(&pHddCtx->tdls_lock);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011797
Masti, Narayanraddi07262462016-01-19 12:40:06 +053011798 if (ret <= 0)
11799 {
11800 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11801 "%s: timeout waiting for tdls add station indication %ld",
11802 __func__, ret);
11803 goto error;
11804 }
11805
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011806 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
11807 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011808 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011809 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070011810 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011811 }
11812
11813 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -070011814
11815error:
Atul Mittal115287b2014-07-08 13:26:33 +053011816 wlan_hdd_tdls_set_link_status(pAdapter,
11817 mac,
11818 eTDLS_LINK_IDLE,
11819 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -070011820 return -EPERM;
11821
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011822}
11823#endif
11824
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011825static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011826 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011827#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
11828 const u8 *mac,
11829#else
Jeff Johnson295189b2012-06-20 16:38:30 -070011830 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011831#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011832 struct station_parameters *params)
11833{
11834 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011835 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +053011836 hdd_context_t *pHddCtx;
11837 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011838 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011839 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070011840#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011841 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011842 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011843 tANI_U8 isOffChannelSupported = 0;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011844 tANI_U8 isQosWmmSta = FALSE;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070011845#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070011846
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011847 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011848
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011849 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +053011850 if ((NULL == pAdapter))
11851 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011852 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053011853 "invalid adapter ");
11854 return -EINVAL;
11855 }
11856
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011857 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11858 TRACE_CODE_HDD_CHANGE_STATION,
11859 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +053011860 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +053011861
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011862 ret = wlan_hdd_validate_context(pHddCtx);
11863 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +053011864 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011865 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +053011866 }
11867
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011868 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11869
11870 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011871 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011872 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11873 "invalid HDD station context");
11874 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011875 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011876 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
11877
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011878 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
11879 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -070011880 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011881 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -070011882 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011883 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -070011884 WLANTL_STA_AUTHENTICATED);
11885
Gopichand Nakkala29149562013-05-10 21:43:41 +053011886 if (status != VOS_STATUS_SUCCESS)
11887 {
11888 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11889 "%s: Not able to change TL state to AUTHENTICATED", __func__);
11890 return -EINVAL;
11891 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011892 }
11893 }
Hoonki Leea6d49be2013-04-05 09:43:25 -070011894 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
11895 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +053011896#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011897 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
11898 StaParams.capability = params->capability;
11899 StaParams.uapsd_queues = params->uapsd_queues;
11900 StaParams.max_sp = params->max_sp;
11901
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011902 /* Convert (first channel , number of channels) tuple to
11903 * the total list of channels. This goes with the assumption
11904 * that if the first channel is < 14, then the next channels
11905 * are an incremental of 1 else an incremental of 4 till the number
11906 * of channels.
11907 */
11908 if (0 != params->supported_channels_len) {
11909 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
11910 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
11911 {
11912 int wifi_chan_index;
11913 StaParams.supported_channels[j] = params->supported_channels[i];
11914 wifi_chan_index =
11915 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
11916 no_of_channels = params->supported_channels[i+1];
11917 for(k=1; k <= no_of_channels; k++)
11918 {
11919 StaParams.supported_channels[j+1] =
11920 StaParams.supported_channels[j] + wifi_chan_index;
11921 j+=1;
11922 }
11923 }
11924 StaParams.supported_channels_len = j;
11925 }
SaidiReddy Yenuga0f1a1592017-04-05 13:18:26 +053011926 if (params->supported_oper_classes_len >
11927 SIR_MAC_MAX_SUPP_OPER_CLASSES) {
11928 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11929 "received oper classes:%d, resetting it to max supported %d",
11930 params->supported_oper_classes_len,
11931 SIR_MAC_MAX_SUPP_OPER_CLASSES);
11932 params->supported_oper_classes_len =
11933 SIR_MAC_MAX_SUPP_OPER_CLASSES;
11934 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011935 vos_mem_copy(StaParams.supported_oper_classes,
11936 params->supported_oper_classes,
11937 params->supported_oper_classes_len);
11938 StaParams.supported_oper_classes_len =
11939 params->supported_oper_classes_len;
11940
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053011941 if (params->ext_capab_len > sizeof(StaParams.extn_capability)) {
11942 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11943 "received extn capabilities:%d, resetting it to max supported",
11944 params->ext_capab_len);
11945 params->ext_capab_len = sizeof(StaParams.extn_capability);
11946 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011947 if (0 != params->ext_capab_len)
11948 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053011949 params->ext_capab_len);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011950
11951 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070011952 {
11953 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011954 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070011955 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011956
11957 StaParams.supported_rates_len = params->supported_rates_len;
11958
11959 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
11960 * The supported_rates array , for all the structures propogating till Add Sta
11961 * to the firmware has to be modified , if the supplicant (ieee80211) is
11962 * modified to send more rates.
11963 */
11964
11965 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
11966 */
11967 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
11968 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
11969
11970 if (0 != StaParams.supported_rates_len) {
11971 int i = 0;
11972 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
11973 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011974 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011975 "Supported Rates with Length %d", StaParams.supported_rates_len);
11976 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011977 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011978 "[%d]: %0x", i, StaParams.supported_rates[i]);
11979 }
11980
11981 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070011982 {
11983 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011984 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070011985 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011986
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011987 if (0 != params->ext_capab_len ) {
11988 /*Define A Macro : TODO Sunil*/
11989 if ((1<<4) & StaParams.extn_capability[3]) {
11990 isBufSta = 1;
11991 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011992 /* TDLS Channel Switching Support */
11993 if ((1<<6) & StaParams.extn_capability[3]) {
11994 isOffChannelSupported = 1;
11995 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011996 }
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011997
11998 if (pHddCtx->cfg_ini->fEnableTDLSWmmMode &&
Nitesh Shah48df4c02016-08-12 16:27:33 +053011999 (params->ht_capa || params->vht_capa ||
12000 (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME))))
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053012001 /* TDLS Peer is WME/QoS capable */
12002 isQosWmmSta = TRUE;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053012003
12004 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12005 "%s: TDLS Peer is QOS capable isQosWmmSta= %d HTcapPresent= %d",
12006 __func__, isQosWmmSta, StaParams.htcap_present);
12007
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012008 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
12009 &StaParams, isBufSta,
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053012010 isOffChannelSupported,
12011 isQosWmmSta);
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012012
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053012013 if (VOS_STATUS_SUCCESS != status) {
12014 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12015 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
12016 return -EINVAL;
12017 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012018 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
12019
12020 if (VOS_STATUS_SUCCESS != status) {
12021 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12022 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
12023 return -EINVAL;
12024 }
12025 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -070012026#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +053012027 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012028 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012029 return status;
12030}
12031
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012032#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
12033static int wlan_hdd_change_station(struct wiphy *wiphy,
12034 struct net_device *dev,
12035 const u8 *mac,
12036 struct station_parameters *params)
12037#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012038static int wlan_hdd_change_station(struct wiphy *wiphy,
12039 struct net_device *dev,
12040 u8 *mac,
12041 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012042#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012043{
12044 int ret;
12045
12046 vos_ssr_protect(__func__);
12047 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
12048 vos_ssr_unprotect(__func__);
12049
12050 return ret;
12051}
12052
Jeff Johnson295189b2012-06-20 16:38:30 -070012053/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012054 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -070012055 * This function is used to initialize the key information
12056 */
12057#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012058static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012059 struct net_device *ndev,
12060 u8 key_index, bool pairwise,
12061 const u8 *mac_addr,
12062 struct key_params *params
12063 )
12064#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012065static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012066 struct net_device *ndev,
12067 u8 key_index, const u8 *mac_addr,
12068 struct key_params *params
12069 )
12070#endif
12071{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012072 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070012073 tCsrRoamSetKey setKey;
12074 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012075 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012076 v_U32_t roamId= 0xFF;
12077 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070012078 hdd_hostapd_state_t *pHostapdState;
12079 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012080 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012081 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012082
12083 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012084
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012085 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12086 TRACE_CODE_HDD_CFG80211_ADD_KEY,
12087 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012088 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12089 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012090 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012091 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012092 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012093 }
12094
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012095 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12096 __func__, hdd_device_modetoString(pAdapter->device_mode),
12097 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012098
12099 if (CSR_MAX_NUM_KEY <= key_index)
12100 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012101 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012102 key_index);
12103
12104 return -EINVAL;
12105 }
12106
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012107 if (CSR_MAX_KEY_LEN < params->key_len)
12108 {
12109 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
12110 params->key_len);
12111
12112 return -EINVAL;
12113 }
12114
12115 hddLog(VOS_TRACE_LEVEL_INFO,
12116 "%s: called with key index = %d & key length %d",
12117 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070012118
12119 /*extract key idx, key len and key*/
12120 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
12121 setKey.keyId = key_index;
12122 setKey.keyLength = params->key_len;
12123 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
12124
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012125 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070012126 {
12127 case WLAN_CIPHER_SUITE_WEP40:
12128 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
12129 break;
12130
12131 case WLAN_CIPHER_SUITE_WEP104:
12132 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
12133 break;
12134
12135 case WLAN_CIPHER_SUITE_TKIP:
12136 {
12137 u8 *pKey = &setKey.Key[0];
12138 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
12139
12140 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
12141
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012142 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -070012143
12144 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012145 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070012146 |--------------|----------|----------|
12147 <---16bytes---><--8bytes--><--8bytes-->
12148
12149 */
12150 /*Sme expects the 32 bytes key to be in the below order
12151
12152 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012153 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070012154 |--------------|----------|----------|
12155 <---16bytes---><--8bytes--><--8bytes-->
12156 */
12157 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012158 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -070012159
12160 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012161 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070012162
12163 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012164 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070012165
12166
12167 break;
12168 }
12169
12170 case WLAN_CIPHER_SUITE_CCMP:
12171 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
12172 break;
12173
12174#ifdef FEATURE_WLAN_WAPI
12175 case WLAN_CIPHER_SUITE_SMS4:
12176 {
12177 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
12178 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
12179 params->key, params->key_len);
12180 return 0;
12181 }
12182#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070012183
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080012184#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070012185 case WLAN_CIPHER_SUITE_KRK:
12186 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
12187 break;
12188#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070012189
12190#ifdef WLAN_FEATURE_11W
12191 case WLAN_CIPHER_SUITE_AES_CMAC:
12192 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -070012193 break;
Chet Lanctot186b5732013-03-18 10:26:30 -070012194#endif
12195
Jeff Johnson295189b2012-06-20 16:38:30 -070012196 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012197 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070012198 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012199 status = -EOPNOTSUPP;
12200 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012201 }
12202
12203 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
12204 __func__, setKey.encType);
12205
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012206 if (
Jeff Johnson295189b2012-06-20 16:38:30 -070012207#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12208 (!pairwise)
12209#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012210 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -070012211#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012212 )
12213 {
12214 /* set group key*/
12215 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12216 "%s- %d: setting Broadcast key",
12217 __func__, __LINE__);
12218 setKey.keyDirection = eSIR_RX_ONLY;
12219 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
12220 }
12221 else
12222 {
12223 /* set pairwise key*/
12224 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12225 "%s- %d: setting pairwise key",
12226 __func__, __LINE__);
12227 setKey.keyDirection = eSIR_TX_RX;
12228 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
12229 }
12230 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
12231 {
12232 setKey.keyDirection = eSIR_TX_RX;
12233 /*Set the group key*/
12234 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
12235 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -070012236
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012237 if ( 0 != status )
12238 {
12239 hddLog(VOS_TRACE_LEVEL_ERROR,
12240 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012241 status = -EINVAL;
12242 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012243 }
12244 /*Save the keys here and call sme_RoamSetKey for setting
12245 the PTK after peer joins the IBSS network*/
12246 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
12247 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012248 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012249 }
Gopichand Nakkala29149562013-05-10 21:43:41 +053012250 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
12251 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
12252 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012253 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012254 if( pHostapdState->bssState == BSS_START )
12255 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012256 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12257 vos_status = wlan_hdd_check_ula_done(pAdapter);
12258
12259 if ( vos_status != VOS_STATUS_SUCCESS )
12260 {
12261 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12262 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
12263 __LINE__, vos_status );
12264
12265 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
12266
12267 status = -EINVAL;
12268 goto end;
12269 }
12270
Jeff Johnson295189b2012-06-20 16:38:30 -070012271 status = WLANSAP_SetKeySta( pVosContext, &setKey);
12272
12273 if ( status != eHAL_STATUS_SUCCESS )
12274 {
12275 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12276 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
12277 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012278 status = -EINVAL;
12279 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012280 }
12281 }
12282
12283 /* Saving WEP keys */
12284 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
12285 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
12286 {
12287 //Save the wep key in ap context. Issue setkey after the BSS is started.
12288 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
12289 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
12290 }
12291 else
12292 {
12293 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012294 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012295 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
12296 }
12297 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012298 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
12299 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012300 {
12301 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12302 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12303
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012304#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12305 if (!pairwise)
12306#else
12307 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
12308#endif
12309 {
12310 /* set group key*/
12311 if (pHddStaCtx->roam_info.deferKeyComplete)
12312 {
12313 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12314 "%s- %d: Perform Set key Complete",
12315 __func__, __LINE__);
12316 hdd_PerformRoamSetKeyComplete(pAdapter);
12317 }
12318 }
12319
Jeff Johnson295189b2012-06-20 16:38:30 -070012320 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
12321
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -080012322 pWextState->roamProfile.Keys.defaultIndex = key_index;
12323
12324
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012325 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070012326 params->key, params->key_len);
12327
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012328
Jeff Johnson295189b2012-06-20 16:38:30 -070012329 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
12330
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012331 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070012332 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012333 __func__, setKey.peerMac[0], setKey.peerMac[1],
12334 setKey.peerMac[2], setKey.peerMac[3],
12335 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070012336 setKey.keyDirection);
12337
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012338 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +053012339
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012340 if ( vos_status != VOS_STATUS_SUCCESS )
12341 {
12342 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012343 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
12344 __LINE__, vos_status );
12345
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012346 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012347
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012348 status = -EINVAL;
12349 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012350
12351 }
12352
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012353#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012354 /* The supplicant may attempt to set the PTK once pre-authentication
12355 is done. Save the key in the UMAC and include it in the ADD BSS
12356 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012357 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012358 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012359 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012360 hddLog(VOS_TRACE_LEVEL_INFO_MED,
12361 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012362 status = 0;
12363 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012364 }
12365 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
12366 {
12367 hddLog(VOS_TRACE_LEVEL_ERROR,
12368 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012369 status = -EINVAL;
12370 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012371 }
12372#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070012373
12374 /* issue set key request to SME*/
12375 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
12376 pAdapter->sessionId, &setKey, &roamId );
12377
12378 if ( 0 != status )
12379 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012380 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012381 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
12382 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012383 status = -EINVAL;
12384 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012385 }
12386
12387
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012388 /* in case of IBSS as there was no information available about WEP keys during
12389 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070012390 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012391 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
12392 !( ( IW_AUTH_KEY_MGMT_802_1X
12393 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070012394 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
12395 )
12396 &&
12397 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
12398 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
12399 )
12400 )
12401 {
12402 setKey.keyDirection = eSIR_RX_ONLY;
12403 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
12404
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012405 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070012406 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012407 __func__, setKey.peerMac[0], setKey.peerMac[1],
12408 setKey.peerMac[2], setKey.peerMac[3],
12409 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070012410 setKey.keyDirection);
12411
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012412 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070012413 pAdapter->sessionId, &setKey, &roamId );
12414
12415 if ( 0 != status )
12416 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012417 hddLog(VOS_TRACE_LEVEL_ERROR,
12418 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012419 __func__, status);
12420 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012421 status = -EINVAL;
12422 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012423 }
12424 }
12425 }
12426
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012427end:
12428 /* Need to clear any trace of key value in the memory.
12429 * Thus zero out the memory even though it is local
12430 * variable.
12431 */
12432 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012433 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012434 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012435}
12436
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012437#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12438static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
12439 struct net_device *ndev,
12440 u8 key_index, bool pairwise,
12441 const u8 *mac_addr,
12442 struct key_params *params
12443 )
12444#else
12445static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
12446 struct net_device *ndev,
12447 u8 key_index, const u8 *mac_addr,
12448 struct key_params *params
12449 )
12450#endif
12451{
12452 int ret;
12453 vos_ssr_protect(__func__);
12454#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12455 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
12456 mac_addr, params);
12457#else
12458 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
12459 params);
12460#endif
12461 vos_ssr_unprotect(__func__);
12462
12463 return ret;
12464}
12465
Jeff Johnson295189b2012-06-20 16:38:30 -070012466/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012467 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070012468 * This function is used to get the key information
12469 */
12470#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012471static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012472 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012473 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012474 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070012475 const u8 *mac_addr, void *cookie,
12476 void (*callback)(void *cookie, struct key_params*)
12477 )
12478#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012479static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012480 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012481 struct net_device *ndev,
12482 u8 key_index, const u8 *mac_addr, void *cookie,
12483 void (*callback)(void *cookie, struct key_params*)
12484 )
12485#endif
12486{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012487 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012488 hdd_wext_state_t *pWextState = NULL;
12489 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012490 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012491 hdd_context_t *pHddCtx;
12492 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012493
12494 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012495
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012496 if (NULL == pAdapter)
12497 {
12498 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12499 "%s: HDD adapter is Null", __func__);
12500 return -ENODEV;
12501 }
12502
12503 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12504 ret = wlan_hdd_validate_context(pHddCtx);
12505 if (0 != ret)
12506 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012507 return ret;
12508 }
12509
12510 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12511 pRoamProfile = &(pWextState->roamProfile);
12512
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012513 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12514 __func__, hdd_device_modetoString(pAdapter->device_mode),
12515 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012516
Jeff Johnson295189b2012-06-20 16:38:30 -070012517 memset(&params, 0, sizeof(params));
12518
12519 if (CSR_MAX_NUM_KEY <= key_index)
12520 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012521 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070012522 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012523 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012524
12525 switch(pRoamProfile->EncryptionType.encryptionType[0])
12526 {
12527 case eCSR_ENCRYPT_TYPE_NONE:
12528 params.cipher = IW_AUTH_CIPHER_NONE;
12529 break;
12530
12531 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
12532 case eCSR_ENCRYPT_TYPE_WEP40:
12533 params.cipher = WLAN_CIPHER_SUITE_WEP40;
12534 break;
12535
12536 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
12537 case eCSR_ENCRYPT_TYPE_WEP104:
12538 params.cipher = WLAN_CIPHER_SUITE_WEP104;
12539 break;
12540
12541 case eCSR_ENCRYPT_TYPE_TKIP:
12542 params.cipher = WLAN_CIPHER_SUITE_TKIP;
12543 break;
12544
12545 case eCSR_ENCRYPT_TYPE_AES:
12546 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
12547 break;
12548
12549 default:
12550 params.cipher = IW_AUTH_CIPHER_NONE;
12551 break;
12552 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012553
c_hpothuaaf19692014-05-17 17:01:48 +053012554 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12555 TRACE_CODE_HDD_CFG80211_GET_KEY,
12556 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012557
Jeff Johnson295189b2012-06-20 16:38:30 -070012558 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
12559 params.seq_len = 0;
12560 params.seq = NULL;
12561 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
12562 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012563 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012564 return 0;
12565}
12566
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012567#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12568static int wlan_hdd_cfg80211_get_key(
12569 struct wiphy *wiphy,
12570 struct net_device *ndev,
12571 u8 key_index, bool pairwise,
12572 const u8 *mac_addr, void *cookie,
12573 void (*callback)(void *cookie, struct key_params*)
12574 )
12575#else
12576static int wlan_hdd_cfg80211_get_key(
12577 struct wiphy *wiphy,
12578 struct net_device *ndev,
12579 u8 key_index, const u8 *mac_addr, void *cookie,
12580 void (*callback)(void *cookie, struct key_params*)
12581 )
12582#endif
12583{
12584 int ret;
12585
12586 vos_ssr_protect(__func__);
12587#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12588 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
12589 mac_addr, cookie, callback);
12590#else
12591 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
12592 callback);
12593#endif
12594 vos_ssr_unprotect(__func__);
12595
12596 return ret;
12597}
12598
Jeff Johnson295189b2012-06-20 16:38:30 -070012599/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012600 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070012601 * This function is used to delete the key information
12602 */
12603#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012604static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012605 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012606 u8 key_index,
12607 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070012608 const u8 *mac_addr
12609 )
12610#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012611static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012612 struct net_device *ndev,
12613 u8 key_index,
12614 const u8 *mac_addr
12615 )
12616#endif
12617{
12618 int status = 0;
12619
12620 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012621 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070012622 //it is observed that this is invalidating peer
12623 //key index whenever re-key is done. This is affecting data link.
12624 //It should be ok to ignore del_key.
12625#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012626 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
12627 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070012628 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
12629 tCsrRoamSetKey setKey;
12630 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012631
Jeff Johnson295189b2012-06-20 16:38:30 -070012632 ENTER();
12633
12634 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
12635 __func__,pAdapter->device_mode);
12636
12637 if (CSR_MAX_NUM_KEY <= key_index)
12638 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012639 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012640 key_index);
12641
12642 return -EINVAL;
12643 }
12644
12645 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
12646 setKey.keyId = key_index;
12647
12648 if (mac_addr)
12649 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
12650 else
12651 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
12652
12653 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
12654
12655 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012656 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012657 )
12658 {
12659
12660 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070012661 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
12662 if( pHostapdState->bssState == BSS_START)
12663 {
12664 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012665
Jeff Johnson295189b2012-06-20 16:38:30 -070012666 if ( status != eHAL_STATUS_SUCCESS )
12667 {
12668 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12669 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
12670 __LINE__, status );
12671 }
12672 }
12673 }
12674 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012675 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070012676 )
12677 {
12678 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12679
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012680 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
12681
12682 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070012683 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012684 __func__, setKey.peerMac[0], setKey.peerMac[1],
12685 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070012686 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012687 if(pAdapter->sessionCtx.station.conn_info.connState ==
12688 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070012689 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012690 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070012691 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012692
Jeff Johnson295189b2012-06-20 16:38:30 -070012693 if ( 0 != status )
12694 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012695 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012696 "%s: sme_RoamSetKey failure, returned %d",
12697 __func__, status);
12698 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
12699 return -EINVAL;
12700 }
12701 }
12702 }
12703#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070012704 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012705 return status;
12706}
12707
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012708#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12709static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
12710 struct net_device *ndev,
12711 u8 key_index,
12712 bool pairwise,
12713 const u8 *mac_addr
12714 )
12715#else
12716static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
12717 struct net_device *ndev,
12718 u8 key_index,
12719 const u8 *mac_addr
12720 )
12721#endif
12722{
12723 int ret;
12724
12725 vos_ssr_protect(__func__);
12726#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12727 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
12728 mac_addr);
12729#else
12730 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
12731#endif
12732 vos_ssr_unprotect(__func__);
12733
12734 return ret;
12735}
12736
Jeff Johnson295189b2012-06-20 16:38:30 -070012737/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012738 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070012739 * This function is used to set the default tx key index
12740 */
12741#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012742static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012743 struct net_device *ndev,
12744 u8 key_index,
12745 bool unicast, bool multicast)
12746#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012747static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012748 struct net_device *ndev,
12749 u8 key_index)
12750#endif
12751{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012752 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012753 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053012754 hdd_wext_state_t *pWextState;
12755 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012756 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012757
12758 ENTER();
12759
Gopichand Nakkala29149562013-05-10 21:43:41 +053012760 if ((NULL == pAdapter))
12761 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012762 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053012763 "invalid adapter");
12764 return -EINVAL;
12765 }
12766
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012767 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12768 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
12769 pAdapter->sessionId, key_index));
12770
Gopichand Nakkala29149562013-05-10 21:43:41 +053012771 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12772 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12773
12774 if ((NULL == pWextState) || (NULL == pHddStaCtx))
12775 {
12776 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12777 "invalid Wext state or HDD context");
12778 return -EINVAL;
12779 }
12780
Arif Hussain6d2a3322013-11-17 19:50:10 -080012781 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012782 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012783
Jeff Johnson295189b2012-06-20 16:38:30 -070012784 if (CSR_MAX_NUM_KEY <= key_index)
12785 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012786 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012787 key_index);
12788
12789 return -EINVAL;
12790 }
12791
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012792 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12793 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012794 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012795 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012796 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012797 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012798
Jeff Johnson295189b2012-06-20 16:38:30 -070012799 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070012800 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012801 )
Jeff Johnson295189b2012-06-20 16:38:30 -070012802 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053012803 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080012804 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012805 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080012806 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070012807 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012808 {
12809 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070012810 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012811
Jeff Johnson295189b2012-06-20 16:38:30 -070012812 tCsrRoamSetKey setKey;
12813 v_U32_t roamId= 0xFF;
12814 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012815
12816 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012817 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012818
Jeff Johnson295189b2012-06-20 16:38:30 -070012819 Keys->defaultIndex = (u8)key_index;
12820 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
12821 setKey.keyId = key_index;
12822 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012823
12824 vos_mem_copy(&setKey.Key[0],
12825 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070012826 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012827
Gopichand Nakkala29149562013-05-10 21:43:41 +053012828 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012829
12830 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070012831 &pHddStaCtx->conn_info.bssId[0],
12832 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012833
Gopichand Nakkala29149562013-05-10 21:43:41 +053012834 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
12835 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
12836 eCSR_ENCRYPT_TYPE_WEP104)
12837 {
12838 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
12839 even though ap is configured for WEP-40 encryption. In this canse the key length
12840 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
12841 type(104) and switching encryption type to 40*/
12842 pWextState->roamProfile.EncryptionType.encryptionType[0] =
12843 eCSR_ENCRYPT_TYPE_WEP40;
12844 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
12845 eCSR_ENCRYPT_TYPE_WEP40;
12846 }
12847
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012848 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070012849 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012850
Jeff Johnson295189b2012-06-20 16:38:30 -070012851 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012852 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070012853 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012854
Jeff Johnson295189b2012-06-20 16:38:30 -070012855 if ( 0 != status )
12856 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012857 hddLog(VOS_TRACE_LEVEL_ERROR,
12858 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012859 status);
12860 return -EINVAL;
12861 }
12862 }
12863 }
12864
12865 /* In SoftAp mode setting key direction for default mode */
12866 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
12867 {
12868 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
12869 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
12870 (eCSR_ENCRYPT_TYPE_AES !=
12871 pWextState->roamProfile.EncryptionType.encryptionType[0])
12872 )
12873 {
12874 /* Saving key direction for default key index to TX default */
12875 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
12876 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
12877 }
12878 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012879 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012880 return status;
12881}
12882
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012883#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12884static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
12885 struct net_device *ndev,
12886 u8 key_index,
12887 bool unicast, bool multicast)
12888#else
12889static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
12890 struct net_device *ndev,
12891 u8 key_index)
12892#endif
12893{
12894 int ret;
12895 vos_ssr_protect(__func__);
12896#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12897 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
12898 multicast);
12899#else
12900 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
12901#endif
12902 vos_ssr_unprotect(__func__);
12903
12904 return ret;
12905}
12906
Jeff Johnson295189b2012-06-20 16:38:30 -070012907/*
12908 * FUNCTION: wlan_hdd_cfg80211_inform_bss
12909 * This function is used to inform the BSS details to nl80211 interface.
12910 */
12911static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
12912 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
12913{
12914 struct net_device *dev = pAdapter->dev;
12915 struct wireless_dev *wdev = dev->ieee80211_ptr;
12916 struct wiphy *wiphy = wdev->wiphy;
12917 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
12918 int chan_no;
12919 int ie_length;
12920 const char *ie;
12921 unsigned int freq;
12922 struct ieee80211_channel *chan;
12923 int rssi = 0;
12924 struct cfg80211_bss *bss = NULL;
12925
Jeff Johnson295189b2012-06-20 16:38:30 -070012926 if( NULL == pBssDesc )
12927 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012928 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012929 return bss;
12930 }
12931
12932 chan_no = pBssDesc->channelId;
12933 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
12934 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
12935
12936 if( NULL == ie )
12937 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012938 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012939 return bss;
12940 }
12941
12942#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
12943 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
12944 {
12945 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
12946 }
12947 else
12948 {
12949 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
12950 }
12951#else
12952 freq = ieee80211_channel_to_frequency(chan_no);
12953#endif
12954
12955 chan = __ieee80211_get_channel(wiphy, freq);
12956
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053012957 if (!chan) {
12958 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
12959 return NULL;
12960 }
12961
Abhishek Singhaee43942014-06-16 18:55:47 +053012962 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070012963
Anand N Sunkad9f80b742015-07-30 20:05:51 +053012964 return cfg80211_inform_bss(wiphy, chan,
12965#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12966 CFG80211_BSS_FTYPE_UNKNOWN,
12967#endif
12968 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012969 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070012970 pBssDesc->capabilityInfo,
12971 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053012972 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070012973}
12974
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053012975/*
12976 * wlan_hdd_cfg80211_update_bss_list :to inform nl80211
12977 * interface that BSS might have been lost.
12978 * @pAdapter: adaptor
12979 * @bssid: bssid which might have been lost
12980 *
12981 * Return: bss which is unlinked from kernel cache
12982 */
12983struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_list(
12984 hdd_adapter_t *pAdapter, tSirMacAddr bssid)
12985{
12986 struct net_device *dev = pAdapter->dev;
12987 struct wireless_dev *wdev = dev->ieee80211_ptr;
12988 struct wiphy *wiphy = wdev->wiphy;
12989 struct cfg80211_bss *bss = NULL;
12990
Abhishek Singh5a597e62016-12-05 15:16:30 +053012991 bss = hdd_get_bss_entry(wiphy,
12992 NULL, bssid,
12993 NULL, 0);
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053012994 if (bss == NULL) {
12995 hddLog(LOGE, FL("BSS not present"));
12996 } else {
12997 hddLog(LOG1, FL("cfg80211_unlink_bss called for BSSID "
12998 MAC_ADDRESS_STR), MAC_ADDR_ARRAY(bssid));
12999 cfg80211_unlink_bss(wiphy, bss);
13000 }
13001 return bss;
13002}
Jeff Johnson295189b2012-06-20 16:38:30 -070013003
13004
13005/*
13006 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
13007 * This function is used to inform the BSS details to nl80211 interface.
13008 */
13009struct cfg80211_bss*
13010wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
13011 tSirBssDescription *bss_desc
13012 )
13013{
13014 /*
13015 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
13016 already exists in bss data base of cfg80211 for that particular BSS ID.
13017 Using cfg80211_inform_bss_frame to update the bss entry instead of
13018 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
13019 now there is no possibility to get the mgmt(probe response) frame from PE,
13020 converting bss_desc to ieee80211_mgmt(probe response) and passing to
13021 cfg80211_inform_bss_frame.
13022 */
13023 struct net_device *dev = pAdapter->dev;
13024 struct wireless_dev *wdev = dev->ieee80211_ptr;
13025 struct wiphy *wiphy = wdev->wiphy;
13026 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080013027#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
13028 qcom_ie_age *qie_age = NULL;
13029 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
13030#else
Jeff Johnson295189b2012-06-20 16:38:30 -070013031 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080013032#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013033 const char *ie =
13034 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
13035 unsigned int freq;
13036 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053013037 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013038 struct cfg80211_bss *bss_status = NULL;
13039 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
13040 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070013041 hdd_context_t *pHddCtx;
13042 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070013043#ifdef WLAN_OPEN_SOURCE
13044 struct timespec ts;
13045#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013046
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013047
Wilson Yangf80a0542013-10-07 13:02:37 -070013048 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13049 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070013050 if (0 != status)
13051 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070013052 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070013053 }
13054
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053013055 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070013056 if (!mgmt)
13057 {
13058 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13059 "%s: memory allocation failed ", __func__);
13060 return NULL;
13061 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070013062
Jeff Johnson295189b2012-06-20 16:38:30 -070013063 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070013064
13065#ifdef WLAN_OPEN_SOURCE
13066 /* Android does not want the timestamp from the frame.
13067 Instead it wants a monotonic increasing value */
13068 get_monotonic_boottime(&ts);
13069 mgmt->u.probe_resp.timestamp =
13070 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
13071#else
13072 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070013073 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
13074 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070013075
13076#endif
13077
Jeff Johnson295189b2012-06-20 16:38:30 -070013078 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
13079 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080013080
13081#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
13082 /* GPS Requirement: need age ie per entry. Using vendor specific. */
13083 /* Assuming this is the last IE, copy at the end */
13084 ie_length -=sizeof(qcom_ie_age);
13085 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
13086 qie_age->element_id = QCOM_VENDOR_IE_ID;
13087 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
13088 qie_age->oui_1 = QCOM_OUI1;
13089 qie_age->oui_2 = QCOM_OUI2;
13090 qie_age->oui_3 = QCOM_OUI3;
13091 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
Selvaraj, Sridhar4b3a8362016-10-12 12:34:08 +053013092 /* Lowi expects the timestamp of bss in units of 1/10 ms. In driver all
13093 * bss related timestamp is in units of ms. Due to this when scan results
13094 * are sent to lowi the scan age is high.To address this, send age in units
13095 * of 1/10 ms.
13096 */
13097 qie_age->age = (vos_timer_get_system_time() -
13098 bss_desc->nReceivedTime)/10;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080013099#endif
13100
Jeff Johnson295189b2012-06-20 16:38:30 -070013101 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053013102 if (bss_desc->fProbeRsp)
13103 {
13104 mgmt->frame_control |=
13105 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
13106 }
13107 else
13108 {
13109 mgmt->frame_control |=
13110 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
13111 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013112
13113#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013114 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070013115 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
13116 {
13117 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
13118 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013119 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070013120 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
13121
13122 {
13123 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
13124 }
13125 else
13126 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013127 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
13128 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070013129 kfree(mgmt);
13130 return NULL;
13131 }
13132#else
13133 freq = ieee80211_channel_to_frequency(chan_no);
13134#endif
13135 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080013136 /*when the band is changed on the fly using the GUI, three things are done
13137 * 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)
13138 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
13139 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
13140 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
13141 * and discards the channels correponding to previous band and calls back with zero bss results.
13142 * 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
13143 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
13144 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
13145 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
13146 * So drop the bss and continue to next bss.
13147 */
13148 if(chan == NULL)
13149 {
Deepthi Gowri306657b2016-04-28 17:10:41 +053013150 hddLog(VOS_TRACE_LEVEL_ERROR,
13151 FL("chan pointer is NULL, chan_no: %d freq: %d"),
13152 chan_no, freq);
Chilam Ngc4244af2013-04-01 15:37:32 -070013153 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080013154 return NULL;
13155 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053013156 /*To keep the rssi icon of the connected AP in the scan window
13157 *and the rssi icon of the wireless networks in sync
13158 * */
13159 if (( eConnectionState_Associated ==
13160 pAdapter->sessionCtx.station.conn_info.connState ) &&
13161 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
13162 pAdapter->sessionCtx.station.conn_info.bssId,
13163 WNI_CFG_BSSID_LEN)) &&
13164 (pHddCtx->hdd_wlan_suspended == FALSE))
13165 {
13166 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
13167 rssi = (pAdapter->rssi * 100);
13168 }
13169 else
13170 {
13171 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
13172 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013173
Nirav Shah20ac06f2013-12-12 18:14:06 +053013174 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053013175 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
13176 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053013177
Jeff Johnson295189b2012-06-20 16:38:30 -070013178 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
13179 frame_len, rssi, GFP_KERNEL);
13180 kfree(mgmt);
13181 return bss_status;
13182}
13183
13184/*
13185 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
13186 * This function is used to update the BSS data base of CFG8011
13187 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013188struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070013189 tCsrRoamInfo *pRoamInfo
13190 )
13191{
13192 tCsrRoamConnectedProfile roamProfile;
13193 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13194 struct cfg80211_bss *bss = NULL;
13195
13196 ENTER();
13197
13198 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
13199 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
13200
13201 if (NULL != roamProfile.pBssDesc)
13202 {
Girish Gowlif4b68022014-08-28 23:18:57 +053013203 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
13204 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070013205
13206 if (NULL == bss)
13207 {
13208 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
13209 __func__);
13210 }
13211
13212 sme_RoamFreeConnectProfile(hHal, &roamProfile);
13213 }
13214 else
13215 {
13216 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
13217 __func__);
13218 }
13219 return bss;
13220}
13221
13222/*
13223 * FUNCTION: wlan_hdd_cfg80211_update_bss
13224 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013225static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
13226 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070013227 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013228{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013229 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013230 tCsrScanResultInfo *pScanResult;
13231 eHalStatus status = 0;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013232 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013233 tScanResultHandle pResult;
13234 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070013235 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013236 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070013237 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013238
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013239 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13240 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
13241 NO_SESSION, pAdapter->sessionId));
13242
Wilson Yangf80a0542013-10-07 13:02:37 -070013243 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013244 ret = wlan_hdd_validate_context(pHddCtx);
13245 if (0 != ret)
Jeff Johnson295189b2012-06-20 16:38:30 -070013246 {
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013247 return ret;
Wilson Yangf80a0542013-10-07 13:02:37 -070013248 }
13249
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013250 if (pAdapter->request != NULL)
13251 {
13252 if ((pAdapter->request->n_ssids == 1)
13253 && (pAdapter->request->ssids != NULL)
13254 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
13255 is_p2p_scan = true;
13256 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013257 /*
13258 * start getting scan results and populate cgf80211 BSS database
13259 */
13260 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
13261
13262 /* no scan results */
13263 if (NULL == pResult)
13264 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013265 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
13266 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053013267 wlan_hdd_get_frame_logs(pAdapter,
13268 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070013269 return status;
13270 }
13271
13272 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
13273
13274 while (pScanResult)
13275 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013276 /*
13277 * cfg80211_inform_bss() is not updating ie field of bss entry, if
13278 * entry already exists in bss data base of cfg80211 for that
13279 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
13280 * bss entry instead of cfg80211_inform_bss, But this call expects
13281 * mgmt packet as input. As of now there is no possibility to get
13282 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070013283 * ieee80211_mgmt(probe response) and passing to c
13284 * fg80211_inform_bss_frame.
13285 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013286 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
13287 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
13288 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013289 pScanResult = sme_ScanResultGetNext(hHal, pResult);
13290 continue; //Skip the non p2p bss entries
13291 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013292 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
13293 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013294
Jeff Johnson295189b2012-06-20 16:38:30 -070013295
13296 if (NULL == bss_status)
13297 {
13298 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013299 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013300 }
13301 else
13302 {
Yue Maf49ba872013-08-19 12:04:25 -070013303 cfg80211_put_bss(
13304#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
13305 wiphy,
13306#endif
13307 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070013308 }
13309
13310 pScanResult = sme_ScanResultGetNext(hHal, pResult);
13311 }
13312
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013313 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013314 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013315 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013316}
13317
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013318void
13319hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
13320{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013321 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080013322 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013323} /****** end hddPrintMacAddr() ******/
13324
13325void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070013326hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013327{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013328 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013329 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070013330 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
13331 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
13332 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013333} /****** end hddPrintPmkId() ******/
13334
13335//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
13336//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
13337
13338//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
13339//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
13340
13341#define dump_bssid(bssid) \
13342 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070013343 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
13344 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013345 }
13346
13347#define dump_pmkid(pMac, pmkid) \
13348 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070013349 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
13350 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013351 }
13352
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070013353#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013354/*
13355 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
13356 * This function is used to notify the supplicant of a new PMKSA candidate.
13357 */
13358int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013359 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013360 int index, bool preauth )
13361{
Jeff Johnsone7245742012-09-05 17:12:55 -070013362#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013363 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070013364 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013365
13366 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070013367 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013368
13369 if( NULL == pRoamInfo )
13370 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013371 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013372 return -EINVAL;
13373 }
13374
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070013375 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
13376 {
13377 dump_bssid(pRoamInfo->bssid);
13378 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013379 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070013380 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013381#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013382 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013383}
13384#endif //FEATURE_WLAN_LFR
13385
Yue Maef608272013-04-08 23:09:17 -070013386#ifdef FEATURE_WLAN_LFR_METRICS
13387/*
13388 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
13389 * 802.11r/LFR metrics reporting function to report preauth initiation
13390 *
13391 */
13392#define MAX_LFR_METRICS_EVENT_LENGTH 100
13393VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
13394 tCsrRoamInfo *pRoamInfo)
13395{
13396 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
13397 union iwreq_data wrqu;
13398
13399 ENTER();
13400
13401 if (NULL == pAdapter)
13402 {
13403 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
13404 return VOS_STATUS_E_FAILURE;
13405 }
13406
13407 /* create the event */
13408 memset(&wrqu, 0, sizeof(wrqu));
13409 memset(metrics_notification, 0, sizeof(metrics_notification));
13410
13411 wrqu.data.pointer = metrics_notification;
13412 wrqu.data.length = scnprintf(metrics_notification,
13413 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
13414 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
13415
13416 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
13417
13418 EXIT();
13419
13420 return VOS_STATUS_SUCCESS;
13421}
13422
13423/*
13424 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
13425 * 802.11r/LFR metrics reporting function to report preauth completion
13426 * or failure
13427 */
13428VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
13429 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
13430{
13431 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
13432 union iwreq_data wrqu;
13433
13434 ENTER();
13435
13436 if (NULL == pAdapter)
13437 {
13438 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
13439 return VOS_STATUS_E_FAILURE;
13440 }
13441
13442 /* create the event */
13443 memset(&wrqu, 0, sizeof(wrqu));
13444 memset(metrics_notification, 0, sizeof(metrics_notification));
13445
13446 scnprintf(metrics_notification, sizeof(metrics_notification),
13447 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
13448 MAC_ADDR_ARRAY(pRoamInfo->bssid));
13449
13450 if (1 == preauth_status)
13451 strncat(metrics_notification, " TRUE", 5);
13452 else
13453 strncat(metrics_notification, " FALSE", 6);
13454
13455 wrqu.data.pointer = metrics_notification;
13456 wrqu.data.length = strlen(metrics_notification);
13457
13458 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
13459
13460 EXIT();
13461
13462 return VOS_STATUS_SUCCESS;
13463}
13464
13465/*
13466 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
13467 * 802.11r/LFR metrics reporting function to report handover initiation
13468 *
13469 */
13470VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
13471 tCsrRoamInfo *pRoamInfo)
13472{
13473 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
13474 union iwreq_data wrqu;
13475
13476 ENTER();
13477
13478 if (NULL == pAdapter)
13479 {
13480 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
13481 return VOS_STATUS_E_FAILURE;
13482 }
13483
13484 /* create the event */
13485 memset(&wrqu, 0, sizeof(wrqu));
13486 memset(metrics_notification, 0, sizeof(metrics_notification));
13487
13488 wrqu.data.pointer = metrics_notification;
13489 wrqu.data.length = scnprintf(metrics_notification,
13490 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
13491 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
13492
13493 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
13494
13495 EXIT();
13496
13497 return VOS_STATUS_SUCCESS;
13498}
13499#endif
13500
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013501
13502/**
13503 * wlan_hdd_cfg80211_validate_scan_req - validate scan request
13504 * @scan_req: scan request to be checked
13505 *
13506 * Return: true or false
13507 */
13508#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
13509static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
13510 cfg80211_scan_request
13511 *scan_req)
13512{
13513 if (!scan_req || !scan_req->wiphy) {
13514 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
13515 return false;
13516 }
13517 if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HDD, NULL)) {
13518 hddLog(VOS_TRACE_LEVEL_ERROR, "Load/Unload in progress");
13519 return false;
13520 }
13521 return true;
13522}
13523#else
13524static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
13525 cfg80211_scan_request
13526 *scan_req)
13527{
13528 if (!scan_req || !scan_req->wiphy) {
13529 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
13530 return false;
13531 }
13532 return true;
13533}
13534#endif
13535
13536
Jeff Johnson295189b2012-06-20 16:38:30 -070013537/*
13538 * FUNCTION: hdd_cfg80211_scan_done_callback
13539 * scanning callback function, called after finishing scan
13540 *
13541 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013542static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070013543 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
13544{
13545 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013546 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070013547 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013548 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070013549 struct cfg80211_scan_request *req = NULL;
13550 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053013551 bool aborted = false;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013552#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
13553 bool iface_down = false;
13554#endif
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013555 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013556 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013557 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013558
13559 ENTER();
13560
c_manjee1b4ab9a2016-10-26 11:36:55 +053013561 if (!pAdapter || pAdapter->magic != WLAN_HDD_ADAPTER_MAGIC ||
13562 !pAdapter->dev) {
13563 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Adapter is not valid"));
13564 return 0;
13565 }
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013566 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053013567 if (NULL == pHddCtx) {
13568 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013569 return 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013570 }
13571
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053013572#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
13573 if (!(pAdapter->dev->flags & IFF_UP))
13574 {
13575 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Interface is down"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013576 iface_down = true;
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053013577 }
13578#endif
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013579 pScanInfo = &pHddCtx->scan_info;
13580
Jeff Johnson295189b2012-06-20 16:38:30 -070013581 hddLog(VOS_TRACE_LEVEL_INFO,
13582 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080013583 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013584 __func__, halHandle, pContext, (int) scanId, (int) status);
13585
Kiet Lamac06e2c2013-10-23 16:25:07 +053013586 pScanInfo->mScanPendingCounter = 0;
13587
Jeff Johnson295189b2012-06-20 16:38:30 -070013588 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013589 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070013590 &pScanInfo->scan_req_completion_event,
13591 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013592 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070013593 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013594 hddLog(VOS_TRACE_LEVEL_ERROR,
13595 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070013596 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070013597 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070013598 }
13599
Yue Maef608272013-04-08 23:09:17 -070013600 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070013601 {
13602 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070013603 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070013604 }
13605
13606 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013607 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070013608 {
13609 hddLog(VOS_TRACE_LEVEL_INFO,
13610 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080013611 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070013612 (int) scanId);
13613 }
13614
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053013615#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013616 if (!iface_down)
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053013617#endif
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013618 {
13619 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
13620 pAdapter);
13621 if (0 > ret)
13622 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053013623 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013624
Jeff Johnson295189b2012-06-20 16:38:30 -070013625 /* If any client wait scan result through WEXT
13626 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013627 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070013628 {
13629 /* The other scan request waiting for current scan finish
13630 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013631 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070013632 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013633 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070013634 }
13635 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013636 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070013637 {
13638 struct net_device *dev = pAdapter->dev;
13639 union iwreq_data wrqu;
13640 int we_event;
13641 char *msg;
13642
13643 memset(&wrqu, '\0', sizeof(wrqu));
13644 we_event = SIOCGIWSCAN;
13645 msg = NULL;
13646 wireless_send_event(dev, we_event, &wrqu, msg);
13647 }
13648 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013649 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013650
13651 /* Get the Scan Req */
13652 req = pAdapter->request;
mukul sharmae7041822015-12-03 15:09:21 +053013653 pAdapter->request = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013654
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013655 /* Scan is no longer pending */
13656 pScanInfo->mScanPending = VOS_FALSE;
13657
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013658 if (!wlan_hdd_cfg80211_validate_scan_req(req))
Jeff Johnson295189b2012-06-20 16:38:30 -070013659 {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013660#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
13661 hddLog(VOS_TRACE_LEVEL_ERROR, FL("interface state %s"),
13662 iface_down ? "up" : "down");
13663#endif
13664
13665 if (pAdapter->dev) {
13666 hddLog(VOS_TRACE_LEVEL_ERROR, FL("device name %s"),
13667 pAdapter->dev->name);
13668 }
mukul sharmae7041822015-12-03 15:09:21 +053013669 complete(&pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -070013670 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070013671 }
13672
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013673 /* last_scan_timestamp is used to decide if new scan
13674 * is needed or not on station interface. If last station
13675 * scan time and new station scan time is less then
13676 * last_scan_timestamp ; driver will return cached scan.
13677 */
13678 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
13679 {
13680 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
13681
13682 if ( req->n_channels )
13683 {
13684 for (i = 0; i < req->n_channels ; i++ )
13685 {
13686 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
13687 }
13688 /* store no of channel scanned */
13689 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
13690 }
13691
13692 }
13693
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070013694 /*
13695 * cfg80211_scan_done informing NL80211 about completion
13696 * of scanning
13697 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053013698 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
13699 {
13700 aborted = true;
13701 }
mukul sharmae7041822015-12-03 15:09:21 +053013702
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013703#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
13704 if (!iface_down)
13705#endif
13706 cfg80211_scan_done(req, aborted);
mukul sharmae7041822015-12-03 15:09:21 +053013707
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080013708 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070013709
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013710allow_suspend:
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053013711 if ((pHddCtx->cfg_ini->enableMacSpoofing == MAC_ADDR_SPOOFING_FW_HOST_ENABLE
13712 ) && (pHddCtx->spoofMacAddr.isEnabled
13713 || pHddCtx->spoofMacAddr.isReqDeferred)) {
Siddharth Bhal76972212014-10-15 16:22:51 +053013714 /* Generate new random mac addr for next scan */
13715 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +053013716
13717 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
13718 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhal76972212014-10-15 16:22:51 +053013719 }
13720
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070013721 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013722 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070013723
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070013724 /* Acquire wakelock to handle the case where APP's tries to suspend
13725 * immediatly after the driver gets connect request(i.e after scan)
13726 * from supplicant, this result in app's is suspending and not able
13727 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013728 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070013729
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013730#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
13731 if (!iface_down)
13732#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070013733#ifdef FEATURE_WLAN_TDLS
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013734 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070013735#endif
13736
Jeff Johnson295189b2012-06-20 16:38:30 -070013737 EXIT();
13738 return 0;
13739}
13740
13741/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053013742 * FUNCTION: hdd_isConnectionInProgress
13743 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013744 *
13745 */
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013746v_BOOL_t hdd_isConnectionInProgress(hdd_context_t *pHddCtx, v_U8_t *session_id,
13747 scan_reject_states *reason)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013748{
13749 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
13750 hdd_station_ctx_t *pHddStaCtx = NULL;
13751 hdd_adapter_t *pAdapter = NULL;
13752 VOS_STATUS status = 0;
13753 v_U8_t staId = 0;
13754 v_U8_t *staMac = NULL;
13755
13756 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
13757
13758 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
13759 {
13760 pAdapter = pAdapterNode->pAdapter;
13761
13762 if( pAdapter )
13763 {
13764 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013765 "%s: Adapter with device mode %s (%d) exists",
13766 __func__, hdd_device_modetoString(pAdapter->device_mode),
13767 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013768 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053013769 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
13770 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
13771 (eConnectionState_Connecting ==
13772 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
13773 {
13774 hddLog(VOS_TRACE_LEVEL_ERROR,
13775 "%s: %p(%d) Connection is in progress", __func__,
13776 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013777 if (session_id && reason)
13778 {
13779 *session_id = pAdapter->sessionId;
13780 *reason = eHDD_CONNECTION_IN_PROGRESS;
13781 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053013782 return VOS_TRUE;
13783 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013784 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053013785 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013786 {
13787 hddLog(VOS_TRACE_LEVEL_ERROR,
13788 "%s: %p(%d) Reassociation is in progress", __func__,
13789 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013790 if (session_id && reason)
13791 {
13792 *session_id = pAdapter->sessionId;
13793 *reason = eHDD_REASSOC_IN_PROGRESS;
13794 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013795 return VOS_TRUE;
13796 }
13797 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013798 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
13799 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013800 {
13801 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13802 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013803 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013804 {
13805 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
13806 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080013807 "%s: client " MAC_ADDRESS_STR
13808 " is in the middle of WPS/EAPOL exchange.", __func__,
13809 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013810 if (session_id && reason)
13811 {
13812 *session_id = pAdapter->sessionId;
13813 *reason = eHDD_EAPOL_IN_PROGRESS;
13814 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053013815 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013816 }
13817 }
13818 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
13819 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
13820 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013821 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
13822 ptSapContext pSapCtx = NULL;
13823 pSapCtx = VOS_GET_SAP_CB(pVosContext);
13824 if(pSapCtx == NULL){
13825 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13826 FL("psapCtx is NULL"));
13827 return VOS_FALSE;
13828 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013829 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
13830 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013831 if ((pSapCtx->aStaInfo[staId].isUsed) &&
13832 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013833 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013834 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013835
13836 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080013837 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
13838 "middle of WPS/EAPOL exchange.", __func__,
13839 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013840 if (session_id && reason)
13841 {
13842 *session_id = pAdapter->sessionId;
13843 *reason = eHDD_SAP_EAPOL_IN_PROGRESS;
13844 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053013845 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013846 }
13847 }
13848 }
13849 }
13850 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13851 pAdapterNode = pNext;
13852 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053013853 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013854}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013855
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053013856/**
13857 * csr_scan_request_assign_bssid() - Set the BSSID received from Supplicant
13858 * to the Scan request
13859 * @scanRequest: Pointer to the csr scan request
13860 * @request: Pointer to the scan request from supplicant
13861 *
13862 * Return: None
13863 */
13864#ifdef CFG80211_SCAN_BSSID
13865static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
13866 struct cfg80211_scan_request *request)
13867{
13868 vos_mem_copy(scanRequest->bssid, request->bssid, VOS_MAC_ADDR_SIZE);
13869}
13870#else
13871static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
13872 struct cfg80211_scan_request *request)
13873{
13874}
13875#endif
13876
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013877/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013878 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070013879 * this scan respond to scan trigger and update cfg80211 scan database
13880 * later, scan dump command can be used to recieve scan results
13881 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013882int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080013883#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13884 struct net_device *dev,
13885#endif
13886 struct cfg80211_scan_request *request)
13887{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013888 hdd_adapter_t *pAdapter = NULL;
13889 hdd_context_t *pHddCtx = NULL;
13890 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013891 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013892 tCsrScanRequest scanRequest;
13893 tANI_U8 *channelList = NULL, i;
13894 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013895 int status;
13896 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013897 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013898 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053013899 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013900 bool is_p2p_scan = false;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013901 v_U8_t curr_session_id;
13902 scan_reject_states curr_reason;
Jeff Johnson295189b2012-06-20 16:38:30 -070013903
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013904#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
13905 struct net_device *dev = NULL;
13906 if (NULL == request)
13907 {
13908 hddLog(VOS_TRACE_LEVEL_ERROR,
13909 "%s: scan req param null", __func__);
13910 return -EINVAL;
13911 }
13912 dev = request->wdev->netdev;
13913#endif
13914
13915 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
13916 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
13917 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13918
Jeff Johnson295189b2012-06-20 16:38:30 -070013919 ENTER();
13920
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013921 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13922 __func__, hdd_device_modetoString(pAdapter->device_mode),
13923 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013924
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013925 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013926 if (0 != status)
13927 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013928 return status;
13929 }
13930
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013931 if (NULL == pwextBuf)
13932 {
13933 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
13934 __func__);
13935 return -EIO;
13936 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013937 cfg_param = pHddCtx->cfg_ini;
13938 pScanInfo = &pHddCtx->scan_info;
13939
Jeff Johnson295189b2012-06-20 16:38:30 -070013940#ifdef WLAN_BTAMP_FEATURE
13941 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013942 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070013943 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080013944 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013945 "%s: No scanning when AMP is on", __func__);
13946 return -EOPNOTSUPP;
13947 }
13948#endif
13949 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013950 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070013951 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013952 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013953 "%s: Not scanning on device_mode = %s (%d)",
13954 __func__, hdd_device_modetoString(pAdapter->device_mode),
13955 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013956 return -EOPNOTSUPP;
13957 }
13958
13959 if (TRUE == pScanInfo->mScanPending)
13960 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053013961 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
13962 {
13963 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
13964 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013965 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070013966 }
13967
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053013968 // Don't allow scan if PNO scan is going on.
13969 if (pHddCtx->isPnoEnable)
13970 {
13971 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13972 FL("pno scan in progress"));
13973 return -EBUSY;
13974 }
13975
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013976 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070013977 //Channel and action frame is pending
13978 //Otherwise Cancel Remain On Channel and allow Scan
13979 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013980 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070013981 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053013982 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070013983 return -EBUSY;
13984 }
13985
Jeff Johnson295189b2012-06-20 16:38:30 -070013986 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
13987 {
13988 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080013989 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013990 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013991 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013992 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
13993 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013994 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013995 "%s: MAX TM Level Scan not allowed", __func__);
13996 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013997 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070013998 }
13999 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
14000
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014001 /* Check if scan is allowed at this point of time.
14002 */
Hanumanth Reddy Pothulaec960842016-09-14 19:04:26 +053014003 if (TRUE == pHddCtx->btCoexModeSet)
14004 {
14005 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14006 FL("BTCoex Mode operation in progress"));
14007 return -EBUSY;
14008 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014009 if (hdd_isConnectionInProgress(pHddCtx, &curr_session_id, &curr_reason))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014010 {
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053014011 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Scan not allowed"));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014012 if (pHddCtx->last_scan_reject_session_id != curr_session_id ||
14013 pHddCtx->last_scan_reject_reason != curr_reason ||
14014 !pHddCtx->last_scan_reject_timestamp)
14015 {
14016 pHddCtx->last_scan_reject_session_id = curr_session_id;
14017 pHddCtx->last_scan_reject_reason = curr_reason;
Sreelakshmi Konamkif0646d52016-12-09 12:35:31 +053014018 pHddCtx->last_scan_reject_timestamp = jiffies_to_msecs(jiffies);
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053014019 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014020 else {
Sreelakshmi Konamkif0646d52016-12-09 12:35:31 +053014021 if ((jiffies_to_msecs(jiffies) -
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014022 pHddCtx->last_scan_reject_timestamp) >=
14023 SCAN_REJECT_THRESHOLD_TIME)
14024 {
14025 pHddCtx->last_scan_reject_timestamp = 0;
14026 if (pHddCtx->cfg_ini->enableFatalEvent)
14027 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
14028 WLAN_LOG_INDICATOR_HOST_DRIVER,
14029 WLAN_LOG_REASON_SCAN_NOT_ALLOWED,
14030 FALSE, FALSE);
14031 else
14032 {
14033 hddLog(LOGE, FL("Triggering SSR"));
14034 vos_wlanRestart();
14035 }
14036 }
14037 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014038 return -EBUSY;
14039 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014040 pHddCtx->last_scan_reject_timestamp = 0;
14041 pHddCtx->last_scan_reject_session_id = 0xFF;
14042 pHddCtx->last_scan_reject_reason = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014043
Jeff Johnson295189b2012-06-20 16:38:30 -070014044 vos_mem_zero( &scanRequest, sizeof(scanRequest));
14045
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014046 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
14047 * Becasue of this, driver is assuming that this is not wildcard scan and so
14048 * is not aging out the scan results.
14049 */
14050 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070014051 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014052 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014053 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014054
14055 if ((request->ssids) && (0 < request->n_ssids))
14056 {
14057 tCsrSSIDInfo *SsidInfo;
14058 int j;
14059 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
14060 /* Allocate num_ssid tCsrSSIDInfo structure */
14061 SsidInfo = scanRequest.SSIDs.SSIDList =
14062 ( tCsrSSIDInfo *)vos_mem_malloc(
14063 request->n_ssids*sizeof(tCsrSSIDInfo));
14064
14065 if(NULL == scanRequest.SSIDs.SSIDList)
14066 {
14067 hddLog(VOS_TRACE_LEVEL_ERROR,
14068 "%s: memory alloc failed SSIDInfo buffer", __func__);
14069 return -ENOMEM;
14070 }
14071
14072 /* copy all the ssid's and their length */
14073 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
14074 {
14075 /* get the ssid length */
14076 SsidInfo->SSID.length = request->ssids[j].ssid_len;
14077 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
14078 SsidInfo->SSID.length);
14079 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
14080 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
14081 j, SsidInfo->SSID.ssId);
14082 }
14083 /* set the scan type to active */
14084 scanRequest.scanType = eSIR_ACTIVE_SCAN;
14085 }
14086 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070014087 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053014088 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14089 TRACE_CODE_HDD_CFG80211_SCAN,
14090 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070014091 /* set the scan type to active */
14092 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070014093 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014094 else
14095 {
14096 /*Set the scan type to default type, in this case it is ACTIVE*/
14097 scanRequest.scanType = pScanInfo->scan_mode;
14098 }
14099 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
14100 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070014101
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053014102 csr_scan_request_assign_bssid(&scanRequest, request);
14103
Jeff Johnson295189b2012-06-20 16:38:30 -070014104 /* set BSSType to default type */
14105 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
14106
14107 /*TODO: scan the requested channels only*/
14108
14109 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014110 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070014111 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014112 hddLog(VOS_TRACE_LEVEL_WARN,
14113 "No of Scan Channels exceeded limit: %d", request->n_channels);
14114 request->n_channels = MAX_CHANNEL;
14115 }
14116
14117 hddLog(VOS_TRACE_LEVEL_INFO,
14118 "No of Scan Channels: %d", request->n_channels);
14119
14120
14121 if( request->n_channels )
14122 {
14123 char chList [(request->n_channels*5)+1];
14124 int len;
14125 channelList = vos_mem_malloc( request->n_channels );
14126 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053014127 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014128 hddLog(VOS_TRACE_LEVEL_ERROR,
14129 "%s: memory alloc failed channelList", __func__);
14130 status = -ENOMEM;
14131 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053014132 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014133
14134 for( i = 0, len = 0; i < request->n_channels ; i++ )
14135 {
14136 channelList[i] = request->channels[i]->hw_value;
14137 len += snprintf(chList+len, 5, "%d ", channelList[i]);
14138 }
14139
Nirav Shah20ac06f2013-12-12 18:14:06 +053014140 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014141 "Channel-List: %s ", chList);
14142 }
c_hpothu53512302014-04-15 18:49:53 +053014143
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014144 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
14145 scanRequest.ChannelInfo.ChannelList = channelList;
14146
14147 /* set requestType to full scan */
14148 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
14149
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014150 /* if there is back to back scan happening in driver with in
14151 * nDeferScanTimeInterval interval driver should defer new scan request
14152 * and should provide last cached scan results instead of new channel list.
14153 * This rule is not applicable if scan is p2p scan.
14154 * This condition will work only in case when last request no of channels
14155 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053014156 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053014157 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014158 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014159
Sushant Kaushik86592172015-04-27 16:35:03 +053014160 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
14161 /* if wps ie is NULL , then only defer scan */
14162 if ( pWpsIe == NULL &&
14163 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053014164 {
14165 if ( pScanInfo->last_scan_timestamp !=0 &&
14166 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
14167 {
14168 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
14169 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
14170 vos_mem_compare(pScanInfo->last_scan_channelList,
14171 channelList, pScanInfo->last_scan_numChannels))
14172 {
14173 hddLog(VOS_TRACE_LEVEL_WARN,
14174 " New and old station scan time differ is less then %u",
14175 pHddCtx->cfg_ini->nDeferScanTimeInterval);
14176
14177 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014178 pAdapter);
14179
Agarwal Ashish57e84372014-12-05 18:26:53 +053014180 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053014181 "Return old cached scan as all channels and no of channels are same");
14182
Agarwal Ashish57e84372014-12-05 18:26:53 +053014183 if (0 > ret)
14184 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014185
Agarwal Ashish57e84372014-12-05 18:26:53 +053014186 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053014187
14188 status = eHAL_STATUS_SUCCESS;
14189 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053014190 }
14191 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014192 }
14193
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014194 /* Flush the scan results(only p2p beacons) for STA scan and P2P
14195 * search (Flush on both full scan and social scan but not on single
14196 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
14197 */
14198
14199 /* Supplicant does single channel scan after 8-way handshake
14200 * and in that case driver shoudnt flush scan results. If
14201 * driver flushes the scan results here and unfortunately if
14202 * the AP doesnt respond to our probe req then association
14203 * fails which is not desired
14204 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053014205 if ((request->n_ssids == 1)
14206 && (request->ssids != NULL)
14207 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
14208 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014209
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053014210 if( is_p2p_scan ||
14211 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014212 {
14213 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
14214 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
14215 pAdapter->sessionId );
14216 }
14217
14218 if( request->ie_len )
14219 {
14220 /* save this for future association (join requires this) */
14221 /*TODO: Array needs to be converted to dynamic allocation,
14222 * as multiple ie.s can be sent in cfg80211_scan_request structure
14223 * CR 597966
14224 */
14225 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
14226 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
14227 pScanInfo->scanAddIE.length = request->ie_len;
14228
14229 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
14230 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
14231 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070014232 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014233 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070014234 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014235 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
14236 memcpy( pwextBuf->roamProfile.addIEScan,
14237 request->ie, request->ie_len);
14238 }
14239 else
14240 {
14241 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
14242 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070014243 }
14244
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014245 }
14246 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
14247 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
14248
14249 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
14250 request->ie_len);
14251 if (pP2pIe != NULL)
14252 {
14253#ifdef WLAN_FEATURE_P2P_DEBUG
14254 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
14255 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
14256 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053014257 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014258 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
14259 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
14260 "Go nego completed to Connection is started");
14261 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
14262 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053014263 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014264 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
14265 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070014266 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014267 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
14268 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
14269 "Disconnected state to Connection is started");
14270 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
14271 "for 4way Handshake");
14272 }
14273#endif
14274
14275 /* no_cck will be set during p2p find to disable 11b rates */
14276 if(TRUE == request->no_cck)
14277 {
14278 hddLog(VOS_TRACE_LEVEL_INFO,
14279 "%s: This is a P2P Search", __func__);
14280 scanRequest.p2pSearch = 1;
14281
14282 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053014283 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014284 /* set requestType to P2P Discovery */
14285 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
14286 }
14287
14288 /*
14289 Skip Dfs Channel in case of P2P Search
14290 if it is set in ini file
14291 */
14292 if(cfg_param->skipDfsChnlInP2pSearch)
14293 {
14294 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053014295 }
14296 else
14297 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014298 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053014299 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014300
Agarwal Ashish4f616132013-12-30 23:32:50 +053014301 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014302 }
14303 }
14304
14305 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
14306
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014307#ifdef FEATURE_WLAN_TDLS
14308 /* if tdls disagree scan right now, return immediately.
14309 tdls will schedule the scan when scan is allowed. (return SUCCESS)
14310 or will reject the scan if any TDLS is in progress. (return -EBUSY)
14311 */
14312 status = wlan_hdd_tdls_scan_callback (pAdapter,
14313 wiphy,
14314#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
14315 dev,
14316#endif
14317 request);
Abhishek Singhe2b63952016-01-05 18:27:29 +053014318 if (status <= 0)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014319 {
Abhishek Singhe2b63952016-01-05 18:27:29 +053014320 if (!status)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014321 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
14322 "scan rejected %d", __func__, status);
14323 else
14324 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
14325 __func__, status);
Abhishek Singhe2b63952016-01-05 18:27:29 +053014326 hdd_wlan_block_scan_by_tdls();
Gupta, Kapil2ebf3e02016-03-17 19:45:19 +053014327 goto free_mem;
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014328 }
14329#endif
14330
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070014331 /* acquire the wakelock to avoid the apps suspend during the scan. To
14332 * address the following issues.
14333 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
14334 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
14335 * for long time, this result in apps running at full power for long time.
14336 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
14337 * be stuck in full power because of resume BMPS
14338 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014339 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070014340
Nirav Shah20ac06f2013-12-12 18:14:06 +053014341 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
14342 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014343 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
14344 scanRequest.requestType, scanRequest.scanType,
14345 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053014346 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
14347
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053014348 if (pHddCtx->spoofMacAddr.isEnabled &&
14349 pHddCtx->cfg_ini->enableMacSpoofing == 1)
Siddharth Bhal76972212014-10-15 16:22:51 +053014350 {
14351 hddLog(VOS_TRACE_LEVEL_INFO,
14352 "%s: MAC Spoofing enabled for current scan", __func__);
14353 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
14354 * to fill TxBds for probe request during current scan
14355 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053014356 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053014357 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053014358
14359 if(status != VOS_STATUS_SUCCESS)
14360 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014361 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053014362 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053014363#ifdef FEATURE_WLAN_TDLS
14364 wlan_hdd_tdls_scan_done_callback(pAdapter);
14365#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053014366 goto free_mem;
14367 }
Siddharth Bhal76972212014-10-15 16:22:51 +053014368 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053014369 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070014370 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070014371 pAdapter->sessionId, &scanRequest, &scanId,
14372 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070014373
Jeff Johnson295189b2012-06-20 16:38:30 -070014374 if (eHAL_STATUS_SUCCESS != status)
14375 {
14376 hddLog(VOS_TRACE_LEVEL_ERROR,
14377 "%s: sme_ScanRequest returned error %d", __func__, status);
14378 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070014379 if(eHAL_STATUS_RESOURCES == status)
14380 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014381 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
14382 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070014383 status = -EBUSY;
14384 } else {
14385 status = -EIO;
14386 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014387 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014388
14389#ifdef FEATURE_WLAN_TDLS
14390 wlan_hdd_tdls_scan_done_callback(pAdapter);
14391#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014392 goto free_mem;
14393 }
14394
14395 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053014396 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070014397 pAdapter->request = request;
14398 pScanInfo->scanId = scanId;
14399
14400 complete(&pScanInfo->scan_req_completion_event);
14401
14402free_mem:
14403 if( scanRequest.SSIDs.SSIDList )
14404 {
14405 vos_mem_free(scanRequest.SSIDs.SSIDList);
14406 }
14407
14408 if( channelList )
14409 vos_mem_free( channelList );
14410
14411 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014412 return status;
14413}
14414
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014415int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
14416#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
14417 struct net_device *dev,
14418#endif
14419 struct cfg80211_scan_request *request)
14420{
14421 int ret;
14422
14423 vos_ssr_protect(__func__);
14424 ret = __wlan_hdd_cfg80211_scan(wiphy,
14425#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
14426 dev,
14427#endif
14428 request);
14429 vos_ssr_unprotect(__func__);
14430
14431 return ret;
14432}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014433
14434void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
14435{
14436 v_U8_t iniDot11Mode =
14437 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
14438 eHddDot11Mode hddDot11Mode = iniDot11Mode;
14439
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014440 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
14441 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014442 switch ( iniDot11Mode )
14443 {
14444 case eHDD_DOT11_MODE_AUTO:
14445 case eHDD_DOT11_MODE_11ac:
14446 case eHDD_DOT11_MODE_11ac_ONLY:
14447#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053014448 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
14449 sme_IsFeatureSupportedByFW(DOT11AC) )
14450 hddDot11Mode = eHDD_DOT11_MODE_11ac;
14451 else
14452 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014453#else
14454 hddDot11Mode = eHDD_DOT11_MODE_11n;
14455#endif
14456 break;
14457 case eHDD_DOT11_MODE_11n:
14458 case eHDD_DOT11_MODE_11n_ONLY:
14459 hddDot11Mode = eHDD_DOT11_MODE_11n;
14460 break;
14461 default:
14462 hddDot11Mode = iniDot11Mode;
14463 break;
14464 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053014465#ifdef WLAN_FEATURE_AP_HT40_24G
14466 if (operationChannel > SIR_11B_CHANNEL_END)
14467#endif
14468 {
14469 /* This call decides required channel bonding mode */
14470 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014471 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
14472 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053014473 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014474}
14475
Jeff Johnson295189b2012-06-20 16:38:30 -070014476/*
14477 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014478 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070014479 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014480int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053014481 const u8 *ssid, size_t ssid_len, const u8 *bssid,
14482 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070014483{
14484 int status = 0;
14485 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080014486 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014487 v_U32_t roamId;
14488 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070014489 eCsrAuthType RSNAuthType;
14490
14491 ENTER();
14492
14493 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080014494 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14495
14496 status = wlan_hdd_validate_context(pHddCtx);
14497 if (status)
14498 {
Yue Mae36e3552014-03-05 17:06:20 -080014499 return status;
14500 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014501
Jeff Johnson295189b2012-06-20 16:38:30 -070014502 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
14503 {
14504 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
14505 return -EINVAL;
14506 }
14507
Nitesh Shah9b066282017-06-06 18:05:52 +053014508 wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
14509
Jeff Johnson295189b2012-06-20 16:38:30 -070014510 pRoamProfile = &pWextState->roamProfile;
14511
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014512 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070014513 {
Jeff Johnsone7245742012-09-05 17:12:55 -070014514 hdd_station_ctx_t *pHddStaCtx;
14515 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Abhishek Singh6782c9e2017-06-06 13:37:45 +053014516 pHddStaCtx->get_mgmt_log_sent = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014517
Siddharth Bhalda0d1622015-04-24 15:47:49 +053014518 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
14519
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014520 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070014521 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
14522 {
14523 /*QoS not enabled in cfg file*/
14524 pRoamProfile->uapsd_mask = 0;
14525 }
14526 else
14527 {
14528 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014529 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070014530 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
14531 }
14532
14533 pRoamProfile->SSIDs.numOfSSIDs = 1;
14534 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
14535 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014536 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070014537 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
14538 ssid, ssid_len);
14539
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014540 vos_mem_zero(pRoamProfile->BSSIDs.bssid, WNI_CFG_BSSID_LEN);
14541 vos_mem_zero(pRoamProfile->bssid_hint, WNI_CFG_BSSID_LEN);
14542
Jeff Johnson295189b2012-06-20 16:38:30 -070014543 if (bssid)
14544 {
14545 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014546 vos_mem_copy(pRoamProfile->BSSIDs.bssid, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070014547 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014548 /* Save BSSID in seperate variable as well, as RoamProfile
14549 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070014550 case of join failure we should send valid BSSID to supplicant
14551 */
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014552 vos_mem_copy(pWextState->req_bssId, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070014553 WNI_CFG_BSSID_LEN);
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014554
Jeff Johnson295189b2012-06-20 16:38:30 -070014555 }
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014556 else if (bssid_hint)
Dhanashri Atre51981c62013-06-13 11:47:57 -070014557 {
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014558 /* Store bssid_hint to use in the scan filter. */
14559 vos_mem_copy(pRoamProfile->bssid_hint, bssid_hint,
14560 WNI_CFG_BSSID_LEN);
14561 /*
14562 * Save BSSID in seperate variable as well, as RoamProfile
14563 * BSSID is getting zeroed out in the association process. And in
14564 * case of join failure we should send valid BSSID to supplicant
14565 */
14566 vos_mem_copy(pWextState->req_bssId, bssid_hint,
14567 WNI_CFG_BSSID_LEN);
14568 hddLog(LOG1, FL(" bssid_hint: "MAC_ADDRESS_STR),
14569 MAC_ADDR_ARRAY(pRoamProfile->bssid_hint));
Dhanashri Atre51981c62013-06-13 11:47:57 -070014570 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014571
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014572
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014573 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
14574 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070014575 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
14576 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014577 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014578 /*set gen ie*/
14579 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
14580 /*set auth*/
14581 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
14582 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014583#ifdef FEATURE_WLAN_WAPI
14584 if (pAdapter->wapi_info.nWapiMode)
14585 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014586 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014587 switch (pAdapter->wapi_info.wapiAuthMode)
14588 {
14589 case WAPI_AUTH_MODE_PSK:
14590 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014591 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014592 pAdapter->wapi_info.wapiAuthMode);
14593 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
14594 break;
14595 }
14596 case WAPI_AUTH_MODE_CERT:
14597 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014598 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014599 pAdapter->wapi_info.wapiAuthMode);
14600 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
14601 break;
14602 }
14603 } // End of switch
14604 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
14605 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
14606 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014607 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014608 pRoamProfile->AuthType.numEntries = 1;
14609 pRoamProfile->EncryptionType.numEntries = 1;
14610 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
14611 pRoamProfile->mcEncryptionType.numEntries = 1;
14612 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
14613 }
14614 }
14615#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014616#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014617 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014618 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
14619 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
14620 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014621 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
14622 sizeof (tSirGtkOffloadParams));
14623 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014624 }
14625#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014626 pRoamProfile->csrPersona = pAdapter->device_mode;
14627
Jeff Johnson32d95a32012-09-10 13:15:23 -070014628 if( operatingChannel )
14629 {
14630 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
14631 pRoamProfile->ChannelInfo.numOfChannels = 1;
14632 }
Chet Lanctot186b5732013-03-18 10:26:30 -070014633 else
14634 {
14635 pRoamProfile->ChannelInfo.ChannelList = NULL;
14636 pRoamProfile->ChannelInfo.numOfChannels = 0;
14637 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014638 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
14639 {
14640 hdd_select_cbmode(pAdapter,operatingChannel);
14641 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014642
Agarwal Ashish40f9b872015-09-01 16:17:35 +053014643 /*
14644 * Change conn_state to connecting before sme_RoamConnect(),
14645 * because sme_RoamConnect() has a direct path to call
14646 * hdd_smeRoamCallback(), which will change the conn_state
14647 * If direct path, conn_state will be accordingly changed
14648 * to NotConnected or Associated by either
14649 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
14650 * in sme_RoamCallback()
14651 * if sme_RomConnect is to be queued,
14652 * Connecting state will remain until it is completed.
14653 * If connection state is not changed,
14654 * connection state will remain in eConnectionState_NotConnected state.
14655 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
14656 * if conn state is eConnectionState_NotConnected.
14657 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
14658 * informed of connect result indication which is an issue.
14659 */
14660
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053014661 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
14662 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053014663 {
14664 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053014665 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080014666 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
14667 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053014668 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014669 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070014670 pAdapter->sessionId, pRoamProfile, &roamId);
14671
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053014672 if ((eHAL_STATUS_SUCCESS != status) &&
14673 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
14674 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053014675
14676 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053014677 hddLog(VOS_TRACE_LEVEL_ERROR,
14678 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
14679 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080014680 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053014681 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080014682 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053014683 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080014684
14685 pRoamProfile->ChannelInfo.ChannelList = NULL;
14686 pRoamProfile->ChannelInfo.numOfChannels = 0;
14687
Jeff Johnson295189b2012-06-20 16:38:30 -070014688 }
14689 else
14690 {
14691 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
14692 return -EINVAL;
14693 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080014694 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014695 return status;
14696}
14697
14698/*
14699 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
14700 * This function is used to set the authentication type (OPEN/SHARED).
14701 *
14702 */
14703static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
14704 enum nl80211_auth_type auth_type)
14705{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014706 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014707 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14708
14709 ENTER();
14710
14711 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014712 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070014713 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014714 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053014715 hddLog(VOS_TRACE_LEVEL_INFO,
14716 "%s: set authentication type to AUTOSWITCH", __func__);
14717 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
14718 break;
14719
14720 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014721#ifdef WLAN_FEATURE_VOWIFI_11R
14722 case NL80211_AUTHTYPE_FT:
14723#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014724 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070014725 "%s: set authentication type to OPEN", __func__);
14726 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
14727 break;
14728
14729 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014730 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070014731 "%s: set authentication type to SHARED", __func__);
14732 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
14733 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080014734#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070014735 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014736 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070014737 "%s: set authentication type to CCKM WPA", __func__);
14738 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
14739 break;
14740#endif
14741
14742
14743 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014744 hddLog(VOS_TRACE_LEVEL_ERROR,
14745 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014746 auth_type);
14747 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
14748 return -EINVAL;
14749 }
14750
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014751 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070014752 pHddStaCtx->conn_info.authType;
14753 return 0;
14754}
14755
14756/*
14757 * FUNCTION: wlan_hdd_set_akm_suite
14758 * This function is used to set the key mgmt type(PSK/8021x).
14759 *
14760 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014761static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014762 u32 key_mgmt
14763 )
14764{
14765 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
14766 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053014767 /* Should be in ieee802_11_defs.h */
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053014768#ifndef WLAN_AKM_SUITE_8021X_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053014769#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053014770#endif
14771#ifndef WLAN_AKM_SUITE_PSK_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053014772#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053014773#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014774 /*set key mgmt type*/
14775 switch(key_mgmt)
14776 {
14777 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053014778 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053014779#ifdef WLAN_FEATURE_VOWIFI_11R
14780 case WLAN_AKM_SUITE_FT_PSK:
14781#endif
14782 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070014783 __func__);
14784 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
14785 break;
14786
14787 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053014788 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053014789#ifdef WLAN_FEATURE_VOWIFI_11R
14790 case WLAN_AKM_SUITE_FT_8021X:
14791#endif
14792 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070014793 __func__);
14794 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
14795 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080014796#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070014797#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
14798#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
14799 case WLAN_AKM_SUITE_CCKM:
14800 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
14801 __func__);
14802 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
14803 break;
14804#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070014805#ifndef WLAN_AKM_SUITE_OSEN
14806#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
14807 case WLAN_AKM_SUITE_OSEN:
14808 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
14809 __func__);
14810 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
14811 break;
14812#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014813
14814 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014815 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014816 __func__, key_mgmt);
14817 return -EINVAL;
14818
14819 }
14820 return 0;
14821}
14822
14823/*
14824 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014825 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070014826 * (NONE/WEP40/WEP104/TKIP/CCMP).
14827 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014828static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
14829 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070014830 bool ucast
14831 )
14832{
14833 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014834 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014835 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14836
14837 ENTER();
14838
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014839 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070014840 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053014841 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070014842 __func__, cipher);
14843 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
14844 }
14845 else
14846 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014847
Jeff Johnson295189b2012-06-20 16:38:30 -070014848 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014849 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070014850 {
14851 case IW_AUTH_CIPHER_NONE:
14852 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
14853 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014854
Jeff Johnson295189b2012-06-20 16:38:30 -070014855 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053014856 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070014857 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014858
Jeff Johnson295189b2012-06-20 16:38:30 -070014859 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053014860 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070014861 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014862
Jeff Johnson295189b2012-06-20 16:38:30 -070014863 case WLAN_CIPHER_SUITE_TKIP:
14864 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
14865 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014866
Jeff Johnson295189b2012-06-20 16:38:30 -070014867 case WLAN_CIPHER_SUITE_CCMP:
14868 encryptionType = eCSR_ENCRYPT_TYPE_AES;
14869 break;
14870#ifdef FEATURE_WLAN_WAPI
14871 case WLAN_CIPHER_SUITE_SMS4:
14872 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
14873 break;
14874#endif
14875
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080014876#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070014877 case WLAN_CIPHER_SUITE_KRK:
14878 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
14879 break;
14880#endif
14881 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014882 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014883 __func__, cipher);
14884 return -EOPNOTSUPP;
14885 }
14886 }
14887
14888 if (ucast)
14889 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014890 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014891 __func__, encryptionType);
14892 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
14893 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014894 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070014895 encryptionType;
14896 }
14897 else
14898 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014899 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014900 __func__, encryptionType);
14901 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
14902 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
14903 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
14904 }
14905
14906 return 0;
14907}
14908
14909
14910/*
14911 * FUNCTION: wlan_hdd_cfg80211_set_ie
14912 * This function is used to parse WPA/RSN IE's.
14913 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014914int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014915#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14916 const u8 *ie,
14917#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014918 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014919#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014920 size_t ie_len
14921 )
14922{
14923 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014924#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14925 const u8 *genie = ie;
14926#else
Jeff Johnson295189b2012-06-20 16:38:30 -070014927 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014928#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014929 v_U16_t remLen = ie_len;
14930#ifdef FEATURE_WLAN_WAPI
14931 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
14932 u16 *tmp;
14933 v_U16_t akmsuiteCount;
14934 int *akmlist;
14935#endif
14936 ENTER();
14937
14938 /* clear previous assocAddIE */
14939 pWextState->assocAddIE.length = 0;
14940 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070014941 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014942
14943 while (remLen >= 2)
14944 {
14945 v_U16_t eLen = 0;
14946 v_U8_t elementId;
14947 elementId = *genie++;
14948 eLen = *genie++;
14949 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014950
Nachiket Kukade4aba5f02017-06-09 15:43:48 +053014951 /* Sanity check on eLen */
14952 if (eLen > remLen) {
14953 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid IE length[%d] for IE[0x%X]",
14954 __func__, eLen, elementId);
14955 VOS_ASSERT(0);
14956 return -EINVAL;
14957 }
14958
Arif Hussain6d2a3322013-11-17 19:50:10 -080014959 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070014960 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014961
14962 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070014963 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014964 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014965 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 -070014966 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014967 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014968 "%s: Invalid WPA IE", __func__);
14969 return -EINVAL;
14970 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014971 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070014972 {
14973 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014974 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070014975 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014976
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014977 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070014978 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014979 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
14980 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070014981 VOS_ASSERT(0);
14982 return -ENOMEM;
14983 }
14984 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
14985 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14986 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014987
Jeff Johnson295189b2012-06-20 16:38:30 -070014988 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
14989 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14990 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14991 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014992 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
14993 {
Nachiket Kukade3d72b7e2017-06-09 16:58:24 +053014994 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
14995 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d]",
14996 __func__, eLen);
14997 VOS_ASSERT(0);
14998 return -EINVAL;
14999 }
15000
Jeff Johnson295189b2012-06-20 16:38:30 -070015001 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
15002 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
15003 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
15004 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
15005 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
15006 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015007 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053015008 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070015009 {
15010 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015011 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070015012 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015013
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015014 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015015 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015016 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15017 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070015018 VOS_ASSERT(0);
15019 return -ENOMEM;
15020 }
15021 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
15022 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15023 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015024
Jeff Johnson295189b2012-06-20 16:38:30 -070015025 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15026 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15027 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015028#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015029 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
15030 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015031 /*Consider WFD IE, only for P2P Client */
15032 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
15033 {
15034 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015035 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070015036 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015037
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015038 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015039 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015040 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15041 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070015042 VOS_ASSERT(0);
15043 return -ENOMEM;
15044 }
15045 // WFD IE is saved to Additional IE ; it should be accumulated to handle
15046 // WPS IE + P2P IE + WFD IE
15047 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15048 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015049
Jeff Johnson295189b2012-06-20 16:38:30 -070015050 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15051 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15052 }
15053#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015054 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015055 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015056 HS20_OUI_TYPE_SIZE)) )
15057 {
15058 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015059 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015060 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015061
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015062 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015063 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015064 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15065 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015066 VOS_ASSERT(0);
15067 return -ENOMEM;
15068 }
15069 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15070 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015071
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015072 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15073 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15074 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070015075 /* Appending OSEN Information Element in Assiciation Request */
15076 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
15077 OSEN_OUI_TYPE_SIZE)) )
15078 {
15079 v_U16_t curAddIELen = pWextState->assocAddIE.length;
15080 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
15081 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015082
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015083 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070015084 {
15085 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15086 "Need bigger buffer space");
15087 VOS_ASSERT(0);
15088 return -ENOMEM;
15089 }
15090 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15091 pWextState->assocAddIE.length += eLen + 2;
15092
15093 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
15094 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15095 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15096 }
15097
Abhishek Singh4322e622015-06-10 15:42:54 +053015098 /* Update only for WPA IE */
15099 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
15100 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070015101
15102 /* populating as ADDIE in beacon frames */
15103 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015104 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070015105 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
15106 {
15107 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
15108 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
15109 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
15110 {
15111 hddLog(LOGE,
15112 "Coldn't pass "
15113 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
15114 }
15115 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
15116 else
15117 hddLog(LOGE,
15118 "Could not pass on "
15119 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
15120
15121 /* IBSS mode doesn't contain params->proberesp_ies still
15122 beaconIE's need to be populated in probe response frames */
15123 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
15124 {
15125 u16 rem_probe_resp_ie_len = eLen + 2;
15126 u8 probe_rsp_ie_len[3] = {0};
15127 u8 counter = 0;
15128
15129 /* Check Probe Resp Length if it is greater then 255 then
15130 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
15131 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
15132 not able Store More then 255 bytes into One Variable */
15133
15134 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
15135 {
15136 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
15137 {
15138 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
15139 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
15140 }
15141 else
15142 {
15143 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
15144 rem_probe_resp_ie_len = 0;
15145 }
15146 }
15147
15148 rem_probe_resp_ie_len = 0;
15149
15150 if (probe_rsp_ie_len[0] > 0)
15151 {
15152 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
15153 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
15154 (tANI_U8*)(genie - 2),
15155 probe_rsp_ie_len[0], NULL,
15156 eANI_BOOLEAN_FALSE)
15157 == eHAL_STATUS_FAILURE)
15158 {
15159 hddLog(LOGE,
15160 "Could not pass"
15161 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
15162 }
15163 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
15164 }
15165
15166 if (probe_rsp_ie_len[1] > 0)
15167 {
15168 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
15169 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
15170 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
15171 probe_rsp_ie_len[1], NULL,
15172 eANI_BOOLEAN_FALSE)
15173 == eHAL_STATUS_FAILURE)
15174 {
15175 hddLog(LOGE,
15176 "Could not pass"
15177 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
15178 }
15179 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
15180 }
15181
15182 if (probe_rsp_ie_len[2] > 0)
15183 {
15184 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
15185 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
15186 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
15187 probe_rsp_ie_len[2], NULL,
15188 eANI_BOOLEAN_FALSE)
15189 == eHAL_STATUS_FAILURE)
15190 {
15191 hddLog(LOGE,
15192 "Could not pass"
15193 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
15194 }
15195 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
15196 }
15197
15198 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
15199 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
15200 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
15201 {
15202 hddLog(LOGE,
15203 "Could not pass"
15204 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
15205 }
15206 }
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070015207 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070015208 break;
15209 case DOT11F_EID_RSN:
15210 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
15211 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
15212 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
15213 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
15214 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
15215 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053015216
Abhishek Singhb16f3562016-01-20 11:08:32 +053015217 /* Appending extended capabilities with Interworking or
15218 * bsstransition bit set in Assoc Req.
Abhishek Singh15d95602015-03-24 15:52:57 +053015219 *
15220 * In assoc req this EXT Cap will only be taken into account if
Abhishek Singhb16f3562016-01-20 11:08:32 +053015221 * interworkingService or bsstransition bit is set to 1.
15222 * Driver is only interested in interworkingService and
15223 * bsstransition capability from supplicant.
15224 * If in future any other EXT Cap info is
Abhishek Singh15d95602015-03-24 15:52:57 +053015225 * required from supplicat, it needs to be handled while
15226 * sending Assoc Req in LIM.
15227 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015228 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015229 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015230 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015231 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015232 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015233
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015234 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015235 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015236 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15237 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015238 VOS_ASSERT(0);
15239 return -ENOMEM;
15240 }
15241 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15242 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015243
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015244 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15245 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15246 break;
15247 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015248#ifdef FEATURE_WLAN_WAPI
15249 case WLAN_EID_WAPI:
15250 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070015251 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070015252 pAdapter->wapi_info.nWapiMode);
15253 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015254 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070015255 akmsuiteCount = WPA_GET_LE16(tmp);
15256 tmp = tmp + 1;
15257 akmlist = (int *)(tmp);
15258 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
15259 {
15260 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
15261 }
15262 else
15263 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015264 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070015265 VOS_ASSERT(0);
15266 return -EINVAL;
15267 }
15268
15269 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
15270 {
15271 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015272 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015273 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015274 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015275 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015276 {
Jeff Johnson295189b2012-06-20 16:38:30 -070015277 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015278 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015279 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
15280 }
15281 break;
15282#endif
15283 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015284 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015285 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015286 /* when Unknown IE is received we should break and continue
15287 * to the next IE in the buffer instead we were returning
15288 * so changing this to break */
15289 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070015290 }
15291 genie += eLen;
15292 remLen -= eLen;
15293 }
15294 EXIT();
15295 return 0;
15296}
15297
15298/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053015299 * FUNCTION: hdd_isWPAIEPresent
15300 * Parse the received IE to find the WPA IE
15301 *
15302 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015303static bool hdd_isWPAIEPresent(
15304#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
15305 const u8 *ie,
15306#else
15307 u8 *ie,
15308#endif
15309 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053015310{
15311 v_U8_t eLen = 0;
15312 v_U16_t remLen = ie_len;
15313 v_U8_t elementId = 0;
15314
15315 while (remLen >= 2)
15316 {
15317 elementId = *ie++;
15318 eLen = *ie++;
15319 remLen -= 2;
15320 if (eLen > remLen)
15321 {
15322 hddLog(VOS_TRACE_LEVEL_ERROR,
15323 "%s: IE length is wrong %d", __func__, eLen);
15324 return FALSE;
15325 }
15326 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
15327 {
15328 /* OUI - 0x00 0X50 0XF2
15329 WPA Information Element - 0x01
15330 WPA version - 0x01*/
15331 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
15332 return TRUE;
15333 }
15334 ie += eLen;
15335 remLen -= eLen;
15336 }
15337 return FALSE;
15338}
15339
15340/*
Jeff Johnson295189b2012-06-20 16:38:30 -070015341 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015342 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070015343 * parameters during connect operation.
15344 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015345int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070015346 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015347 )
Jeff Johnson295189b2012-06-20 16:38:30 -070015348{
15349 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015350 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070015351 ENTER();
15352
15353 /*set wpa version*/
15354 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
15355
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015356 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070015357 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053015358 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070015359 {
15360 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
15361 }
15362 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
15363 {
15364 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
15365 }
15366 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015367
15368 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015369 pWextState->wpaVersion);
15370
15371 /*set authentication type*/
15372 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
15373
15374 if (0 > status)
15375 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015376 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015377 "%s: failed to set authentication type ", __func__);
15378 return status;
15379 }
15380
15381 /*set key mgmt type*/
15382 if (req->crypto.n_akm_suites)
15383 {
15384 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
15385 if (0 > status)
15386 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015387 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070015388 __func__);
15389 return status;
15390 }
15391 }
15392
15393 /*set pairwise cipher type*/
15394 if (req->crypto.n_ciphers_pairwise)
15395 {
15396 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
15397 req->crypto.ciphers_pairwise[0], true);
15398 if (0 > status)
15399 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015400 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015401 "%s: failed to set unicast cipher type", __func__);
15402 return status;
15403 }
15404 }
15405 else
15406 {
15407 /*Reset previous cipher suite to none*/
15408 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
15409 if (0 > status)
15410 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015411 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015412 "%s: failed to set unicast cipher type", __func__);
15413 return status;
15414 }
15415 }
15416
15417 /*set group cipher type*/
15418 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
15419 false);
15420
15421 if (0 > status)
15422 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015423 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070015424 __func__);
15425 return status;
15426 }
15427
Chet Lanctot186b5732013-03-18 10:26:30 -070015428#ifdef WLAN_FEATURE_11W
15429 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
15430#endif
15431
Jeff Johnson295189b2012-06-20 16:38:30 -070015432 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
15433 if (req->ie_len)
15434 {
15435 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
15436 if ( 0 > status)
15437 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015438 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070015439 __func__);
15440 return status;
15441 }
15442 }
15443
15444 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015445 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070015446 {
15447 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
15448 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
15449 )
15450 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015451 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070015452 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
15453 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015454 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070015455 __func__);
15456 return -EOPNOTSUPP;
15457 }
15458 else
15459 {
15460 u8 key_len = req->key_len;
15461 u8 key_idx = req->key_idx;
15462
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015463 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070015464 && (CSR_MAX_NUM_KEY > key_idx)
15465 )
15466 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015467 hddLog(VOS_TRACE_LEVEL_INFO,
15468 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015469 __func__, key_idx, key_len);
15470 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015471 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070015472 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015473 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070015474 (u8)key_len;
15475 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
15476 }
15477 }
15478 }
15479 }
15480
15481 return status;
15482}
15483
15484/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015485 * FUNCTION: wlan_hdd_try_disconnect
15486 * This function is used to disconnect from previous
15487 * connection
15488 */
Agrawal Ashishc407f192017-01-23 17:18:35 +053015489int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015490{
15491 long ret = 0;
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015492 int status, result = 0;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015493 hdd_station_ctx_t *pHddStaCtx;
15494 eMib_dot11DesiredBssType connectedBssType;
Abhishek Singh19a7dd92015-12-30 16:31:51 +053015495 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015496
Abhishek Singh19a7dd92015-12-30 16:31:51 +053015497 ret = wlan_hdd_validate_context(pHddCtx);
15498 if (0 != ret)
15499 {
15500 return ret;
15501 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015502 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15503
15504 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
15505
15506 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
15507 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
Abhishek Singh630ff592016-01-07 18:15:53 +053015508 (eConnectionState_Connecting == pHddStaCtx->conn_info.connState) ||
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015509 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
15510 {
Abhishek Singh9f4df782017-03-15 17:29:10 +053015511 /* Indicate disconnect to SME so that in-progress connection or preauth
15512 * can be aborted
15513 */
15514 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
15515 pAdapter->sessionId);
Abhishek Singh19a7dd92015-12-30 16:31:51 +053015516 spin_lock_bh(&pAdapter->lock_for_active_session);
15517 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
15518 {
15519 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
15520 }
15521 spin_unlock_bh(&pAdapter->lock_for_active_session);
Abhishek Singhf7962582015-10-23 10:54:06 +053015522 hdd_connSetConnectionState(pHddStaCtx,
15523 eConnectionState_Disconnecting);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015524 /* Issue disconnect to CSR */
15525 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015526 status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015527 pAdapter->sessionId,
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015528 eCSR_DISCONNECT_REASON_UNSPECIFIED);
15529 if(eHAL_STATUS_CMD_NOT_QUEUED == status) {
15530 hddLog(LOG1,
15531 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
15532 } else if ( 0 != status ) {
15533 hddLog(LOGE,
15534 FL("csrRoamDisconnect failure, returned %d"),
15535 (int)status );
15536 result = -EINVAL;
15537 goto disconnected;
15538 }
15539 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015540 &pAdapter->disconnect_comp_var,
15541 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015542 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status)) {
15543 hddLog(LOGE,
15544 "%s: Failed to disconnect, timed out", __func__);
15545 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015546 }
15547 }
15548 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
15549 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015550 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015551 &pAdapter->disconnect_comp_var,
15552 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015553 if (!ret)
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015554 {
15555 hddLog(LOGE, FL("Failed to receive disconnect event"));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015556 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015557 }
15558 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015559disconnected:
15560 hddLog(LOG1,
15561 FL("Set HDD connState to eConnectionState_NotConnected"));
15562 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
15563 return result;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015564}
15565
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053015566/**
15567 * wlan_hdd_reassoc_bssid_hint() - Start reassociation if bssid is present
15568 * @adapter: Pointer to the HDD adapter
15569 * @req: Pointer to the structure cfg_connect_params receieved from user space
15570 *
15571 * This function will start reassociation if bssid hint, channel hint and
15572 * previous bssid parameters are present in the connect request
15573 *
15574 * Return: success if reassociation is happening
15575 * Error code if reassociation is not permitted or not happening
15576 */
15577#ifdef CFG80211_CONNECT_PREV_BSSID
15578static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
15579 struct cfg80211_connect_params *req)
15580{
15581 int status = -EPERM;
15582 if (req->bssid_hint && req->channel_hint && req->prev_bssid) {
15583 hddLog(VOS_TRACE_LEVEL_INFO,
15584 FL("REASSOC Attempt on channel %d to "MAC_ADDRESS_STR),
15585 req->channel_hint->hw_value,
15586 MAC_ADDR_ARRAY(req->bssid_hint));
15587 status = hdd_reassoc(adapter, req->bssid_hint,
15588 req->channel_hint->hw_value,
15589 CONNECT_CMD_USERSPACE);
15590 }
15591 return status;
15592}
15593#else
15594static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
15595 struct cfg80211_connect_params *req)
15596{
15597 return -EPERM;
15598}
15599#endif
15600
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015601/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053015602 * FUNCTION: __wlan_hdd_cfg80211_connect
15603 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070015604 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015605static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015606 struct net_device *ndev,
15607 struct cfg80211_connect_params *req
15608 )
15609{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015610 int status;
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053015611 u16 channel;
Edhar, Mahesh Kumar496c7f72016-03-18 12:47:44 +053015612#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) || \
15613 defined(CFG80211_BSSID_HINT_BACKPORT)
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053015614 const u8 *bssid_hint = req->bssid_hint;
15615#else
15616 const u8 *bssid_hint = NULL;
15617#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015618 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070015619 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053015620 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015621
15622 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015623
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015624 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15625 TRACE_CODE_HDD_CFG80211_CONNECT,
15626 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015627 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015628 "%s: device_mode = %s (%d)", __func__,
15629 hdd_device_modetoString(pAdapter->device_mode),
15630 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015631
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015632 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080015633 if (!pHddCtx)
15634 {
15635 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15636 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053015637 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080015638 }
15639
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015640 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015641 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070015642 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015643 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015644 }
15645
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053015646 status = wlan_hdd_reassoc_bssid_hint(pAdapter, req);
15647 if (0 == status)
15648 return status;
15649
Agarwal Ashish51325b52014-06-16 16:50:49 +053015650
Jeff Johnson295189b2012-06-20 16:38:30 -070015651#ifdef WLAN_BTAMP_FEATURE
15652 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015653 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070015654 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015655 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015656 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080015657 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070015658 }
15659#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015660
15661 //If Device Mode is Station Concurrent Sessions Exit BMps
15662 //P2P Mode will be taken care in Open/close adapter
15663 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053015664 (vos_concurrent_open_sessions_running())) {
15665 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
15666 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015667 }
15668
15669 /*Try disconnecting if already in connected state*/
15670 status = wlan_hdd_try_disconnect(pAdapter);
15671 if ( 0 > status)
15672 {
15673 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
15674 " connection"));
15675 return -EALREADY;
15676 }
Agrawal Ashish559530c2015-12-01 18:04:20 +053015677 /* Check for max concurrent connections after doing disconnect if any*/
15678 if (vos_max_concurrent_connections_reached()) {
15679 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
15680 return -ECONNREFUSED;
15681 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015682
Jeff Johnson295189b2012-06-20 16:38:30 -070015683 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015684 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070015685
15686 if ( 0 > status)
15687 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015688 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070015689 __func__);
15690 return status;
15691 }
Sravan Kumar Kairam589c5722016-01-27 20:28:53 +053015692
15693 if (pHddCtx->spoofMacAddr.isEnabled)
15694 {
15695 hddLog(VOS_TRACE_LEVEL_INFO,
15696 "%s: MAC Spoofing enabled ", __func__);
15697 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
15698 * to fill TxBds for probe request during SSID scan which may happen
15699 * as part of connect command
15700 */
15701 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
15702 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
15703 if (status != VOS_STATUS_SUCCESS)
15704 return -ECONNREFUSED;
15705 }
15706
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053015707 if (req->channel)
15708 channel = req->channel->hw_value;
Mohit Khanna765234a2012-09-11 15:08:35 -070015709 else
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053015710 channel = 0;
Kapil Gupta312028a2016-10-25 14:15:20 +053015711
15712 /* Abort if any scan is going on */
15713 status = wlan_hdd_scan_abort(pAdapter);
15714 if (0 != status)
15715 hddLog(VOS_TRACE_LEVEL_ERROR, FL("scan abort failed"));
15716
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053015717 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
15718 req->ssid_len, req->bssid,
15719 bssid_hint, channel);
Jeff Johnson295189b2012-06-20 16:38:30 -070015720
Sushant Kaushikd7083982015-03-18 14:33:24 +053015721 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070015722 {
15723 //ReEnable BMPS if disabled
15724 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
15725 (NULL != pHddCtx))
15726 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053015727 if (pHddCtx->hdd_wlan_suspended)
15728 {
15729 hdd_set_pwrparams(pHddCtx);
15730 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015731 //ReEnable Bmps and Imps back
15732 hdd_enable_bmps_imps(pHddCtx);
15733 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053015734 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070015735 return status;
15736 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015737 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015738 EXIT();
15739 return status;
15740}
15741
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015742static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
15743 struct net_device *ndev,
15744 struct cfg80211_connect_params *req)
15745{
15746 int ret;
15747 vos_ssr_protect(__func__);
15748 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
15749 vos_ssr_unprotect(__func__);
15750
15751 return ret;
15752}
Jeff Johnson295189b2012-06-20 16:38:30 -070015753
15754/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015755 * FUNCTION: wlan_hdd_disconnect
15756 * This function is used to issue a disconnect request to SME
15757 */
15758int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
15759{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015760 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015761 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015762 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053015763 long ret;
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053015764 eConnectionState prev_conn_state;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015765
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015766 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015767
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015768 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015769 if (0 != status)
15770 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015771 return status;
15772 }
Abhishek Singh07e4a892015-11-23 11:29:57 +053015773 /* Indicate sme of disconnect so that in progress connection or preauth
15774 * can be aborted
15775 */
15776 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
Sushant Kaushikb4834d22015-07-15 15:29:05 +053015777 pAdapter->sessionId);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015778 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053015779
Agarwal Ashish47d18112014-08-04 19:55:07 +053015780 /* Need to apply spin lock before decreasing active sessions
15781 * as there can be chance for double decrement if context switch
15782 * Calls hdd_DisConnectHandler.
15783 */
15784
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053015785 prev_conn_state = pHddStaCtx->conn_info.connState;
15786
Agarwal Ashish47d18112014-08-04 19:55:07 +053015787 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053015788 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
15789 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053015790 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
15791 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053015792 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
15793 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053015794
Abhishek Singhf4669da2014-05-26 15:07:49 +053015795 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053015796 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
15797
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015798 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015799
Mihir Shete182a0b22014-08-18 16:08:48 +053015800 /*
15801 * stop tx queues before deleting STA/BSS context from the firmware.
15802 * tx has to be disabled because the firmware can get busy dropping
15803 * the tx frames after BSS/STA has been deleted and will not send
15804 * back a response resulting in WDI timeout
15805 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053015806 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053015807 netif_tx_disable(pAdapter->dev);
15808 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015809
Mihir Shete182a0b22014-08-18 16:08:48 +053015810 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015811 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
15812 pAdapter->sessionId, reason);
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053015813 if((eHAL_STATUS_CMD_NOT_QUEUED == status) &&
15814 prev_conn_state != eConnectionState_Connecting)
15815 {
15816 hddLog(LOG1,
15817 FL("status = %d, already disconnected"), status);
15818 result = 0;
15819 goto disconnected;
15820 }
15821 /*
15822 * Wait here instead of returning directly, this will block the next
15823 * connect command and allow processing of the scan for ssid and
15824 * the previous connect command in CSR. Else we might hit some
15825 * race conditions leading to SME and HDD out of sync.
15826 */
15827 else if(eHAL_STATUS_CMD_NOT_QUEUED == status)
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015828 {
15829 hddLog(LOG1,
15830 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053015831 }
15832 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015833 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015834 hddLog(LOGE,
15835 FL("csrRoamDisconnect failure, returned %d"),
15836 (int)status);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015837 result = -EINVAL;
15838 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015839 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015840 ret = wait_for_completion_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015841 &pAdapter->disconnect_comp_var,
15842 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015843 if (!ret && (eHAL_STATUS_CMD_NOT_QUEUED != status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015844 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015845 hddLog(LOGE,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053015846 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015847 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053015848 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015849disconnected:
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015850 hddLog(LOG1,
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053015851 FL("Set HDD connState to eConnectionState_NotConnected"));
15852 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Mahesh A Saptasagar936ffc32016-05-25 11:27:43 +053015853#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
15854 /* Sending disconnect event to userspace for kernel version < 3.11
15855 * is handled by __cfg80211_disconnect call to __cfg80211_disconnected
15856 */
15857 hddLog(LOG1, FL("Send disconnected event to userspace"));
15858
Mahesh A Saptasagarf5859b12016-06-01 17:17:50 +053015859 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, true,
Mahesh A Saptasagar936ffc32016-05-25 11:27:43 +053015860 WLAN_REASON_UNSPECIFIED);
15861#endif
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053015862
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015863 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015864 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015865}
15866
15867
15868/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015869 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070015870 * This function is used to issue a disconnect request to SME
15871 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015872static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015873 struct net_device *dev,
15874 u16 reason
15875 )
15876{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015877 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015878 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053015879 tCsrRoamProfile *pRoamProfile;
15880 hdd_station_ctx_t *pHddStaCtx;
15881 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015882#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015883 tANI_U8 staIdx;
15884#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015885
Jeff Johnson295189b2012-06-20 16:38:30 -070015886 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015887
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053015888 if (!pAdapter) {
15889 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
15890 return -EINVAL;
15891 }
15892
15893 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15894 if (!pHddStaCtx) {
15895 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
15896 return -EINVAL;
15897 }
15898
15899 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15900 status = wlan_hdd_validate_context(pHddCtx);
15901 if (0 != status)
15902 {
15903 return status;
15904 }
15905
15906 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
15907
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015908 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15909 TRACE_CODE_HDD_CFG80211_DISCONNECT,
15910 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015911 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
15912 __func__, hdd_device_modetoString(pAdapter->device_mode),
15913 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015914
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015915 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
15916 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070015917
Jeff Johnson295189b2012-06-20 16:38:30 -070015918 if (NULL != pRoamProfile)
15919 {
15920 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053015921 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
15922 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070015923 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015924 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070015925 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015926 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070015927 switch(reason)
15928 {
15929 case WLAN_REASON_MIC_FAILURE:
15930 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
15931 break;
15932
15933 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
15934 case WLAN_REASON_DISASSOC_AP_BUSY:
15935 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
15936 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
15937 break;
15938
15939 case WLAN_REASON_PREV_AUTH_NOT_VALID:
15940 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053015941 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070015942 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
15943 break;
15944
Jeff Johnson295189b2012-06-20 16:38:30 -070015945 default:
15946 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
15947 break;
15948 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015949 pScanInfo = &pHddCtx->scan_info;
15950 if (pScanInfo->mScanPending)
15951 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053015952 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015953 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053015954 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053015955 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015956 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053015957 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015958#ifdef FEATURE_WLAN_TDLS
15959 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080015960 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015961 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080015962 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
15963 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015964 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015965 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080015966 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015967 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015968 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080015969 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015970 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015971 status = sme_DeleteTdlsPeerSta(
15972 WLAN_HDD_GET_HAL_CTX(pAdapter),
15973 pAdapter->sessionId,
15974 mac);
15975 if (status != eHAL_STATUS_SUCCESS) {
15976 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
15977 return -EPERM;
15978 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015979 }
15980 }
15981#endif
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053015982
15983 hddLog(LOG1, FL("Disconnecting with reasoncode:%u connState %d"),
15984 reasonCode,
15985 pHddStaCtx->conn_info.connState);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015986 status = wlan_hdd_disconnect(pAdapter, reasonCode);
15987 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070015988 {
15989 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080015990 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015991 __func__, (int)status );
15992 return -EINVAL;
15993 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015994 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053015995 else
15996 {
15997 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
15998 "called while in %d state", __func__,
15999 pHddStaCtx->conn_info.connState);
16000 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016001 }
16002 else
16003 {
16004 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
16005 }
16006
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016007 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016008 return status;
16009}
16010
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016011static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
16012 struct net_device *dev,
16013 u16 reason
16014 )
16015{
16016 int ret;
16017 vos_ssr_protect(__func__);
16018 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
16019 vos_ssr_unprotect(__func__);
16020
16021 return ret;
16022}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016023
Jeff Johnson295189b2012-06-20 16:38:30 -070016024/*
16025 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016026 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070016027 * settings in IBSS mode.
16028 */
16029static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016030 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070016031 struct cfg80211_ibss_params *params
16032 )
16033{
16034 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016035 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016036 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
16037 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016038
Jeff Johnson295189b2012-06-20 16:38:30 -070016039 ENTER();
16040
16041 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070016042 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070016043
16044 if (params->ie_len && ( NULL != params->ie) )
16045 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016046 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
16047 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070016048 {
16049 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
16050 encryptionType = eCSR_ENCRYPT_TYPE_AES;
16051 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016052 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070016053 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070016054 tDot11fIEWPA dot11WPAIE;
16055 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016056 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070016057
Wilson Yang00256342013-10-10 23:13:38 -070016058 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016059 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
16060 params->ie_len, DOT11F_EID_WPA);
16061 if ( NULL != ie )
16062 {
16063 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
16064 // Unpack the WPA IE
16065 //Skip past the EID byte and length byte - and four byte WiFi OUI
16066 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
16067 &ie[2+4],
16068 ie[1] - 4,
16069 &dot11WPAIE);
16070 /*Extract the multicast cipher, the encType for unicast
16071 cipher for wpa-none is none*/
16072 encryptionType =
16073 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
16074 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016075 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016076
Jeff Johnson295189b2012-06-20 16:38:30 -070016077 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
16078
16079 if (0 > status)
16080 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016081 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070016082 __func__);
16083 return status;
16084 }
16085 }
16086
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016087 pWextState->roamProfile.AuthType.authType[0] =
16088 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070016089 eCSR_AUTH_TYPE_OPEN_SYSTEM;
16090
16091 if (params->privacy)
16092 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016093 /* Security enabled IBSS, At this time there is no information available
16094 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070016095 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016096 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070016097 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016098 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070016099 *enable privacy bit in beacons */
16100
16101 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
16102 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070016103 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
16104 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070016105 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
16106 pWextState->roamProfile.EncryptionType.numEntries = 1;
16107 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070016108 return status;
16109}
16110
16111/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016112 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016113 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070016114 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016115static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016116 struct net_device *dev,
16117 struct cfg80211_ibss_params *params
16118 )
16119{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016120 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070016121 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
16122 tCsrRoamProfile *pRoamProfile;
16123 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016124 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16125 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016126 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070016127
16128 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016129
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016130 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16131 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
16132 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016133 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016134 "%s: device_mode = %s (%d)", __func__,
16135 hdd_device_modetoString(pAdapter->device_mode),
16136 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070016137
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016138 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016139 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070016140 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016141 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016142 }
16143
16144 if (NULL == pWextState)
16145 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016146 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070016147 __func__);
16148 return -EIO;
16149 }
16150
Agarwal Ashish51325b52014-06-16 16:50:49 +053016151 if (vos_max_concurrent_connections_reached()) {
16152 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
16153 return -ECONNREFUSED;
16154 }
16155
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016156 /*Try disconnecting if already in connected state*/
16157 status = wlan_hdd_try_disconnect(pAdapter);
16158 if ( 0 > status)
16159 {
16160 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
16161 " IBSS connection"));
16162 return -EALREADY;
16163 }
16164
Jeff Johnson295189b2012-06-20 16:38:30 -070016165 pRoamProfile = &pWextState->roamProfile;
16166
16167 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
16168 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016169 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080016170 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016171 return -EINVAL;
16172 }
16173
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070016174 /* BSSID is provided by upper layers hence no need to AUTO generate */
16175 if (NULL != params->bssid) {
16176 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
16177 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
16178 hddLog (VOS_TRACE_LEVEL_ERROR,
16179 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
16180 return -EIO;
16181 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016182 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070016183 }
krunal sonie9002db2013-11-25 14:24:17 -080016184 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
16185 {
16186 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
16187 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
16188 {
16189 hddLog (VOS_TRACE_LEVEL_ERROR,
16190 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
16191 return -EIO;
16192 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016193
16194 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080016195 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016196 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080016197 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070016198
Jeff Johnson295189b2012-06-20 16:38:30 -070016199 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070016200 if (NULL !=
16201#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
16202 params->chandef.chan)
16203#else
16204 params->channel)
16205#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016206 {
16207 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016208 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
16209 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
16210 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
16211 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070016212
16213 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016214 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070016215 ieee80211_frequency_to_channel(
16216#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
16217 params->chandef.chan->center_freq);
16218#else
16219 params->channel->center_freq);
16220#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016221
16222 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
16223 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070016224 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016225 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
16226 __func__);
16227 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070016228 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016229
16230 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070016231 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016232 if (channelNum == validChan[indx])
16233 {
16234 break;
16235 }
16236 }
16237 if (indx >= numChans)
16238 {
16239 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016240 __func__, channelNum);
16241 return -EINVAL;
16242 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016243 /* Set the Operational Channel */
16244 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
16245 channelNum);
16246 pRoamProfile->ChannelInfo.numOfChannels = 1;
16247 pHddStaCtx->conn_info.operationChannel = channelNum;
16248 pRoamProfile->ChannelInfo.ChannelList =
16249 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070016250 }
16251
16252 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016253 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070016254 if (status < 0)
16255 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016256 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070016257 __func__);
16258 return status;
16259 }
16260
16261 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016262 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Abhishek Singh4d924682015-11-17 15:23:06 +053016263 params->ssid_len, (const u8 *)&bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016264 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070016265
16266 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070016267 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016268
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016269 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016270 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016271}
16272
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016273static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
16274 struct net_device *dev,
16275 struct cfg80211_ibss_params *params
16276 )
16277{
16278 int ret = 0;
16279
16280 vos_ssr_protect(__func__);
16281 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
16282 vos_ssr_unprotect(__func__);
16283
16284 return ret;
16285}
16286
Jeff Johnson295189b2012-06-20 16:38:30 -070016287/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016288 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016289 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070016290 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016291static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016292 struct net_device *dev
16293 )
16294{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016295 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016296 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
16297 tCsrRoamProfile *pRoamProfile;
16298 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016299 int status;
Abhishek Singh69de3302016-11-11 16:44:32 +053016300 eHalStatus hal_status;
Abhishek Singh7cd040e2016-01-07 10:51:04 +053016301#ifdef WLAN_FEATURE_RMC
16302 tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN] = {0};
16303#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016304
16305 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016306
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016307 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16308 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
16309 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016310 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016311 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016312 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016313 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016314 }
16315
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016316 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
16317 hdd_device_modetoString(pAdapter->device_mode),
16318 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070016319 if (NULL == pWextState)
16320 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016321 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070016322 __func__);
16323 return -EIO;
16324 }
16325
16326 pRoamProfile = &pWextState->roamProfile;
16327
16328 /* Issue disconnect only if interface type is set to IBSS */
16329 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
16330 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016331 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070016332 __func__);
16333 return -EINVAL;
16334 }
16335
Abhishek Singh7cd040e2016-01-07 10:51:04 +053016336#ifdef WLAN_FEATURE_RMC
16337 /* Clearing add IE of beacon */
16338 if (ccmCfgSetStr(pHddCtx->hHal,
16339 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0],
16340 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN,
16341 NULL, eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
16342 {
16343 hddLog (VOS_TRACE_LEVEL_ERROR,
16344 "%s: unable to clear PROBE_RSP_BCN_ADDNIE_DATA", __func__);
16345 return -EINVAL;
16346 }
16347 if (ccmCfgSetInt(pHddCtx->hHal,
16348 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0, NULL,
16349 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
16350 {
16351 hddLog (VOS_TRACE_LEVEL_ERROR,
16352 "%s: unable to clear WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
16353 __func__);
16354 return -EINVAL;
16355 }
16356
16357 // Reset WNI_CFG_PROBE_RSP Flags
16358 wlan_hdd_reset_prob_rspies(pAdapter);
16359
16360 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
16361 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 0,NULL,
16362 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
16363 {
16364 hddLog (VOS_TRACE_LEVEL_ERROR,
16365 "%s: unable to clear WNI_CFG_PROBE_RSP_ADDNIE_FLAG",
16366 __func__);
16367 return -EINVAL;
16368 }
16369#endif
16370
Jeff Johnson295189b2012-06-20 16:38:30 -070016371 /* Issue Disconnect request */
16372 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singh69de3302016-11-11 16:44:32 +053016373 hal_status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
16374 pAdapter->sessionId,
16375 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
16376 if (!HAL_STATUS_SUCCESS(hal_status)) {
16377 hddLog(LOGE,
16378 FL("sme_RoamDisconnect failed hal_status(%d)"),
16379 hal_status);
16380 return -EAGAIN;
16381 }
16382 status = wait_for_completion_timeout(
16383 &pAdapter->disconnect_comp_var,
16384 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
16385 if (!status) {
16386 hddLog(LOGE,
16387 FL("wait on disconnect_comp_var failed"));
16388 return -ETIMEDOUT;
16389 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016390
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016391 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016392 return 0;
16393}
16394
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016395static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
16396 struct net_device *dev
16397 )
16398{
16399 int ret = 0;
16400
16401 vos_ssr_protect(__func__);
16402 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
16403 vos_ssr_unprotect(__func__);
16404
16405 return ret;
16406}
16407
Jeff Johnson295189b2012-06-20 16:38:30 -070016408/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016409 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070016410 * This function is used to set the phy parameters
16411 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
16412 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016413static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016414 u32 changed)
16415{
16416 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
16417 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016418 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016419
16420 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016421
16422 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016423 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
16424 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016425
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016426 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016427 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016428 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016429 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016430 }
16431
Jeff Johnson295189b2012-06-20 16:38:30 -070016432 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
16433 {
16434 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
16435 WNI_CFG_RTS_THRESHOLD_STAMAX :
16436 wiphy->rts_threshold;
16437
16438 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016439 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070016440 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016441 hddLog(VOS_TRACE_LEVEL_ERROR,
16442 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016443 __func__, rts_threshold);
16444 return -EINVAL;
16445 }
16446
16447 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
16448 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016449 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016450 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016451 hddLog(VOS_TRACE_LEVEL_ERROR,
16452 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016453 __func__, rts_threshold);
16454 return -EIO;
16455 }
16456
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016457 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016458 rts_threshold);
16459 }
16460
16461 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
16462 {
16463 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
16464 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
16465 wiphy->frag_threshold;
16466
16467 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016468 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016469 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016470 hddLog(VOS_TRACE_LEVEL_ERROR,
16471 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016472 frag_threshold);
16473 return -EINVAL;
16474 }
16475
16476 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
16477 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016478 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016479 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016480 hddLog(VOS_TRACE_LEVEL_ERROR,
16481 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016482 __func__, frag_threshold);
16483 return -EIO;
16484 }
16485
16486 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
16487 frag_threshold);
16488 }
16489
16490 if ((changed & WIPHY_PARAM_RETRY_SHORT)
16491 || (changed & WIPHY_PARAM_RETRY_LONG))
16492 {
16493 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
16494 wiphy->retry_short :
16495 wiphy->retry_long;
16496
16497 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
16498 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
16499 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016500 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016501 __func__, retry_value);
16502 return -EINVAL;
16503 }
16504
16505 if (changed & WIPHY_PARAM_RETRY_SHORT)
16506 {
16507 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
16508 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016509 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016510 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016511 hddLog(VOS_TRACE_LEVEL_ERROR,
16512 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016513 __func__, retry_value);
16514 return -EIO;
16515 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016516 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016517 __func__, retry_value);
16518 }
16519 else if (changed & WIPHY_PARAM_RETRY_SHORT)
16520 {
16521 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
16522 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016523 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016524 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016525 hddLog(VOS_TRACE_LEVEL_ERROR,
16526 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016527 __func__, retry_value);
16528 return -EIO;
16529 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016530 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016531 __func__, retry_value);
16532 }
16533 }
16534
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016535 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016536 return 0;
16537}
16538
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016539static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
16540 u32 changed)
16541{
16542 int ret;
16543
16544 vos_ssr_protect(__func__);
16545 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
16546 vos_ssr_unprotect(__func__);
16547
16548 return ret;
16549}
16550
Jeff Johnson295189b2012-06-20 16:38:30 -070016551/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016552 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070016553 * This function is used to set the txpower
16554 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016555static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070016556#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16557 struct wireless_dev *wdev,
16558#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016559#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016560 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070016561#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016562 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070016563#endif
16564 int dbm)
16565{
16566 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016567 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070016568 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
16569 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016570 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016571
16572 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016573
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016574 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16575 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
16576 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016577 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016578 if (0 != status)
16579 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016580 return status;
16581 }
16582
16583 hHal = pHddCtx->hHal;
16584
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016585 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
16586 dbm, ccmCfgSetCallback,
16587 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016588 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016589 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016590 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
16591 return -EIO;
16592 }
16593
16594 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
16595 dbm);
16596
16597 switch(type)
16598 {
16599 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
16600 /* Fall through */
16601 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
16602 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
16603 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016604 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
16605 __func__);
16606 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070016607 }
16608 break;
16609 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016610 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070016611 __func__);
16612 return -EOPNOTSUPP;
16613 break;
16614 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016615 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
16616 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070016617 return -EIO;
16618 }
16619
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016620 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016621 return 0;
16622}
16623
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016624static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
16625#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16626 struct wireless_dev *wdev,
16627#endif
16628#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
16629 enum tx_power_setting type,
16630#else
16631 enum nl80211_tx_power_setting type,
16632#endif
16633 int dbm)
16634{
16635 int ret;
16636 vos_ssr_protect(__func__);
16637 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
16638#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16639 wdev,
16640#endif
16641#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
16642 type,
16643#else
16644 type,
16645#endif
16646 dbm);
16647 vos_ssr_unprotect(__func__);
16648
16649 return ret;
16650}
16651
Jeff Johnson295189b2012-06-20 16:38:30 -070016652/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016653 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070016654 * This function is used to read the txpower
16655 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016656static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070016657#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16658 struct wireless_dev *wdev,
16659#endif
16660 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070016661{
16662
16663 hdd_adapter_t *pAdapter;
16664 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016665 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016666
Jeff Johnsone7245742012-09-05 17:12:55 -070016667 ENTER();
16668
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016669 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016670 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016671 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016672 *dbm = 0;
16673 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016674 }
16675
Jeff Johnson295189b2012-06-20 16:38:30 -070016676 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
16677 if (NULL == pAdapter)
16678 {
16679 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
16680 return -ENOENT;
16681 }
16682
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016683 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16684 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
16685 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070016686 wlan_hdd_get_classAstats(pAdapter);
16687 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
16688
Jeff Johnsone7245742012-09-05 17:12:55 -070016689 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016690 return 0;
16691}
16692
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016693static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
16694#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16695 struct wireless_dev *wdev,
16696#endif
16697 int *dbm)
16698{
16699 int ret;
16700
16701 vos_ssr_protect(__func__);
16702 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
16703#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16704 wdev,
16705#endif
16706 dbm);
16707 vos_ssr_unprotect(__func__);
16708
16709 return ret;
16710}
16711
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016712static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016713#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16714 const u8* mac,
16715#else
16716 u8* mac,
16717#endif
16718 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070016719{
16720 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
16721 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16722 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053016723 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070016724
16725 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
16726 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070016727
16728 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
16729 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
16730 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
16731 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
16732 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
16733 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
16734 tANI_U16 maxRate = 0;
16735 tANI_U16 myRate;
16736 tANI_U16 currentRate = 0;
16737 tANI_U8 maxSpeedMCS = 0;
16738 tANI_U8 maxMCSIdx = 0;
16739 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053016740 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070016741 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016742 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016743
Leo Chang6f8870f2013-03-26 18:11:36 -070016744#ifdef WLAN_FEATURE_11AC
16745 tANI_U32 vht_mcs_map;
16746 eDataRate11ACMaxMcs vhtMaxMcs;
16747#endif /* WLAN_FEATURE_11AC */
16748
Jeff Johnsone7245742012-09-05 17:12:55 -070016749 ENTER();
16750
Jeff Johnson295189b2012-06-20 16:38:30 -070016751 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
16752 (0 == ssidlen))
16753 {
16754 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
16755 " Invalid ssidlen, %d", __func__, ssidlen);
16756 /*To keep GUI happy*/
16757 return 0;
16758 }
16759
Mukul Sharma811205f2014-07-09 21:07:30 +053016760 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
16761 {
16762 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16763 "%s: Roaming in progress, so unable to proceed this request", __func__);
Sachin Ahuja81ab1812016-08-19 21:35:58 +053016764 /* return a cached value */
16765 sinfo->signal = pAdapter->rssi;
Mukul Sharma811205f2014-07-09 21:07:30 +053016766 return 0;
16767 }
16768
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016769 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016770 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016771 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016772 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016773 }
16774
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053016775 wlan_hdd_get_station_stats(pAdapter);
16776 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070016777
Kiet Lam3b17fc82013-09-27 05:24:08 +053016778 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
16779 sinfo->filled |= STATION_INFO_SIGNAL;
16780
c_hpothu09f19542014-05-30 21:53:31 +053016781 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053016782 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
16783 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053016784 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053016785 {
16786 rate_flags = pAdapter->maxRateFlags;
16787 }
c_hpothu44ff4e02014-05-08 00:13:57 +053016788
Jeff Johnson295189b2012-06-20 16:38:30 -070016789 //convert to the UI units of 100kbps
16790 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
16791
16792#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070016793 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 -070016794 sinfo->signal,
16795 pCfg->reportMaxLinkSpeed,
16796 myRate,
16797 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070016798 (int) pCfg->linkSpeedRssiMid,
16799 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070016800 (int) rate_flags,
16801 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070016802#endif //LINKSPEED_DEBUG_ENABLED
16803
16804 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
16805 {
16806 // we do not want to necessarily report the current speed
16807 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
16808 {
16809 // report the max possible speed
16810 rssidx = 0;
16811 }
16812 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
16813 {
16814 // report the max possible speed with RSSI scaling
16815 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
16816 {
16817 // report the max possible speed
16818 rssidx = 0;
16819 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070016820 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070016821 {
16822 // report middle speed
16823 rssidx = 1;
16824 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070016825 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
16826 {
16827 // report middle speed
16828 rssidx = 2;
16829 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016830 else
16831 {
16832 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070016833 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070016834 }
16835 }
16836 else
16837 {
16838 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
16839 hddLog(VOS_TRACE_LEVEL_ERROR,
16840 "%s: Invalid value for reportMaxLinkSpeed: %u",
16841 __func__, pCfg->reportMaxLinkSpeed);
16842 rssidx = 0;
16843 }
16844
16845 maxRate = 0;
16846
16847 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053016848 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
16849 OperationalRates, &ORLeng))
16850 {
16851 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
16852 /*To keep GUI happy*/
16853 return 0;
16854 }
16855
Jeff Johnson295189b2012-06-20 16:38:30 -070016856 for (i = 0; i < ORLeng; i++)
16857 {
Jeff Johnsone7245742012-09-05 17:12:55 -070016858 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070016859 {
16860 /* Validate Rate Set */
16861 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
16862 {
16863 currentRate = supported_data_rate[j].supported_rate[rssidx];
16864 break;
16865 }
16866 }
16867 /* Update MAX rate */
16868 maxRate = (currentRate > maxRate)?currentRate:maxRate;
16869 }
16870
16871 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053016872 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
16873 ExtendedRates, &ERLeng))
16874 {
16875 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
16876 /*To keep GUI happy*/
16877 return 0;
16878 }
16879
Jeff Johnson295189b2012-06-20 16:38:30 -070016880 for (i = 0; i < ERLeng; i++)
16881 {
Jeff Johnsone7245742012-09-05 17:12:55 -070016882 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070016883 {
16884 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
16885 {
16886 currentRate = supported_data_rate[j].supported_rate[rssidx];
16887 break;
16888 }
16889 }
16890 /* Update MAX rate */
16891 maxRate = (currentRate > maxRate)?currentRate:maxRate;
16892 }
c_hpothu79aab322014-07-14 21:11:01 +053016893
Kiet Lamb69f8dc2013-11-15 15:34:27 +053016894 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053016895 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053016896 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053016897 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070016898 {
c_hpothu79aab322014-07-14 21:11:01 +053016899 if (rate_flags & eHAL_TX_RATE_VHT80)
16900 mode = 2;
16901 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
16902 mode = 1;
16903 else
16904 mode = 0;
16905
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053016906 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
16907 MCSRates, &MCSLeng))
16908 {
16909 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
16910 /*To keep GUI happy*/
16911 return 0;
16912 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016913 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070016914#ifdef WLAN_FEATURE_11AC
16915 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016916 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070016917 {
Leo Chang6f8870f2013-03-26 18:11:36 -070016918 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016919 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070016920 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070016921 {
Leo Chang6f8870f2013-03-26 18:11:36 -070016922 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070016923 }
Leo Chang6f8870f2013-03-26 18:11:36 -070016924 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070016925 {
Leo Chang6f8870f2013-03-26 18:11:36 -070016926 maxMCSIdx = 7;
16927 }
16928 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
16929 {
16930 maxMCSIdx = 8;
16931 }
16932 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
16933 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016934 //VHT20 is supporting 0~8
16935 if (rate_flags & eHAL_TX_RATE_VHT20)
16936 maxMCSIdx = 8;
16937 else
16938 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070016939 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016940
c_hpothu79aab322014-07-14 21:11:01 +053016941 if (0 != rssidx)/*check for scaled */
16942 {
16943 //get middle rate MCS index if rssi=1/2
16944 for (i=0; i <= maxMCSIdx; i++)
16945 {
16946 if (sinfo->signal <= rssiMcsTbl[mode][i])
16947 {
16948 maxMCSIdx = i;
16949 break;
16950 }
16951 }
16952 }
16953
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016954 if (rate_flags & eHAL_TX_RATE_VHT80)
16955 {
16956 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
16957 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
16958 }
16959 else if (rate_flags & eHAL_TX_RATE_VHT40)
16960 {
16961 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
16962 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
16963 }
16964 else if (rate_flags & eHAL_TX_RATE_VHT20)
16965 {
16966 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
16967 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
16968 }
16969
Leo Chang6f8870f2013-03-26 18:11:36 -070016970 maxSpeedMCS = 1;
16971 if (currentRate > maxRate)
16972 {
16973 maxRate = currentRate;
16974 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016975
Leo Chang6f8870f2013-03-26 18:11:36 -070016976 }
16977 else
16978#endif /* WLAN_FEATURE_11AC */
16979 {
16980 if (rate_flags & eHAL_TX_RATE_HT40)
16981 {
16982 rateFlag |= 1;
16983 }
16984 if (rate_flags & eHAL_TX_RATE_SGI)
16985 {
16986 rateFlag |= 2;
16987 }
16988
Girish Gowli01abcee2014-07-31 20:18:55 +053016989 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053016990 if (rssidx == 1 || rssidx == 2)
16991 {
16992 //get middle rate MCS index if rssi=1/2
16993 for (i=0; i <= 7; i++)
16994 {
16995 if (sinfo->signal <= rssiMcsTbl[mode][i])
16996 {
16997 temp = i+1;
16998 break;
16999 }
17000 }
17001 }
c_hpothu79aab322014-07-14 21:11:01 +053017002
17003 for (i = 0; i < MCSLeng; i++)
17004 {
Leo Chang6f8870f2013-03-26 18:11:36 -070017005 for (j = 0; j < temp; j++)
17006 {
17007 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
17008 {
17009 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053017010 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070017011 break;
17012 }
17013 }
17014 if ((j < temp) && (currentRate > maxRate))
17015 {
17016 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070017017 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017018 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053017019 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070017020 }
17021 }
17022
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017023 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
17024 {
17025 maxRate = myRate;
17026 maxSpeedMCS = 1;
17027 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
17028 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017029 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053017030 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070017031 {
17032 maxRate = myRate;
17033 if (rate_flags & eHAL_TX_RATE_LEGACY)
17034 {
17035 maxSpeedMCS = 0;
17036 }
17037 else
17038 {
17039 maxSpeedMCS = 1;
17040 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
17041 }
17042 }
17043
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017044 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070017045 {
17046 sinfo->txrate.legacy = maxRate;
17047#ifdef LINKSPEED_DEBUG_ENABLED
17048 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
17049#endif //LINKSPEED_DEBUG_ENABLED
17050 }
17051 else
17052 {
17053 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070017054#ifdef WLAN_FEATURE_11AC
17055 sinfo->txrate.nss = 1;
17056 if (rate_flags & eHAL_TX_RATE_VHT80)
17057 {
17058 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017059 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070017060 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017061 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070017062 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017063 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
17064 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
17065 }
17066 else if (rate_flags & eHAL_TX_RATE_VHT20)
17067 {
17068 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
17069 }
17070#endif /* WLAN_FEATURE_11AC */
17071 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
17072 {
17073 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
17074 if (rate_flags & eHAL_TX_RATE_HT40)
17075 {
17076 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
17077 }
Leo Chang6f8870f2013-03-26 18:11:36 -070017078 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017079 if (rate_flags & eHAL_TX_RATE_SGI)
17080 {
17081 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
17082 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017083
Jeff Johnson295189b2012-06-20 16:38:30 -070017084#ifdef LINKSPEED_DEBUG_ENABLED
17085 pr_info("Reporting MCS rate %d flags %x\n",
17086 sinfo->txrate.mcs,
17087 sinfo->txrate.flags );
17088#endif //LINKSPEED_DEBUG_ENABLED
17089 }
17090 }
17091 else
17092 {
17093 // report current rate instead of max rate
17094
17095 if (rate_flags & eHAL_TX_RATE_LEGACY)
17096 {
17097 //provide to the UI in units of 100kbps
17098 sinfo->txrate.legacy = myRate;
17099#ifdef LINKSPEED_DEBUG_ENABLED
17100 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
17101#endif //LINKSPEED_DEBUG_ENABLED
17102 }
17103 else
17104 {
17105 //must be MCS
17106 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070017107#ifdef WLAN_FEATURE_11AC
17108 sinfo->txrate.nss = 1;
17109 if (rate_flags & eHAL_TX_RATE_VHT80)
17110 {
17111 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
17112 }
17113 else
17114#endif /* WLAN_FEATURE_11AC */
17115 {
17116 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
17117 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017118 if (rate_flags & eHAL_TX_RATE_SGI)
17119 {
17120 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
17121 }
17122 if (rate_flags & eHAL_TX_RATE_HT40)
17123 {
17124 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
17125 }
Leo Chang6f8870f2013-03-26 18:11:36 -070017126#ifdef WLAN_FEATURE_11AC
17127 else if (rate_flags & eHAL_TX_RATE_VHT80)
17128 {
17129 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
17130 }
17131#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070017132#ifdef LINKSPEED_DEBUG_ENABLED
17133 pr_info("Reporting actual MCS rate %d flags %x\n",
17134 sinfo->txrate.mcs,
17135 sinfo->txrate.flags );
17136#endif //LINKSPEED_DEBUG_ENABLED
17137 }
17138 }
17139 sinfo->filled |= STATION_INFO_TX_BITRATE;
17140
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070017141 sinfo->tx_packets =
17142 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
17143 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
17144 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
17145 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
17146
17147 sinfo->tx_retries =
17148 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
17149 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
17150 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
17151 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
17152
17153 sinfo->tx_failed =
17154 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
17155 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
17156 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
17157 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
17158
17159 sinfo->filled |=
17160 STATION_INFO_TX_PACKETS |
17161 STATION_INFO_TX_RETRIES |
17162 STATION_INFO_TX_FAILED;
17163
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053017164 sinfo->rx_packets = pAdapter->hdd_stats.summary_stat.rx_frm_cnt;
17165 sinfo->filled |= STATION_INFO_RX_PACKETS;
17166
17167 if (rate_flags & eHAL_TX_RATE_LEGACY)
17168 hddLog(LOG1, FL("Reporting RSSI:%d legacy rate %d pkt cnt tx %d rx %d"),
17169 sinfo->signal, sinfo->txrate.legacy, sinfo->tx_packets,
17170 sinfo->rx_packets);
17171 else
17172 hddLog(LOG1,
17173 FL("Reporting RSSI:%d MCS rate %d flags 0x%x pkt cnt tx %d rx %d"),
17174 sinfo->signal, sinfo->txrate.mcs, sinfo->txrate.flags,
17175 sinfo->tx_packets, sinfo->rx_packets);
17176
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017177 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17178 TRACE_CODE_HDD_CFG80211_GET_STA,
17179 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070017180 EXIT();
17181 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070017182}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017183#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
17184static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
17185 const u8* mac, struct station_info *sinfo)
17186#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017187static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
17188 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017189#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017190{
17191 int ret;
17192
17193 vos_ssr_protect(__func__);
17194 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
17195 vos_ssr_unprotect(__func__);
17196
17197 return ret;
17198}
17199
17200static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070017201 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070017202{
17203 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017204 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070017205 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017206 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017207
Jeff Johnsone7245742012-09-05 17:12:55 -070017208 ENTER();
17209
Jeff Johnson295189b2012-06-20 16:38:30 -070017210 if (NULL == pAdapter)
17211 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017212 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017213 return -ENODEV;
17214 }
17215
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017216 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17217 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
17218 pAdapter->sessionId, timeout));
17219
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017220 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017221 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017222 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017223 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017224 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017225 }
17226
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017227 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
17228 (TRUE == pHddCtx->hdd_wlan_suspended) &&
17229 (pHddCtx->cfg_ini->fhostArpOffload) &&
17230 (eConnectionState_Associated ==
17231 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
17232 {
Amar Singhald53568e2013-09-26 11:03:45 -070017233
17234 hddLog(VOS_TRACE_LEVEL_INFO,
17235 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053017236 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017237 if (!VOS_IS_STATUS_SUCCESS(vos_status))
17238 {
17239 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017240 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017241 __func__, vos_status);
17242 }
17243 }
17244
Jeff Johnson295189b2012-06-20 16:38:30 -070017245 /**The get power cmd from the supplicant gets updated by the nl only
17246 *on successful execution of the function call
17247 *we are oppositely mapped w.r.t mode in the driver
17248 **/
17249 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
17250
17251 if (VOS_STATUS_E_FAILURE == vos_status)
17252 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053017253 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17254 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017255 return -EINVAL;
17256 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017257 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017258 return 0;
17259}
17260
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017261static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
17262 struct net_device *dev, bool mode, int timeout)
17263{
17264 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070017265
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017266 vos_ssr_protect(__func__);
17267 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
17268 vos_ssr_unprotect(__func__);
17269
17270 return ret;
17271}
Sushant Kaushik084f6592015-09-10 13:11:56 +053017272
Jeff Johnson295189b2012-06-20 16:38:30 -070017273#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017274static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
17275 struct net_device *netdev,
17276 u8 key_index)
17277{
17278 ENTER();
17279 return 0;
17280}
17281
Jeff Johnson295189b2012-06-20 16:38:30 -070017282static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017283 struct net_device *netdev,
17284 u8 key_index)
17285{
17286 int ret;
17287 vos_ssr_protect(__func__);
17288 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
17289 vos_ssr_unprotect(__func__);
17290 return ret;
17291}
17292#endif //LINUX_VERSION_CODE
17293
17294#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
17295static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
17296 struct net_device *dev,
17297 struct ieee80211_txq_params *params)
17298{
17299 ENTER();
17300 return 0;
17301}
17302#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
17303static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
17304 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070017305{
Jeff Johnsone7245742012-09-05 17:12:55 -070017306 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070017307 return 0;
17308}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017309#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070017310
17311#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
17312static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017313 struct net_device *dev,
17314 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070017315{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017316 int ret;
17317
17318 vos_ssr_protect(__func__);
17319 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
17320 vos_ssr_unprotect(__func__);
17321 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070017322}
17323#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
17324static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
17325 struct ieee80211_txq_params *params)
17326{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017327 int ret;
17328
17329 vos_ssr_protect(__func__);
17330 ret = __wlan_hdd_set_txq_params(wiphy, params);
17331 vos_ssr_unprotect(__func__);
17332 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070017333}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017334#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017335
Naresh Jayaram69e3f282014-10-14 12:29:12 +053017336static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017337 struct net_device *dev,
17338 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070017339{
17340 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017341 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017342 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017343 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017344 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017345 v_CONTEXT_t pVosContext = NULL;
17346 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017347
Jeff Johnsone7245742012-09-05 17:12:55 -070017348 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017349
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017350 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070017351 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017352 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017353 return -EINVAL;
17354 }
17355
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017356 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17357 TRACE_CODE_HDD_CFG80211_DEL_STA,
17358 pAdapter->sessionId, pAdapter->device_mode));
17359
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017360 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17361 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017362 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017363 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017364 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017365 }
17366
Jeff Johnson295189b2012-06-20 16:38:30 -070017367 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070017368 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070017369 )
17370 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017371 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
17372 pSapCtx = VOS_GET_SAP_CB(pVosContext);
17373 if(pSapCtx == NULL){
17374 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17375 FL("psapCtx is NULL"));
17376 return -ENOENT;
17377 }
Agrawal Ashish306b75f2017-01-11 19:16:25 +053017378 if (pHddCtx->cfg_ini->enable_sap_auth_offload)
17379 {
17380 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
17381 "Change reason code to eSIR_MAC_DISASSOC_LEAVING_BSS_REASON in sap auth offload");
17382 pDelStaParams->reason_code = eSIR_MAC_DISASSOC_LEAVING_BSS_REASON;
17383 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017384 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070017385 {
17386 v_U16_t i;
17387 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
17388 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017389 if ((pSapCtx->aStaInfo[i].isUsed) &&
17390 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070017391 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017392 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017393 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017394 ETHER_ADDR_LEN);
17395
Jeff Johnson295189b2012-06-20 16:38:30 -070017396 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080017397 "%s: Delete STA with MAC::"
17398 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017399 __func__,
17400 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
17401 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070017402 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017403 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070017404 }
17405 }
17406 }
17407 else
17408 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017409
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017410 vos_status = hdd_softap_GetStaId(pAdapter,
17411 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017412 if (!VOS_IS_STATUS_SUCCESS(vos_status))
17413 {
17414 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080017415 "%s: Skip this DEL STA as this is not used::"
17416 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017417 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017418 return -ENOENT;
17419 }
17420
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017421 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017422 {
17423 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080017424 "%s: Skip this DEL STA as deauth is in progress::"
17425 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017426 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017427 return -ENOENT;
17428 }
17429
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017430 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017431
Jeff Johnson295189b2012-06-20 16:38:30 -070017432 hddLog(VOS_TRACE_LEVEL_INFO,
17433 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080017434 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070017435 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017436 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017437
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017438 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017439 if (!VOS_IS_STATUS_SUCCESS(vos_status))
17440 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017441 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017442 hddLog(VOS_TRACE_LEVEL_INFO,
17443 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080017444 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017445 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017446 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017447 return -ENOENT;
17448 }
17449
Jeff Johnson295189b2012-06-20 16:38:30 -070017450 }
17451 }
17452
17453 EXIT();
17454
17455 return 0;
17456}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053017457
17458#ifdef CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053017459int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Naresh Jayaram69e3f282014-10-14 12:29:12 +053017460 struct net_device *dev,
17461 struct station_del_parameters *param)
17462#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017463#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
Kapil Gupta137ef892016-12-13 19:38:00 +053017464int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017465 struct net_device *dev, const u8 *mac)
17466#else
Kapil Gupta137ef892016-12-13 19:38:00 +053017467int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017468 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053017469#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017470#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017471{
17472 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017473 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070017474
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017475 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017476
Naresh Jayaram69e3f282014-10-14 12:29:12 +053017477#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017478 if (NULL == param) {
17479 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017480 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017481 return -EINVAL;
17482 }
17483
17484 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
17485 param->subtype, &delStaParams);
17486
Naresh Jayaram69e3f282014-10-14 12:29:12 +053017487#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053017488 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017489 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053017490#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017491 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
17492
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017493 vos_ssr_unprotect(__func__);
17494
17495 return ret;
17496}
17497
17498static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017499 struct net_device *dev,
17500#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17501 const u8 *mac,
17502#else
17503 u8 *mac,
17504#endif
17505 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017506{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017507 hdd_adapter_t *pAdapter;
17508 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017509 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017510#ifdef FEATURE_WLAN_TDLS
17511 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017512
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017513 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017514
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017515 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17516 if (NULL == pAdapter)
17517 {
17518 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17519 "%s: Adapter is NULL",__func__);
17520 return -EINVAL;
17521 }
17522 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17523 status = wlan_hdd_validate_context(pHddCtx);
17524 if (0 != status)
17525 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017526 return status;
17527 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017528
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017529 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17530 TRACE_CODE_HDD_CFG80211_ADD_STA,
17531 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017532 mask = params->sta_flags_mask;
17533
17534 set = params->sta_flags_set;
17535
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017536 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017537 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
17538 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017539
17540 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
17541 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080017542 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017543 }
17544 }
17545#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017546 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017547 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017548}
17549
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017550#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
17551static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
17552 struct net_device *dev, const u8 *mac,
17553 struct station_parameters *params)
17554#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017555static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
17556 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017557#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017558{
17559 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017560
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017561 vos_ssr_protect(__func__);
17562 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
17563 vos_ssr_unprotect(__func__);
17564
17565 return ret;
17566}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017567#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070017568
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017569static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070017570 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017571{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017572 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17573 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017574 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017575 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017576 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017577 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070017578
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017579 ENTER();
17580
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017581 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017582 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017583 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017584 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017585 return -EINVAL;
17586 }
17587
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017588 if (!pmksa) {
17589 hddLog(LOGE, FL("pmksa is NULL"));
17590 return -EINVAL;
17591 }
17592
17593 if (!pmksa->bssid || !pmksa->pmkid) {
17594 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
17595 pmksa->bssid, pmksa->pmkid);
17596 return -EINVAL;
17597 }
17598
17599 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
17600 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
17601
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017602 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17603 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017604 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017605 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017606 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017607 }
17608
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017609 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017610 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
17611
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017612 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
17613 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017614
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017615 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017616 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017617 &pmk_id, 1, FALSE);
17618
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017619 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17620 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
17621 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017622
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017623 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017624 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017625}
17626
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017627static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
17628 struct cfg80211_pmksa *pmksa)
17629{
17630 int ret;
17631
17632 vos_ssr_protect(__func__);
17633 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
17634 vos_ssr_unprotect(__func__);
17635
17636 return ret;
17637}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017638
Wilson Yang6507c4e2013-10-01 20:11:19 -070017639
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017640static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070017641 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017642{
Wilson Yang6507c4e2013-10-01 20:11:19 -070017643 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17644 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017645 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080017646 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017647
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017648 ENTER();
17649
Wilson Yang6507c4e2013-10-01 20:11:19 -070017650 /* Validate pAdapter */
17651 if (NULL == pAdapter)
17652 {
17653 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
17654 return -EINVAL;
17655 }
17656
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017657 if (!pmksa) {
17658 hddLog(LOGE, FL("pmksa is NULL"));
17659 return -EINVAL;
17660 }
17661
17662 if (!pmksa->bssid) {
17663 hddLog(LOGE, FL("pmksa->bssid is NULL"));
17664 return -EINVAL;
17665 }
17666
Kiet Lam98c46a12014-10-31 15:34:57 -070017667 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
17668 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
17669
Wilson Yang6507c4e2013-10-01 20:11:19 -070017670 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17671 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070017672 if (0 != status)
17673 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070017674 return status;
17675 }
17676
17677 /*Retrieve halHandle*/
17678 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
17679
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017680 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17681 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
17682 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017683 /* Delete the PMKID CSR cache */
17684 if (eHAL_STATUS_SUCCESS !=
17685 sme_RoamDelPMKIDfromCache(halHandle,
17686 pAdapter->sessionId, pmksa->bssid, FALSE)) {
17687 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
17688 MAC_ADDR_ARRAY(pmksa->bssid));
17689 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017690 }
17691
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017692 EXIT();
17693 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017694}
17695
Wilson Yang6507c4e2013-10-01 20:11:19 -070017696
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017697static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
17698 struct cfg80211_pmksa *pmksa)
17699{
17700 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017701
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017702 vos_ssr_protect(__func__);
17703 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
17704 vos_ssr_unprotect(__func__);
17705
17706 return ret;
17707
17708}
17709
17710static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017711{
Wilson Yang6507c4e2013-10-01 20:11:19 -070017712 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17713 tHalHandle halHandle;
17714 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080017715 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017716
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017717 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070017718
17719 /* Validate pAdapter */
17720 if (NULL == pAdapter)
17721 {
17722 hddLog(VOS_TRACE_LEVEL_ERROR,
17723 "%s: Invalid Adapter" ,__func__);
17724 return -EINVAL;
17725 }
17726
17727 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17728 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070017729 if (0 != status)
17730 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070017731 return status;
17732 }
17733
17734 /*Retrieve halHandle*/
17735 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
17736
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017737 /* Flush the PMKID cache in CSR */
17738 if (eHAL_STATUS_SUCCESS !=
17739 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
17740 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
17741 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017742 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017743 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080017744 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017745}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017746
17747static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
17748{
17749 int ret;
17750
17751 vos_ssr_protect(__func__);
17752 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
17753 vos_ssr_unprotect(__func__);
17754
17755 return ret;
17756}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017757#endif
17758
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017759#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017760static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
17761 struct net_device *dev,
17762 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017763{
17764 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17765 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017766 hdd_context_t *pHddCtx;
17767 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017768
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017769 ENTER();
17770
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017771 if (NULL == pAdapter)
17772 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017773 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017774 return -ENODEV;
17775 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017776 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17777 ret = wlan_hdd_validate_context(pHddCtx);
17778 if (0 != ret)
17779 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017780 return ret;
17781 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017782 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017783 if (NULL == pHddStaCtx)
17784 {
17785 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
17786 return -EINVAL;
17787 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017788
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017789 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17790 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
17791 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017792 // Added for debug on reception of Re-assoc Req.
17793 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
17794 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017795 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017796 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080017797 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017798 }
17799
17800#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080017801 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017802 ftie->ie_len);
17803#endif
17804
17805 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053017806 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
17807 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017808 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017809
17810 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017811 return 0;
17812}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017813
17814static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
17815 struct net_device *dev,
17816 struct cfg80211_update_ft_ies_params *ftie)
17817{
17818 int ret;
17819
17820 vos_ssr_protect(__func__);
17821 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
17822 vos_ssr_unprotect(__func__);
17823
17824 return ret;
17825}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017826#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017827
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017828#ifdef FEATURE_WLAN_SCAN_PNO
17829
17830void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
17831 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
17832{
17833 int ret;
17834 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
17835 hdd_context_t *pHddCtx;
17836
Nirav Shah80830bf2013-12-31 16:35:12 +053017837 ENTER();
17838
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017839 if (NULL == pAdapter)
17840 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053017841 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017842 "%s: HDD adapter is Null", __func__);
17843 return ;
17844 }
17845
17846 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17847 if (NULL == pHddCtx)
17848 {
17849 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17850 "%s: HDD context is Null!!!", __func__);
17851 return ;
17852 }
17853
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017854 spin_lock(&pHddCtx->schedScan_lock);
17855 if (TRUE == pHddCtx->isWiphySuspended)
17856 {
17857 pHddCtx->isSchedScanUpdatePending = TRUE;
17858 spin_unlock(&pHddCtx->schedScan_lock);
17859 hddLog(VOS_TRACE_LEVEL_INFO,
17860 "%s: Update cfg80211 scan database after it resume", __func__);
17861 return ;
17862 }
17863 spin_unlock(&pHddCtx->schedScan_lock);
17864
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017865 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
17866
17867 if (0 > ret)
17868 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagarfb49cdd2015-10-16 18:41:59 +053017869 else
17870 {
17871 /* Acquire wakelock to handle the case where APP's tries to suspend
17872 * immediatly after the driver gets connect request(i.e after pno)
17873 * from supplicant, this result in app's is suspending and not able
17874 * to process the connect request to AP */
17875 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
17876 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017877 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017878 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17879 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017880}
17881
17882/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017883 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053017884 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017885 */
17886static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
17887{
17888 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
17889 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017890 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017891 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17892 int status = 0;
Agrawal Ashishcff31692016-12-16 17:17:50 +053017893
17894 if (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
17895 {
17896 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17897 "%s: PNO is allowed only in STA interface", __func__);
17898 return eHAL_STATUS_FAILURE;
17899 }
17900
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017901 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
17902
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053017903 /* The current firmware design does not allow PNO during any
Agrawal Ashishcff31692016-12-16 17:17:50 +053017904 * active sessions. PNO is allowed only in case when sap session
17905 * is present and sapo auth offload feature enabled in firmare.
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053017906 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017907 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
17908 {
17909 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017910 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017911
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017912 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
17913 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
17914 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
17915 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
Agrawal Ashishcff31692016-12-16 17:17:50 +053017916 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode &&
17917 !pHddCtx->cfg_ini->enable_sap_auth_offload)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053017918 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017919 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017920 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017921 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017922 }
17923 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
17924 pAdapterNode = pNext;
17925 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017926 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017927}
17928
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017929void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
17930{
17931 hdd_adapter_t *pAdapter = callbackContext;
17932 hdd_context_t *pHddCtx;
17933
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017934 ENTER();
17935
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017936 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
17937 {
17938 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17939 FL("Invalid adapter or adapter has invalid magic"));
17940 return;
17941 }
17942
17943 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17944 if (0 != wlan_hdd_validate_context(pHddCtx))
17945 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017946 return;
17947 }
17948
c_hpothub53c45d2014-08-18 16:53:14 +053017949 if (VOS_STATUS_SUCCESS != status)
17950 {
17951 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017952 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053017953 pHddCtx->isPnoEnable = FALSE;
17954 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017955
17956 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
17957 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017958 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017959}
17960
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017961#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) || \
17962 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
17963/**
17964 * hdd_config_sched_scan_plan() - configures the sched scan plans
17965 * from the framework.
17966 * @pno_req: pointer to PNO scan request
17967 * @request: pointer to scan request from framework
17968 *
17969 * Return: None
17970 */
17971static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
17972 struct cfg80211_sched_scan_request *request,
17973 hdd_context_t *hdd_ctx)
17974{
17975 v_U32_t i = 0;
17976
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053017977 pno_req->scanTimers.ucScanTimersCount = request->n_scan_plans;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017978 for (i = 0; i < request->n_scan_plans; i++)
17979 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053017980 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
17981 request->scan_plans[i].iterations;
17982 pno_req->scanTimers.aTimerValues[i].uTimerValue =
17983 request->scan_plans[i].interval;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017984 }
17985}
17986#else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053017987static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017988 struct cfg80211_sched_scan_request *request,
17989 hdd_context_t *hdd_ctx)
17990{
17991 v_U32_t i, temp_int;
17992 /* Driver gets only one time interval which is hardcoded in
17993 * supplicant for 10000ms. Taking power consumption into account 6
17994 * timers will be used, Timervalue is increased exponentially
17995 * i.e 10,20,40, 80,160,320 secs. And number of scan cycle for each
17996 * timer is configurable through INI param gPNOScanTimerRepeatValue.
17997 * If it is set to 0 only one timer will be used and PNO scan cycle
17998 * will be repeated after each interval specified by supplicant
17999 * till PNO is disabled.
18000 */
18001 if (0 == hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue)
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018002 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018003 HDD_PNO_SCAN_TIMERS_SET_ONE;
18004 else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018005 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018006 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
18007
18008 temp_int = (request->interval)/1000;
18009 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18010 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
18011 temp_int, hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue);
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018012 for ( i = 0; i < pno_req->scanTimers.ucScanTimersCount; i++)
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018013 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018014 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018015 hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue;
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018016 pno_req->scanTimers.aTimerValues[i].uTimerValue = temp_int;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018017 temp_int *= 2;
18018 }
18019 //Repeat last timer until pno disabled.
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018020 pno_req->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018021}
18022#endif
18023
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018024/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018025 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
18026 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018027 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018028static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018029 struct net_device *dev, struct cfg80211_sched_scan_request *request)
18030{
18031 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018032 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018033 hdd_context_t *pHddCtx;
18034 tHalHandle hHal;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018035 v_U32_t i, indx, num_ch, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053018036 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
18037 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018038 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
18039 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018040 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053018041 hdd_config_t *pConfig = NULL;
18042 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018043
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018044 ENTER();
18045
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018046 if (NULL == pAdapter)
18047 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018048 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018049 "%s: HDD adapter is Null", __func__);
18050 return -ENODEV;
18051 }
18052
18053 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018054 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018055
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018056 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018057 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018058 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018059 }
18060
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053018061 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018062 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
18063 if (NULL == hHal)
18064 {
18065 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18066 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018067 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018068 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018069 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18070 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
18071 pAdapter->sessionId, pAdapter->device_mode));
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053018072 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053018073 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053018074 {
18075 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18076 "%s: aborting the existing scan is unsuccessfull", __func__);
18077 return -EBUSY;
18078 }
18079
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018080 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018081 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053018082 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018083 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018084 return -EBUSY;
18085 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018086
c_hpothu37f21312014-04-09 21:49:54 +053018087 if (TRUE == pHddCtx->isPnoEnable)
18088 {
18089 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
18090 FL("already PNO is enabled"));
18091 return -EBUSY;
18092 }
c_hpothu225aa7c2014-10-22 17:45:13 +053018093
18094 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
18095 {
18096 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18097 "%s: abort ROC failed ", __func__);
18098 return -EBUSY;
18099 }
18100
c_hpothu37f21312014-04-09 21:49:54 +053018101 pHddCtx->isPnoEnable = TRUE;
18102
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018103 pnoRequest.enable = 1; /*Enable PNO */
18104 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018105
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018106 if (( !pnoRequest.ucNetworksCount ) ||
18107 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018108 {
18109 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053018110 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018111 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053018112 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018113 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018114 goto error;
18115 }
18116
18117 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
18118 {
18119 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053018120 "%s: Incorrect number of channels %d",
18121 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018122 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018123 goto error;
18124 }
18125
18126 /* Framework provides one set of channels(all)
18127 * common for all saved profile */
18128 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
18129 channels_allowed, &num_channels_allowed))
18130 {
18131 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18132 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018133 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018134 goto error;
18135 }
18136 /* Checking each channel against allowed channel list */
18137 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053018138 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018139 {
Nirav Shah80830bf2013-12-31 16:35:12 +053018140 char chList [(request->n_channels*5)+1];
18141 int len;
18142 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018143 {
Nirav Shah80830bf2013-12-31 16:35:12 +053018144 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018145 {
Nirav Shah80830bf2013-12-31 16:35:12 +053018146 if (request->channels[i]->hw_value == channels_allowed[indx])
18147 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053018148 if ((!pConfig->enableDFSPnoChnlScan) &&
18149 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
18150 {
18151 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18152 "%s : Dropping DFS channel : %d",
18153 __func__,channels_allowed[indx]);
18154 num_ignore_dfs_ch++;
18155 break;
18156 }
18157
Nirav Shah80830bf2013-12-31 16:35:12 +053018158 valid_ch[num_ch++] = request->channels[i]->hw_value;
18159 len += snprintf(chList+len, 5, "%d ",
18160 request->channels[i]->hw_value);
18161 break ;
18162 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018163 }
18164 }
Nirav Shah80830bf2013-12-31 16:35:12 +053018165 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018166
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053018167 /*If all channels are DFS and dropped, then ignore the PNO request*/
18168 if (num_ignore_dfs_ch == request->n_channels)
18169 {
18170 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18171 "%s : All requested channels are DFS channels", __func__);
18172 ret = -EINVAL;
18173 goto error;
18174 }
18175 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018176
18177 pnoRequest.aNetworks =
18178 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
18179 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018180 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018181 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
18182 FL("failed to allocate memory aNetworks %u"),
18183 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
18184 goto error;
18185 }
18186 vos_mem_zero(pnoRequest.aNetworks,
18187 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
18188
18189 /* Filling per profile params */
18190 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
18191 {
18192 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018193 request->match_sets[i].ssid.ssid_len;
18194
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018195 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
18196 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018197 {
18198 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053018199 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018200 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018201 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018202 goto error;
18203 }
18204
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018205 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018206 request->match_sets[i].ssid.ssid,
18207 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053018208 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18209 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018210 i, pnoRequest.aNetworks[i].ssId.ssId);
18211 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
18212 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
18213 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018214
18215 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018216 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
18217 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018218
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018219 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018220 }
18221
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018222 for (i = 0; i < request->n_ssids; i++)
18223 {
18224 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018225 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018226 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018227 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018228 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018229 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018230 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018231 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018232 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018233 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018234 break;
18235 }
18236 j++;
18237 }
18238 }
18239 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18240 "Number of hidden networks being Configured = %d",
18241 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053018242 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080018243 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018244
18245 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
18246 if (pnoRequest.p24GProbeTemplate == NULL)
18247 {
18248 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
18249 FL("failed to allocate memory p24GProbeTemplate %u"),
18250 SIR_PNO_MAX_PB_REQ_SIZE);
18251 goto error;
18252 }
18253
18254 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
18255 if (pnoRequest.p5GProbeTemplate == NULL)
18256 {
18257 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
18258 FL("failed to allocate memory p5GProbeTemplate %u"),
18259 SIR_PNO_MAX_PB_REQ_SIZE);
18260 goto error;
18261 }
18262
18263 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
18264 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
18265
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053018266 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
18267 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053018268 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018269 pnoRequest.us24GProbeTemplateLen = request->ie_len;
18270 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
18271 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053018272
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018273 pnoRequest.us5GProbeTemplateLen = request->ie_len;
18274 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
18275 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053018276 }
18277
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018278 hdd_config_sched_scan_plan(&pnoRequest, request, pHddCtx);
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053018279
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018280 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018281
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018282 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018283 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
18284 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018285 pAdapter->pno_req_status = 0;
18286
Nirav Shah80830bf2013-12-31 16:35:12 +053018287 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18288 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018289 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
18290 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053018291
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018292 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018293 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018294 hdd_cfg80211_sched_scan_done_callback, pAdapter);
18295 if (eHAL_STATUS_SUCCESS != status)
18296 {
18297 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053018298 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018299 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018300 goto error;
18301 }
18302
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018303 ret = wait_for_completion_timeout(
18304 &pAdapter->pno_comp_var,
18305 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
18306 if (0 >= ret)
18307 {
18308 // Did not receive the response for PNO enable in time.
18309 // Assuming the PNO enable was success.
18310 // Returning error from here, because we timeout, results
18311 // in side effect of Wifi (Wifi Setting) not to work.
18312 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18313 FL("Timed out waiting for PNO to be Enabled"));
18314 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018315 }
18316
18317 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053018318 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018319
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018320error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018321 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18322 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053018323 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018324 if (pnoRequest.aNetworks)
18325 vos_mem_free(pnoRequest.aNetworks);
18326 if (pnoRequest.p24GProbeTemplate)
18327 vos_mem_free(pnoRequest.p24GProbeTemplate);
18328 if (pnoRequest.p5GProbeTemplate)
18329 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018330
18331 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018332 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018333}
18334
18335/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018336 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
18337 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018338 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018339static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
18340 struct net_device *dev, struct cfg80211_sched_scan_request *request)
18341{
18342 int ret;
18343
18344 vos_ssr_protect(__func__);
18345 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
18346 vos_ssr_unprotect(__func__);
18347
18348 return ret;
18349}
18350
18351/*
18352 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
18353 * Function to disable PNO
18354 */
18355static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018356 struct net_device *dev)
18357{
18358 eHalStatus status = eHAL_STATUS_FAILURE;
18359 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18360 hdd_context_t *pHddCtx;
18361 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018362 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018363 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018364
18365 ENTER();
18366
18367 if (NULL == pAdapter)
18368 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018369 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018370 "%s: HDD adapter is Null", __func__);
18371 return -ENODEV;
18372 }
18373
18374 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018375
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018376 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018377 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018378 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018379 "%s: HDD context is Null", __func__);
18380 return -ENODEV;
18381 }
18382
18383 /* The return 0 is intentional when isLogpInProgress and
18384 * isLoadUnloadInProgress. We did observe a crash due to a return of
18385 * failure in sched_scan_stop , especially for a case where the unload
18386 * of the happens at the same time. The function __cfg80211_stop_sched_scan
18387 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
18388 * success. If it returns a failure , then its next invocation due to the
18389 * clean up of the second interface will have the dev pointer corresponding
18390 * to the first one leading to a crash.
18391 */
18392 if (pHddCtx->isLogpInProgress)
18393 {
18394 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18395 "%s: LOGP in Progress. Ignore!!!", __func__);
Mahesh A Saptasagar0c11d822015-10-08 19:54:08 +053018396 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018397 return ret;
18398 }
18399
Mihir Shete18156292014-03-11 15:38:30 +053018400 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018401 {
18402 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18403 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
18404 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018405 }
18406
18407 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
18408 if (NULL == hHal)
18409 {
18410 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18411 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018412 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018413 }
18414
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018415 pnoRequest.enable = 0; /* Disable PNO */
18416 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018417
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018418 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18419 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
18420 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053018421
18422 INIT_COMPLETION(pAdapter->pno_comp_var);
18423 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
18424 pnoRequest.callbackContext = pAdapter;
18425 pAdapter->pno_req_status = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018426 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018427 pAdapter->sessionId,
18428 NULL, pAdapter);
18429 if (eHAL_STATUS_SUCCESS != status)
18430 {
18431 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18432 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018433 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018434 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018435 }
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053018436 ret = wait_for_completion_timeout(
18437 &pAdapter->pno_comp_var,
18438 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
18439 if (0 >= ret)
18440 {
18441 // Did not receive the response for PNO disable in time.
18442 // Assuming the PNO disable was success.
18443 // Returning error from here, because we timeout, results
18444 // in side effect of Wifi (Wifi Setting) not to work.
Anurag Chouhan96b41cb2016-09-28 18:54:47 +053018445 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053018446 FL("Timed out waiting for PNO to be disabled"));
18447 ret = 0;
18448 }
18449
18450 ret = pAdapter->pno_req_status;
18451 pHddCtx->isPnoEnable = (ret == 0) ? FALSE : TRUE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018452
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018453error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018454 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018455 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018456
18457 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018458 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018459}
18460
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018461/*
18462 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
18463 * NL interface to disable PNO
18464 */
18465static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
18466 struct net_device *dev)
18467{
18468 int ret;
18469
18470 vos_ssr_protect(__func__);
18471 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
18472 vos_ssr_unprotect(__func__);
18473
18474 return ret;
18475}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018476#endif /*FEATURE_WLAN_SCAN_PNO*/
18477
18478
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018479#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018480#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018481static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18482 struct net_device *dev,
18483 u8 *peer, u8 action_code,
18484 u8 dialog_token,
18485 u16 status_code, u32 peer_capability,
18486 const u8 *buf, size_t len)
18487#else /* TDLS_MGMT_VERSION2 */
18488#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
18489static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18490 struct net_device *dev,
18491 const u8 *peer, u8 action_code,
18492 u8 dialog_token, u16 status_code,
18493 u32 peer_capability, bool initiator,
18494 const u8 *buf, size_t len)
18495#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
18496static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18497 struct net_device *dev,
18498 const u8 *peer, u8 action_code,
18499 u8 dialog_token, u16 status_code,
18500 u32 peer_capability, const u8 *buf,
18501 size_t len)
18502#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
18503static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18504 struct net_device *dev,
18505 u8 *peer, u8 action_code,
18506 u8 dialog_token,
18507 u16 status_code, u32 peer_capability,
18508 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018509#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018510static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18511 struct net_device *dev,
18512 u8 *peer, u8 action_code,
18513 u8 dialog_token,
18514 u16 status_code, const u8 *buf,
18515 size_t len)
18516#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018517#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018518{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018519 hdd_adapter_t *pAdapter;
18520 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018521 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070018522 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080018523 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070018524 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018525 int ret;
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053018526 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018527#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018528 u32 peer_capability = 0;
18529#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053018530 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018531 hdd_station_ctx_t *pHddStaCtx = NULL;
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053018532 tdlsCtx_t *pHddTdlsCtx;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018533
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018534 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18535 if (NULL == pAdapter)
18536 {
18537 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18538 "%s: Adapter is NULL",__func__);
18539 return -EINVAL;
18540 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018541 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18542 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
18543 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018544
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018545 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018546 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018547 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018548 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018549 "Invalid arguments");
18550 return -EINVAL;
18551 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018552
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080018553 if (pHddCtx->isLogpInProgress)
18554 {
18555 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18556 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053018557 wlan_hdd_tdls_set_link_status(pAdapter,
18558 peer,
18559 eTDLS_LINK_IDLE,
18560 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080018561 return -EBUSY;
18562 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018563
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018564 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
18565 {
18566 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18567 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
18568 return -EAGAIN;
18569 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018570
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053018571 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
18572 if (!pHddTdlsCtx) {
18573 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18574 "%s: pHddTdlsCtx not valid.", __func__);
18575 }
18576
Hoonki Lee27511902013-03-14 18:19:06 -070018577 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018578 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018579 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070018580 "%s: TDLS mode is disabled OR not enabled in FW."
18581 MAC_ADDRESS_STR " action %d declined.",
18582 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018583 return -ENOTSUPP;
18584 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018585
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018586 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18587
18588 if( NULL == pHddStaCtx )
18589 {
18590 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18591 "%s: HDD station context NULL ",__func__);
18592 return -EINVAL;
18593 }
18594
18595 /* STA should be connected and authenticated
18596 * before sending any TDLS frames
18597 */
18598 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
18599 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
18600 {
18601 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18602 "STA is not connected or unauthenticated. "
18603 "connState %u, uIsAuthenticated %u",
18604 pHddStaCtx->conn_info.connState,
18605 pHddStaCtx->conn_info.uIsAuthenticated);
18606 return -EAGAIN;
18607 }
18608
Hoonki Lee27511902013-03-14 18:19:06 -070018609 /* other than teardown frame, other mgmt frames are not sent if disabled */
18610 if (SIR_MAC_TDLS_TEARDOWN != action_code)
18611 {
18612 /* if tdls_mode is disabled to respond to peer's request */
18613 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
18614 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018615 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070018616 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070018617 " TDLS mode is disabled. action %d declined.",
18618 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070018619
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018620 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070018621 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053018622
18623 if (vos_max_concurrent_connections_reached())
18624 {
18625 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
18626 return -EINVAL;
18627 }
Hoonki Lee27511902013-03-14 18:19:06 -070018628 }
18629
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018630 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
18631 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053018632 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018633 {
18634 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018635 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070018636 " TDLS setup is ongoing. action %d declined.",
18637 __func__, MAC_ADDR_ARRAY(peer), action_code);
18638 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018639 }
18640 }
18641
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018642 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
18643 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080018644 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053018645 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
18646 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080018647 {
18648 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
18649 we return error code at 'add_station()'. Hence we have this
18650 check again in addtion to add_station().
18651 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018652 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080018653 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018654 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18655 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053018656 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
18657 __func__, MAC_ADDR_ARRAY(peer), action_code,
18658 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053018659 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080018660 }
18661 else
18662 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018663 /* maximum reached. tweak to send error code to peer and return
18664 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080018665 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018666 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18667 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053018668 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
18669 __func__, MAC_ADDR_ARRAY(peer), status_code,
18670 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070018671 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018672 /* fall through to send setup resp with failure status
18673 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080018674 }
18675 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018676 else
18677 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018678 mutex_lock(&pHddCtx->tdls_lock);
18679 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018680 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018681 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018682 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018683 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070018684 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
18685 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018686 return -EPERM;
18687 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018688 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018689 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018690 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018691
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018692 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053018693 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018694 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
18695 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018696
Hoonki Leea34dd892013-02-05 22:56:02 -080018697 /*Except teardown responder will not be used so just make 0*/
18698 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018699 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080018700 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070018701
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018702 mutex_lock(&pHddCtx->tdls_lock);
18703 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070018704
18705 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
18706 responder = pTdlsPeer->is_responder;
18707 else
Hoonki Leea34dd892013-02-05 22:56:02 -080018708 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070018709 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053018710 "%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 -070018711 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
18712 dialog_token, status_code, len);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018713 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070018714 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080018715 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018716 mutex_unlock(&pHddCtx->tdls_lock);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018717 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018718
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053018719 /* Discard TDLS setup if peer is removed by user app */
18720 if ((pHddCtx->cfg_ini->fTDLSExternalControl) &&
18721 ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
18722 (SIR_MAC_TDLS_SETUP_CNF == action_code) ||
18723 (SIR_MAC_TDLS_DIS_REQ == action_code))) {
18724
18725 mutex_lock(&pHddCtx->tdls_lock);
18726 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18727 if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) {
18728 mutex_unlock(&pHddCtx->tdls_lock);
18729 hddLog(LOGE, FL("TDLS External Control enabled, but peer "
18730 MAC_ADDRESS_STR " is not forced, so reject the action code %d"),
18731 MAC_ADDR_ARRAY(peer), action_code);
18732 return -EINVAL;
18733 }
18734 mutex_unlock(&pHddCtx->tdls_lock);
18735 }
18736
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053018737 /* For explicit trigger of DIS_REQ come out of BMPS for
18738 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070018739 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Deepthi Gowrif78f1f72016-03-21 13:13:28 +053018740 (SIR_MAC_TDLS_SETUP_CNF== action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053018741 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
18742 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070018743 {
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053018744 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter))) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018745 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053018746 "%s: Sending frame action_code %u.Disable BMPS", __func__,
18747 action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018748 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
18749 if (status != VOS_STATUS_SUCCESS) {
18750 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053018751 } else {
18752 pHddTdlsCtx->is_tdls_disabled_bmps = true;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018753 }
Hoonki Lee14621352013-04-16 17:51:19 -070018754 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018755 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018756 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018757 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
18758 }
18759 }
Hoonki Lee14621352013-04-16 17:51:19 -070018760 }
18761
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018762 /* make sure doesn't call send_mgmt() while it is pending */
18763 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
18764 {
18765 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080018766 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018767 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018768 ret = -EBUSY;
18769 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018770 }
18771
18772 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018773 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
18774
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018775 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
18776 pAdapter->sessionId, peer, action_code, dialog_token,
18777 status_code, peer_capability, (tANI_U8 *)buf, len,
18778 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018779
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018780 if (VOS_STATUS_SUCCESS != status)
18781 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018782 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18783 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018784 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018785 ret = -EINVAL;
18786 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018787 }
18788
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018789 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18790 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
18791 WAIT_TIME_TDLS_MGMT);
18792
Hoonki Leed37cbb32013-04-20 00:31:14 -070018793 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
18794 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
18795
18796 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018797 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070018798 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070018799 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070018800 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018801 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080018802
18803 if (pHddCtx->isLogpInProgress)
18804 {
18805 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18806 "%s: LOGP in Progress. Ignore!!!", __func__);
18807 return -EAGAIN;
18808 }
Abhishek Singh837adf22015-10-01 17:37:37 +053018809 if (rc <= 0)
18810 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
18811 WLAN_LOG_INDICATOR_HOST_DRIVER,
18812 WLAN_LOG_REASON_HDD_TIME_OUT,
18813 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080018814
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018815 ret = -EINVAL;
18816 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018817 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018818 else
18819 {
18820 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18821 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
18822 __func__, rc, pAdapter->mgmtTxCompletionStatus);
18823 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018824
Gopichand Nakkala05922802013-03-14 12:23:19 -070018825 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070018826 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018827 ret = max_sta_failed;
18828 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070018829 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018830
Hoonki Leea34dd892013-02-05 22:56:02 -080018831 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
18832 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018833 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018834 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
18835 }
Hoonki Leea34dd892013-02-05 22:56:02 -080018836 }
18837 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
18838 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018839 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018840 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
18841 }
Hoonki Leea34dd892013-02-05 22:56:02 -080018842 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018843
18844 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018845
18846tx_failed:
18847 /* add_station will be called before sending TDLS_SETUP_REQ and
18848 * TDLS_SETUP_RSP and as part of add_station driver will enable
18849 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
18850 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
18851 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
18852 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
18853 */
18854
18855 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
18856 (SIR_MAC_TDLS_SETUP_RSP == action_code))
18857 wlan_hdd_tdls_check_bmps(pAdapter);
18858 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018859}
18860
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018861#if TDLS_MGMT_VERSION2
18862static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
18863 u8 *peer, u8 action_code, u8 dialog_token,
18864 u16 status_code, u32 peer_capability,
18865 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018866#else /* TDLS_MGMT_VERSION2 */
18867#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
18868static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18869 struct net_device *dev,
18870 const u8 *peer, u8 action_code,
18871 u8 dialog_token, u16 status_code,
18872 u32 peer_capability, bool initiator,
18873 const u8 *buf, size_t len)
18874#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18875static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18876 struct net_device *dev,
18877 const u8 *peer, u8 action_code,
18878 u8 dialog_token, u16 status_code,
18879 u32 peer_capability, const u8 *buf,
18880 size_t len)
18881#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
18882static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18883 struct net_device *dev,
18884 u8 *peer, u8 action_code,
18885 u8 dialog_token,
18886 u16 status_code, u32 peer_capability,
18887 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018888#else
18889static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
18890 u8 *peer, u8 action_code, u8 dialog_token,
18891 u16 status_code, const u8 *buf, size_t len)
18892#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018893#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018894{
18895 int ret;
18896
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018897 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018898#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018899 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
18900 dialog_token, status_code,
18901 peer_capability, buf, len);
18902#else /* TDLS_MGMT_VERSION2 */
18903#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
18904 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
18905 dialog_token, status_code,
18906 peer_capability, initiator,
18907 buf, len);
18908#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
18909 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
18910 dialog_token, status_code,
18911 peer_capability, buf, len);
18912#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
18913 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
18914 dialog_token, status_code,
18915 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018916#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018917 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
18918 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018919#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018920#endif
18921 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018922
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018923 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018924}
Atul Mittal115287b2014-07-08 13:26:33 +053018925
18926int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018927#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18928 const u8 *peer,
18929#else
Atul Mittal115287b2014-07-08 13:26:33 +053018930 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018931#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018932 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053018933 cfg80211_exttdls_callback callback)
18934{
18935
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018936 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053018937 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053018938 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053018939 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18940 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
18941 __func__, MAC_ADDR_ARRAY(peer));
18942
18943 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
18944 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
18945
18946 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018947 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
18948 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
18949 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053018950 return -ENOTSUPP;
18951 }
18952
18953 /* To cater the requirement of establishing the TDLS link
18954 * irrespective of the data traffic , get an entry of TDLS peer.
18955 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053018956 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053018957 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
18958 if (pTdlsPeer == NULL) {
18959 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18960 "%s: peer " MAC_ADDRESS_STR " not existing",
18961 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053018962 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053018963 return -EINVAL;
18964 }
18965
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053018966 /* check FW TDLS Off Channel capability */
18967 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053018968 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053018969 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018970 {
18971 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
18972 pTdlsPeer->peerParams.global_operating_class =
18973 tdls_peer_params->global_operating_class;
18974 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
18975 pTdlsPeer->peerParams.min_bandwidth_kbps =
18976 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053018977 /* check configured channel is valid, non dfs and
18978 * not current operating channel */
18979 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
18980 tdls_peer_params->channel)) &&
18981 (pHddStaCtx) &&
18982 (tdls_peer_params->channel !=
18983 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018984 {
18985 pTdlsPeer->isOffChannelConfigured = TRUE;
18986 }
18987 else
18988 {
18989 pTdlsPeer->isOffChannelConfigured = FALSE;
18990 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18991 "%s: Configured Tdls Off Channel is not valid", __func__);
18992
18993 }
18994 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053018995 "%s: tdls_off_channel %d isOffChannelConfigured %d "
18996 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018997 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053018998 pTdlsPeer->isOffChannelConfigured,
18999 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019000 }
19001 else
19002 {
19003 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053019004 "%s: TDLS off channel FW capability %d, "
19005 "host capab %d or Invalid TDLS Peer Params", __func__,
19006 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
19007 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019008 }
19009
Atul Mittal115287b2014-07-08 13:26:33 +053019010 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
19011
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019012 mutex_unlock(&pHddCtx->tdls_lock);
19013
Atul Mittal115287b2014-07-08 13:26:33 +053019014 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19015 " %s TDLS Add Force Peer Failed",
19016 __func__);
19017 return -EINVAL;
19018 }
19019 /*EXT TDLS*/
19020
19021 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019022 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019023 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19024 " %s TDLS set callback Failed",
19025 __func__);
19026 return -EINVAL;
19027 }
19028
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019029 mutex_unlock(&pHddCtx->tdls_lock);
19030
Atul Mittal115287b2014-07-08 13:26:33 +053019031 return(0);
19032
19033}
19034
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019035int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
19036#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19037 const u8 *peer
19038#else
19039 u8 *peer
19040#endif
19041)
Atul Mittal115287b2014-07-08 13:26:33 +053019042{
19043
19044 hddTdlsPeer_t *pTdlsPeer;
19045 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053019046
Atul Mittal115287b2014-07-08 13:26:33 +053019047 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19048 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
19049 __func__, MAC_ADDR_ARRAY(peer));
19050
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053019051 if (0 != wlan_hdd_validate_context(pHddCtx)) {
19052 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
19053 return -EINVAL;
19054 }
19055
Atul Mittal115287b2014-07-08 13:26:33 +053019056 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
19057 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
19058
19059 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019060 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
19061 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
19062 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053019063 return -ENOTSUPP;
19064 }
19065
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019066 mutex_lock(&pHddCtx->tdls_lock);
19067 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Atul Mittal115287b2014-07-08 13:26:33 +053019068
19069 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019070 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019071 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019072 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053019073 __func__, MAC_ADDR_ARRAY(peer));
19074 return -EINVAL;
19075 }
19076 else {
19077 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
19078 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053019079 hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_EXT_CTRL,
19080 pTdlsPeer->peerMac);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019081 /* if channel switch is configured, reset
19082 the channel for this peer */
19083 if (TRUE == pTdlsPeer->isOffChannelConfigured)
19084 {
19085 pTdlsPeer->peerParams.channel = 0;
19086 pTdlsPeer->isOffChannelConfigured = FALSE;
19087 }
Atul Mittal115287b2014-07-08 13:26:33 +053019088 }
19089
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019090 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019091 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019092 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053019093 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019094 }
Atul Mittal115287b2014-07-08 13:26:33 +053019095
19096 /*EXT TDLS*/
19097
19098 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019099 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019100 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19101 " %s TDLS set callback Failed",
19102 __func__);
19103 return -EINVAL;
19104 }
Atul Mittal115287b2014-07-08 13:26:33 +053019105
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019106 mutex_unlock(&pHddCtx->tdls_lock);
19107
19108 return(0);
Atul Mittal115287b2014-07-08 13:26:33 +053019109}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019110static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019111#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19112 const u8 *peer,
19113#else
19114 u8 *peer,
19115#endif
19116 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019117{
19118 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19119 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019120 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019121 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019122
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019123 ENTER();
19124
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053019125 if (!pAdapter) {
19126 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
19127 return -EINVAL;
19128 }
19129
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019130 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19131 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
19132 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019133 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019134 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019135 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070019136 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019137 return -EINVAL;
19138 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080019139
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019140 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019141 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080019142 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019143 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080019144 }
19145
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019146
19147 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080019148 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019149 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080019150 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019151 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
19152 "Cannot process TDLS commands",
19153 pHddCtx->cfg_ini->fEnableTDLSSupport,
19154 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019155 return -ENOTSUPP;
19156 }
19157
19158 switch (oper) {
19159 case NL80211_TDLS_ENABLE_LINK:
19160 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019161 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019162 long ret;
Hanumantha Reddy Pothulada389492016-02-11 17:29:27 +053019163 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams = { {0}, 0,
19164 0, 0, 0, 0, 0, 0, {0}, 0, {0} };
Agarwal Ashish16020c42014-12-29 22:01:11 +053019165 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019166 tANI_U16 numCurrTdlsPeers = 0;
19167 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053019168 tANI_U8 suppChannelLen = 0;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019169 tSirMacAddr peerMac;
19170 int channel;
19171 tTDLSLinkStatus peer_status = eTDLS_LINK_IDLE;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019172
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019173 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19174 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
19175 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019176
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019177 mutex_lock(&pHddCtx->tdls_lock);
19178 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053019179 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053019180 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019181 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053019182 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
19183 " (oper %d) not exsting. ignored",
19184 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
19185 return -EINVAL;
19186 }
19187
19188 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19189 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
19190 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
19191 "NL80211_TDLS_ENABLE_LINK");
19192
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070019193 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
19194 {
19195 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
19196 MAC_ADDRESS_STR " failed",
19197 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019198 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070019199 return -EINVAL;
19200 }
19201
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053019202 /* before starting tdls connection, set tdls
19203 * off channel established status to default value */
19204 pTdlsPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019205
19206 mutex_unlock(&pHddCtx->tdls_lock);
19207
Deepthi Gowri2d85bbf2016-07-25 15:43:31 +053019208 wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019209 /* TDLS Off Channel, Disable tdls channel switch,
19210 when there are more than one tdls link */
19211 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053019212 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019213 {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019214 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019215 /* get connected peer and send disable tdls off chan */
19216 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019217 if ((connPeer) &&
19218 (connPeer->isOffChannelSupported == TRUE) &&
19219 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019220 {
19221 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19222 "%s: More then one peer connected, Disable "
19223 "TDLS channel switch", __func__);
19224
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053019225 connPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019226 vos_mem_copy(peerMac, connPeer->peerMac, sizeof (tSirMacAddr));
19227 channel = connPeer->peerParams.channel;
19228
19229 mutex_unlock(&pHddCtx->tdls_lock);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019230
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019231 ret = sme_SendTdlsChanSwitchReq(
19232 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019233 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019234 peerMac,
19235 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019236 TDLS_OFF_CHANNEL_BW_OFFSET,
19237 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019238 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019239 hddLog(VOS_TRACE_LEVEL_ERROR,
19240 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019241 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019242 }
19243 else
19244 {
19245 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19246 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019247 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019248 "isOffChannelConfigured %d",
19249 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019250 (connPeer ? (connPeer->isOffChannelSupported)
19251 : -1),
19252 (connPeer ? (connPeer->isOffChannelConfigured)
19253 : -1));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019254 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019255 }
19256 }
19257
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019258 mutex_lock(&pHddCtx->tdls_lock);
19259 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
19260 if ( NULL == pTdlsPeer ) {
19261 mutex_unlock(&pHddCtx->tdls_lock);
19262 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19263 "%s: " MAC_ADDRESS_STR
19264 " (oper %d) peer got freed in other context. ignored",
19265 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
19266 return -EINVAL;
19267 }
19268 peer_status = pTdlsPeer->link_status;
19269 mutex_unlock(&pHddCtx->tdls_lock);
19270
19271 if (eTDLS_LINK_CONNECTED != peer_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019272 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019273 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053019274
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019275 if (0 != wlan_hdd_tdls_get_link_establish_params(
19276 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019277 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019278 return -EINVAL;
19279 }
19280 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053019281
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019282 ret = sme_SendTdlsLinkEstablishParams(
19283 WLAN_HDD_GET_HAL_CTX(pAdapter),
19284 pAdapter->sessionId, peer,
19285 &tdlsLinkEstablishParams);
19286 if (ret != VOS_STATUS_SUCCESS) {
19287 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
19288 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019289 /* Send TDLS peer UAPSD capabilities to the firmware and
19290 * register with the TL on after the response for this operation
19291 * is received .
19292 */
19293 ret = wait_for_completion_interruptible_timeout(
19294 &pAdapter->tdls_link_establish_req_comp,
19295 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
Masti, Narayanraddie1892a52015-12-15 15:01:01 +053019296
19297 mutex_lock(&pHddCtx->tdls_lock);
19298 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
19299 if ( NULL == pTdlsPeer ) {
19300 mutex_unlock(&pHddCtx->tdls_lock);
19301 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19302 "%s %d: " MAC_ADDRESS_STR
19303 " (oper %d) peer got freed in other context. ignored",
19304 __func__, __LINE__, MAC_ADDR_ARRAY(peer),
19305 (int)oper);
19306 return -EINVAL;
19307 }
19308 peer_status = pTdlsPeer->link_status;
19309 mutex_unlock(&pHddCtx->tdls_lock);
19310
19311 if (ret <= 0 || (peer_status == eTDLS_LINK_TEARING))
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019312 {
19313 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019314 FL("Link Establish Request Failed Status %ld"),
19315 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019316 return -EINVAL;
19317 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053019318 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019319
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019320 mutex_lock(&pHddCtx->tdls_lock);
19321 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
19322 if ( NULL == pTdlsPeer ) {
19323 mutex_unlock(&pHddCtx->tdls_lock);
19324 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19325 "%s: " MAC_ADDRESS_STR
19326 " (oper %d) peer got freed in other context. ignored",
19327 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
19328 return -EINVAL;
19329 }
19330
Atul Mittal115287b2014-07-08 13:26:33 +053019331 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
19332 eTDLS_LINK_CONNECTED,
19333 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053019334 staDesc.ucSTAId = pTdlsPeer->staId;
19335 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053019336
19337 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19338 "%s: tdlsLinkEstablishParams of peer "
19339 MAC_ADDRESS_STR "uapsdQueues: %d"
19340 "qos: %d maxSp: %d isBufSta: %d isOffChannelSupported: %d"
19341 "isResponder: %d peerstaId: %d",
19342 __func__,
19343 MAC_ADDR_ARRAY(tdlsLinkEstablishParams.peerMac),
19344 tdlsLinkEstablishParams.uapsdQueues,
19345 tdlsLinkEstablishParams.qos,
19346 tdlsLinkEstablishParams.maxSp,
19347 tdlsLinkEstablishParams.isBufSta,
19348 tdlsLinkEstablishParams.isOffChannelSupported,
19349 tdlsLinkEstablishParams.isResponder,
19350 pTdlsPeer->staId);
19351
19352 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19353 "%s: StaDesc ucSTAId: %d ucQosEnabled: %d",
19354 __func__,
19355 staDesc.ucSTAId,
19356 staDesc.ucQosEnabled);
19357
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019358 ret = WLANTL_UpdateTdlsSTAClient(
19359 pHddCtx->pvosContext,
19360 &staDesc);
19361 if (ret != VOS_STATUS_SUCCESS) {
19362 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
19363 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053019364
Gopichand Nakkala471708b2013-06-04 20:03:01 +053019365 /* Mark TDLS client Authenticated .*/
19366 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
19367 pTdlsPeer->staId,
19368 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070019369 if (VOS_STATUS_SUCCESS == status)
19370 {
Hoonki Lee14621352013-04-16 17:51:19 -070019371 if (pTdlsPeer->is_responder == 0)
19372 {
19373 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053019374 tdlsConnInfo_t *tdlsInfo;
19375
19376 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
19377
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053019378 if (!vos_timer_is_initialized(
19379 &pTdlsPeer->initiatorWaitTimeoutTimer))
19380 {
19381 /* Initialize initiator wait callback */
19382 vos_timer_init(
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053019383 &pTdlsPeer->initiatorWaitTimeoutTimer,
19384 VOS_TIMER_TYPE_SW,
19385 wlan_hdd_tdls_initiator_wait_cb,
19386 tdlsInfo);
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053019387 }
Hoonki Lee14621352013-04-16 17:51:19 -070019388 wlan_hdd_tdls_timer_restart(pAdapter,
19389 &pTdlsPeer->initiatorWaitTimeoutTimer,
19390 WAIT_TIME_TDLS_INITIATOR);
19391 /* suspend initiator TX until it receives direct packet from the
19392 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019393 ret = WLANTL_SuspendDataTx(
19394 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
19395 &staId, NULL);
19396 if (ret != VOS_STATUS_SUCCESS) {
19397 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
19398 }
Hoonki Lee14621352013-04-16 17:51:19 -070019399 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019400
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053019401 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019402 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053019403 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019404 suppChannelLen =
19405 tdlsLinkEstablishParams.supportedChannelsLen;
19406
19407 if ((suppChannelLen > 0) &&
19408 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
19409 {
19410 tANI_U8 suppPeerChannel = 0;
19411 int i = 0;
19412 for (i = 0U; i < suppChannelLen; i++)
19413 {
19414 suppPeerChannel =
19415 tdlsLinkEstablishParams.supportedChannels[i];
19416
19417 pTdlsPeer->isOffChannelSupported = FALSE;
19418 if (suppPeerChannel ==
19419 pTdlsPeer->peerParams.channel)
19420 {
19421 pTdlsPeer->isOffChannelSupported = TRUE;
19422 break;
19423 }
19424 }
19425 }
19426 else
19427 {
19428 pTdlsPeer->isOffChannelSupported = FALSE;
19429 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053019430 }
19431 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19432 "%s: TDLS channel switch request for channel "
19433 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019434 "%d isOffChannelSupported %d", __func__,
19435 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053019436 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019437 suppChannelLen,
19438 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053019439
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019440 /* TDLS Off Channel, Enable tdls channel switch,
19441 when their is only one tdls link and it supports */
19442 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
19443 if ((numCurrTdlsPeers == 1) &&
19444 (TRUE == pTdlsPeer->isOffChannelSupported) &&
19445 (TRUE == pTdlsPeer->isOffChannelConfigured))
19446 {
19447 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19448 "%s: Send TDLS channel switch request for channel %d",
19449 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053019450
19451 pTdlsPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019452 vos_mem_copy(peerMac, pTdlsPeer->peerMac, sizeof (tSirMacAddr));
19453 channel = pTdlsPeer->peerParams.channel;
19454
19455 mutex_unlock(&pHddCtx->tdls_lock);
19456
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019457 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
19458 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019459 peerMac,
19460 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019461 TDLS_OFF_CHANNEL_BW_OFFSET,
19462 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019463 if (ret != VOS_STATUS_SUCCESS) {
19464 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
19465 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019466 }
19467 else
19468 {
19469 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19470 "%s: TDLS channel switch request not sent"
19471 " numCurrTdlsPeers %d "
19472 "isOffChannelSupported %d "
19473 "isOffChannelConfigured %d",
19474 __func__, numCurrTdlsPeers,
19475 pTdlsPeer->isOffChannelSupported,
19476 pTdlsPeer->isOffChannelConfigured);
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019477 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019478 }
19479
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070019480 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019481 else
19482 mutex_unlock(&pHddCtx->tdls_lock);
19483
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019484 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053019485
19486 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053019487 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
19488 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053019489 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053019490 int ac;
19491 uint8 ucAc[4] = { WLANTL_AC_VO,
19492 WLANTL_AC_VI,
19493 WLANTL_AC_BK,
19494 WLANTL_AC_BE };
19495 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
19496 for(ac=0; ac < 4; ac++)
19497 {
19498 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
19499 pTdlsPeer->staId, ucAc[ac],
19500 tlTid[ac], tlTid[ac], 0, 0,
19501 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019502 if (status != VOS_STATUS_SUCCESS) {
19503 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
19504 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053019505 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053019506 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019507 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019508
Bhargav Shah66896792015-10-01 18:17:37 +053019509 /* stop TCP delack timer if TDLS is enable */
19510 set_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
19511 hdd_manage_delack_timer(pHddCtx);
Abhishek Singh67fa6bc2016-01-05 15:57:19 +053019512 hdd_wlan_tdls_enable_link_event(peer,
19513 pTdlsPeer->isOffChannelSupported,
19514 pTdlsPeer->isOffChannelConfigured,
19515 pTdlsPeer->isOffChannelEstablished);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019516 }
19517 break;
19518 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080019519 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019520 tANI_U16 numCurrTdlsPeers = 0;
19521 hddTdlsPeer_t *connPeer = NULL;
19522
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019523 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19524 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
19525 __func__, MAC_ADDR_ARRAY(peer));
19526
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019527 mutex_lock(&pHddCtx->tdls_lock);
19528 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Sunil Dutt41de4e22013-11-14 18:09:02 +053019529
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019530
Sunil Dutt41de4e22013-11-14 18:09:02 +053019531 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019532 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053019533 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
19534 " (oper %d) not exsting. ignored",
19535 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
19536 return -EINVAL;
19537 }
19538
19539 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19540 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
19541 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
19542 "NL80211_TDLS_DISABLE_LINK");
19543
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019544 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080019545 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019546 long status;
19547
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053019548 /* set tdls off channel status to false for this peer */
19549 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053019550 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
19551 eTDLS_LINK_TEARING,
19552 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
19553 eTDLS_LINK_UNSPECIFIED:
19554 eTDLS_LINK_DROPPED_BY_REMOTE);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019555 mutex_unlock(&pHddCtx->tdls_lock);
19556
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019557 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
19558
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019559 status = sme_DeleteTdlsPeerSta(
19560 WLAN_HDD_GET_HAL_CTX(pAdapter),
19561 pAdapter->sessionId, peer );
19562 if (status != VOS_STATUS_SUCCESS) {
19563 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
19564 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019565
19566 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
19567 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019568
19569 mutex_lock(&pHddCtx->tdls_lock);
19570 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
19571 if ( NULL == pTdlsPeer ) {
19572 mutex_unlock(&pHddCtx->tdls_lock);
19573 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
19574 " peer was freed in other context",
19575 __func__, MAC_ADDR_ARRAY(peer));
19576 return -EINVAL;
19577 }
19578
Atul Mittal271a7652014-09-12 13:18:22 +053019579 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053019580 eTDLS_LINK_IDLE,
19581 eTDLS_LINK_UNSPECIFIED);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019582 mutex_unlock(&pHddCtx->tdls_lock);
19583
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019584 if (status <= 0)
19585 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019586 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19587 "%s: Del station failed status %ld",
19588 __func__, status);
19589 return -EPERM;
19590 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019591
19592 /* TDLS Off Channel, Enable tdls channel switch,
19593 when their is only one tdls link and it supports */
19594 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
19595 if (numCurrTdlsPeers == 1)
19596 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019597 tSirMacAddr peerMac;
19598 int channel;
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053019599
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019600 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019601 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053019602
19603 if (connPeer == NULL) {
19604 mutex_unlock(&pHddCtx->tdls_lock);
19605 hddLog(VOS_TRACE_LEVEL_ERROR,
19606 "%s connPeer is NULL", __func__);
19607 return -EINVAL;
19608 }
19609
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019610 vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr));
19611 channel = connPeer->peerParams.channel;
19612
19613 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19614 "%s: TDLS channel switch "
19615 "isOffChannelSupported %d "
19616 "isOffChannelConfigured %d "
19617 "isOffChannelEstablished %d",
19618 __func__,
19619 (connPeer ? connPeer->isOffChannelSupported : -1),
19620 (connPeer ? connPeer->isOffChannelConfigured : -1),
19621 (connPeer ? connPeer->isOffChannelEstablished : -1));
19622
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019623 if ((connPeer) &&
19624 (connPeer->isOffChannelSupported == TRUE) &&
19625 (connPeer->isOffChannelConfigured == TRUE))
19626 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053019627 connPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019628 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019629 status = sme_SendTdlsChanSwitchReq(
19630 WLAN_HDD_GET_HAL_CTX(pAdapter),
19631 pAdapter->sessionId,
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019632 peerMac,
19633 channel,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019634 TDLS_OFF_CHANNEL_BW_OFFSET,
19635 TDLS_CHANNEL_SWITCH_ENABLE);
19636 if (status != VOS_STATUS_SUCCESS) {
19637 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
19638 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019639 }
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019640 else
19641 mutex_unlock(&pHddCtx->tdls_lock);
19642 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019643 else
19644 {
19645 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19646 "%s: TDLS channel switch request not sent "
19647 "numCurrTdlsPeers %d ",
19648 __func__, numCurrTdlsPeers);
19649 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080019650 }
19651 else
19652 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019653 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019654 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19655 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080019656 }
Bhargav Shah66896792015-10-01 18:17:37 +053019657 if (numCurrTdlsPeers == 0) {
19658 /* start TCP delack timer if TDLS is disable */
19659 clear_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
19660 hdd_manage_delack_timer(pHddCtx);
19661 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080019662 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019663 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019664 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053019665 {
Atul Mittal115287b2014-07-08 13:26:33 +053019666 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053019667
Atul Mittal115287b2014-07-08 13:26:33 +053019668 if (0 != status)
19669 {
19670 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019671 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053019672 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053019673 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053019674 break;
19675 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019676 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053019677 {
Atul Mittal115287b2014-07-08 13:26:33 +053019678 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
19679 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019680 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053019681 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053019682
Atul Mittal115287b2014-07-08 13:26:33 +053019683 if (0 != status)
19684 {
19685 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019686 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053019687 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053019688 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053019689 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053019690 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019691 case NL80211_TDLS_DISCOVERY_REQ:
19692 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019693 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019694 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019695 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019696 return -ENOTSUPP;
19697 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019698 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19699 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019700 return -ENOTSUPP;
19701 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019702
19703 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019704 return 0;
19705}
Chilam NG571c65a2013-01-19 12:27:36 +053019706
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019707static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019708#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19709 const u8 *peer,
19710#else
19711 u8 *peer,
19712#endif
19713 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019714{
19715 int ret;
19716
19717 vos_ssr_protect(__func__);
19718 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
19719 vos_ssr_unprotect(__func__);
19720
19721 return ret;
19722}
19723
Chilam NG571c65a2013-01-19 12:27:36 +053019724int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
19725 struct net_device *dev, u8 *peer)
19726{
Arif Hussaina7c8e412013-11-20 11:06:42 -080019727 hddLog(VOS_TRACE_LEVEL_INFO,
19728 "tdls send discover req: "MAC_ADDRESS_STR,
19729 MAC_ADDR_ARRAY(peer));
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019730#if TDLS_MGMT_VERSION2
19731 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19732 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
19733#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019734#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
19735 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19736 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
19737#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
19738 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19739 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
19740#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
19741 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19742 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
19743#else
Chilam NG571c65a2013-01-19 12:27:36 +053019744 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19745 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019746#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019747#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053019748}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019749#endif
19750
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019751#ifdef WLAN_FEATURE_GTK_OFFLOAD
19752/*
19753 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
19754 * Callback rountine called upon receiving response for
19755 * get offload info
19756 */
19757void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
19758 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
19759{
19760
19761 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019762 tANI_U8 tempReplayCounter[8];
19763 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019764
19765 ENTER();
19766
19767 if (NULL == pAdapter)
19768 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053019769 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019770 "%s: HDD adapter is Null", __func__);
19771 return ;
19772 }
19773
19774 if (NULL == pGtkOffloadGetInfoRsp)
19775 {
19776 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19777 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
19778 return ;
19779 }
19780
19781 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
19782 {
19783 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19784 "%s: wlan Failed to get replay counter value",
19785 __func__);
19786 return ;
19787 }
19788
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019789 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
19790 /* Update replay counter */
19791 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
19792 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
19793
19794 {
19795 /* changing from little to big endian since supplicant
19796 * works on big endian format
19797 */
19798 int i;
19799 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
19800
19801 for (i = 0; i < 8; i++)
19802 {
19803 tempReplayCounter[7-i] = (tANI_U8)p[i];
19804 }
19805 }
19806
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019807 /* Update replay counter to NL */
19808 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019809 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019810}
19811
19812/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019813 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019814 * This function is used to offload GTK rekeying job to the firmware.
19815 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019816int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019817 struct cfg80211_gtk_rekey_data *data)
19818{
19819 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19820 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
19821 hdd_station_ctx_t *pHddStaCtx;
19822 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019823 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019824 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019825 eHalStatus status = eHAL_STATUS_FAILURE;
19826
19827 ENTER();
19828
19829 if (NULL == pAdapter)
19830 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019831 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019832 "%s: HDD adapter is Null", __func__);
19833 return -ENODEV;
19834 }
19835
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019836 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19837 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
19838 pAdapter->sessionId, pAdapter->device_mode));
19839
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019840 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019841 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019842 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019843 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019844 }
19845
19846 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
19847 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
19848 if (NULL == hHal)
19849 {
19850 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19851 "%s: HAL context is Null!!!", __func__);
19852 return -EAGAIN;
19853 }
19854
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019855 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
19856 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
19857 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
19858 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019859 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019860 {
19861 /* changing from big to little endian since driver
19862 * works on little endian format
19863 */
19864 tANI_U8 *p =
19865 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
19866 int i;
19867
19868 for (i = 0; i < 8; i++)
19869 {
19870 p[7-i] = data->replay_ctr[i];
19871 }
19872 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019873
19874 if (TRUE == pHddCtx->hdd_wlan_suspended)
19875 {
19876 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019877 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
19878 sizeof (tSirGtkOffloadParams));
19879 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019880 pAdapter->sessionId);
19881
19882 if (eHAL_STATUS_SUCCESS != status)
19883 {
19884 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19885 "%s: sme_SetGTKOffload failed, returned %d",
19886 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053019887
19888 /* Need to clear any trace of key value in the memory.
19889 * Thus zero out the memory even though it is local
19890 * variable.
19891 */
19892 vos_mem_zero(&hddGtkOffloadReqParams,
19893 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019894 return status;
19895 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019896 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19897 "%s: sme_SetGTKOffload successfull", __func__);
19898 }
19899 else
19900 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019901 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19902 "%s: wlan not suspended GTKOffload request is stored",
19903 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019904 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019905
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053019906 /* Need to clear any trace of key value in the memory.
19907 * Thus zero out the memory even though it is local
19908 * variable.
19909 */
19910 vos_mem_zero(&hddGtkOffloadReqParams,
19911 sizeof(hddGtkOffloadReqParams));
19912
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019913 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019914 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019915}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019916
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019917int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
19918 struct cfg80211_gtk_rekey_data *data)
19919{
19920 int ret;
19921
19922 vos_ssr_protect(__func__);
19923 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
19924 vos_ssr_unprotect(__func__);
19925
19926 return ret;
19927}
19928#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019929/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019930 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019931 * This function is used to set access control policy
19932 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019933static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
19934 struct net_device *dev,
19935 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019936{
19937 int i;
19938 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19939 hdd_hostapd_state_t *pHostapdState;
19940 tsap_Config_t *pConfig;
19941 v_CONTEXT_t pVosContext = NULL;
19942 hdd_context_t *pHddCtx;
19943 int status;
19944
19945 ENTER();
19946
19947 if (NULL == pAdapter)
19948 {
19949 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19950 "%s: HDD adapter is Null", __func__);
19951 return -ENODEV;
19952 }
19953
19954 if (NULL == params)
19955 {
19956 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19957 "%s: params is Null", __func__);
19958 return -EINVAL;
19959 }
19960
19961 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19962 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019963 if (0 != status)
19964 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019965 return status;
19966 }
19967
19968 pVosContext = pHddCtx->pvosContext;
19969 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
19970
19971 if (NULL == pHostapdState)
19972 {
19973 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19974 "%s: pHostapdState is Null", __func__);
19975 return -EINVAL;
19976 }
19977
19978 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
19979 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019980 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19981 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
19982 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019983
19984 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
19985 {
19986 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
19987
19988 /* default value */
19989 pConfig->num_accept_mac = 0;
19990 pConfig->num_deny_mac = 0;
19991
19992 /**
19993 * access control policy
19994 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
19995 * listed in hostapd.deny file.
19996 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
19997 * listed in hostapd.accept file.
19998 */
19999 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
20000 {
20001 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
20002 }
20003 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
20004 {
20005 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
20006 }
20007 else
20008 {
20009 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20010 "%s:Acl Policy : %d is not supported",
20011 __func__, params->acl_policy);
20012 return -ENOTSUPP;
20013 }
20014
20015 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
20016 {
20017 pConfig->num_accept_mac = params->n_acl_entries;
20018 for (i = 0; i < params->n_acl_entries; i++)
20019 {
20020 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20021 "** Add ACL MAC entry %i in WhiletList :"
20022 MAC_ADDRESS_STR, i,
20023 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
20024
20025 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
20026 sizeof(qcmacaddr));
20027 }
20028 }
20029 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
20030 {
20031 pConfig->num_deny_mac = params->n_acl_entries;
20032 for (i = 0; i < params->n_acl_entries; i++)
20033 {
20034 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20035 "** Add ACL MAC entry %i in BlackList :"
20036 MAC_ADDRESS_STR, i,
20037 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
20038
20039 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
20040 sizeof(qcmacaddr));
20041 }
20042 }
20043
20044 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
20045 {
20046 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20047 "%s: SAP Set Mac Acl fail", __func__);
20048 return -EINVAL;
20049 }
20050 }
20051 else
20052 {
20053 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053020054 "%s: Invalid device_mode = %s (%d)",
20055 __func__, hdd_device_modetoString(pAdapter->device_mode),
20056 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020057 return -EINVAL;
20058 }
20059
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020060 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020061 return 0;
20062}
20063
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020064static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
20065 struct net_device *dev,
20066 const struct cfg80211_acl_data *params)
20067{
20068 int ret;
20069 vos_ssr_protect(__func__);
20070 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
20071 vos_ssr_unprotect(__func__);
20072
20073 return ret;
20074}
20075
Leo Chang9056f462013-08-01 19:21:11 -070020076#ifdef WLAN_NL80211_TESTMODE
20077#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070020078void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070020079(
20080 void *pAdapter,
20081 void *indCont
20082)
20083{
Leo Changd9df8aa2013-09-26 13:32:26 -070020084 tSirLPHBInd *lphbInd;
20085 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053020086 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070020087
20088 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070020089 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070020090
c_hpothu73f35e62014-04-18 13:40:08 +053020091 if (pAdapter == NULL)
20092 {
20093 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20094 "%s: pAdapter is NULL\n",__func__);
20095 return;
20096 }
20097
Leo Chang9056f462013-08-01 19:21:11 -070020098 if (NULL == indCont)
20099 {
20100 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070020101 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070020102 return;
20103 }
20104
c_hpothu73f35e62014-04-18 13:40:08 +053020105 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070020106 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070020107 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053020108 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070020109 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070020110 GFP_ATOMIC);
20111 if (!skb)
20112 {
20113 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20114 "LPHB timeout, NL buffer alloc fail");
20115 return;
20116 }
20117
Leo Changac3ba772013-10-07 09:47:04 -070020118 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070020119 {
20120 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20121 "WLAN_HDD_TM_ATTR_CMD put fail");
20122 goto nla_put_failure;
20123 }
Leo Changac3ba772013-10-07 09:47:04 -070020124 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070020125 {
20126 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20127 "WLAN_HDD_TM_ATTR_TYPE put fail");
20128 goto nla_put_failure;
20129 }
Leo Changac3ba772013-10-07 09:47:04 -070020130 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070020131 sizeof(tSirLPHBInd), lphbInd))
20132 {
20133 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20134 "WLAN_HDD_TM_ATTR_DATA put fail");
20135 goto nla_put_failure;
20136 }
Leo Chang9056f462013-08-01 19:21:11 -070020137 cfg80211_testmode_event(skb, GFP_ATOMIC);
20138 return;
20139
20140nla_put_failure:
20141 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20142 "NLA Put fail");
20143 kfree_skb(skb);
20144
20145 return;
20146}
20147#endif /* FEATURE_WLAN_LPHB */
20148
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020149static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070020150{
20151 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
20152 int err = 0;
20153#ifdef FEATURE_WLAN_LPHB
20154 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070020155 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020156
20157 ENTER();
20158
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053020159 err = wlan_hdd_validate_context(pHddCtx);
20160 if (0 != err)
20161 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053020162 return err;
20163 }
Leo Chang9056f462013-08-01 19:21:11 -070020164#endif /* FEATURE_WLAN_LPHB */
20165
20166 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
20167 if (err)
20168 {
20169 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20170 "%s Testmode INV ATTR", __func__);
20171 return err;
20172 }
20173
20174 if (!tb[WLAN_HDD_TM_ATTR_CMD])
20175 {
20176 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20177 "%s Testmode INV CMD", __func__);
20178 return -EINVAL;
20179 }
20180
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053020181 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20182 TRACE_CODE_HDD_CFG80211_TESTMODE,
20183 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070020184 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
20185 {
20186#ifdef FEATURE_WLAN_LPHB
20187 /* Low Power Heartbeat configuration request */
20188 case WLAN_HDD_TM_CMD_WLAN_HB:
20189 {
20190 int buf_len;
20191 void *buf;
20192 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080020193 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070020194
20195 if (!tb[WLAN_HDD_TM_ATTR_DATA])
20196 {
20197 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20198 "%s Testmode INV DATA", __func__);
20199 return -EINVAL;
20200 }
20201
20202 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
20203 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080020204
Manjeet Singh3c577442017-02-10 19:03:38 +053020205 if (buf_len > sizeof(*hb_params)) {
20206 hddLog(LOGE, FL("buf_len=%d exceeded hb_params size limit"),
20207 buf_len);
20208 return -ERANGE;
20209 }
20210
Amar Singhal05852702014-02-04 14:40:00 -080020211 hb_params_temp =(tSirLPHBReq *)buf;
20212 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
20213 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
20214 return -EINVAL;
20215
Leo Chang9056f462013-08-01 19:21:11 -070020216 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
20217 if (NULL == hb_params)
20218 {
20219 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20220 "%s Request Buffer Alloc Fail", __func__);
20221 return -EINVAL;
20222 }
20223
20224 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070020225 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
20226 hb_params,
20227 wlan_hdd_cfg80211_lphb_ind_handler);
20228 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070020229 {
Leo Changd9df8aa2013-09-26 13:32:26 -070020230 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20231 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070020232 vos_mem_free(hb_params);
20233 }
Leo Chang9056f462013-08-01 19:21:11 -070020234 return 0;
20235 }
20236#endif /* FEATURE_WLAN_LPHB */
20237 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020238 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20239 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070020240 return -EOPNOTSUPP;
20241 }
20242
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020243 EXIT();
20244 return err;
Leo Chang9056f462013-08-01 19:21:11 -070020245}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020246
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053020247static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
20248#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
20249 struct wireless_dev *wdev,
20250#endif
20251 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020252{
20253 int ret;
20254
20255 vos_ssr_protect(__func__);
20256 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
20257 vos_ssr_unprotect(__func__);
20258
20259 return ret;
20260}
Leo Chang9056f462013-08-01 19:21:11 -070020261#endif /* CONFIG_NL80211_TESTMODE */
20262
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053020263extern void hdd_set_wlan_suspend_mode(bool suspend);
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020264static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020265 struct net_device *dev,
20266 int idx, struct survey_info *survey)
20267{
20268 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20269 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053020270 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020271 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053020272 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020273 v_S7_t snr,rssi;
20274 int status, i, j, filled = 0;
20275
20276 ENTER();
20277
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020278 if (NULL == pAdapter)
20279 {
20280 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20281 "%s: HDD adapter is Null", __func__);
20282 return -ENODEV;
20283 }
20284
20285 if (NULL == wiphy)
20286 {
20287 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20288 "%s: wiphy is Null", __func__);
20289 return -ENODEV;
20290 }
20291
20292 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
20293 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020294 if (0 != status)
20295 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020296 return status;
20297 }
20298
Mihir Sheted9072e02013-08-21 17:02:29 +053020299 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
20300
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020301 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053020302 0 != pAdapter->survey_idx ||
20303 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020304 {
20305 /* The survey dump ops when implemented completely is expected to
20306 * return a survey of all channels and the ops is called by the
20307 * kernel with incremental values of the argument 'idx' till it
20308 * returns -ENONET. But we can only support the survey for the
20309 * operating channel for now. survey_idx is used to track
20310 * that the ops is called only once and then return -ENONET for
20311 * the next iteration
20312 */
20313 pAdapter->survey_idx = 0;
20314 return -ENONET;
20315 }
20316
Mukul Sharma9d5233b2015-06-11 20:28:20 +053020317 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
20318 {
20319 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20320 "%s: Roaming in progress, hence return ", __func__);
20321 return -ENONET;
20322 }
20323
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020324 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
20325
20326 wlan_hdd_get_snr(pAdapter, &snr);
20327 wlan_hdd_get_rssi(pAdapter, &rssi);
20328
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053020329 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20330 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
20331 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020332 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
20333 hdd_wlan_get_freq(channel, &freq);
20334
20335
20336 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
20337 {
20338 if (NULL == wiphy->bands[i])
20339 {
20340 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
20341 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
20342 continue;
20343 }
20344
20345 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
20346 {
20347 struct ieee80211_supported_band *band = wiphy->bands[i];
20348
20349 if (band->channels[j].center_freq == (v_U16_t)freq)
20350 {
20351 survey->channel = &band->channels[j];
20352 /* The Rx BDs contain SNR values in dB for the received frames
20353 * while the supplicant expects noise. So we calculate and
20354 * return the value of noise (dBm)
20355 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
20356 */
20357 survey->noise = rssi - snr;
20358 survey->filled = SURVEY_INFO_NOISE_DBM;
20359 filled = 1;
20360 }
20361 }
20362 }
20363
20364 if (filled)
20365 pAdapter->survey_idx = 1;
20366 else
20367 {
20368 pAdapter->survey_idx = 0;
20369 return -ENONET;
20370 }
20371
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020372 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020373 return 0;
20374}
20375
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020376static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
20377 struct net_device *dev,
20378 int idx, struct survey_info *survey)
20379{
20380 int ret;
20381
20382 vos_ssr_protect(__func__);
20383 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
20384 vos_ssr_unprotect(__func__);
20385
20386 return ret;
20387}
20388
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020389/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053020390 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020391 * this is called when cfg80211 driver resume
20392 * driver updates latest sched_scan scan result(if any) to cfg80211 database
20393 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053020394int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020395{
20396 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
20397 hdd_adapter_t *pAdapter;
20398 hdd_adapter_list_node_t *pAdapterNode, *pNext;
20399 VOS_STATUS status = VOS_STATUS_SUCCESS;
20400
20401 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020402
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053020403 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020404 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020405 return 0;
20406 }
20407
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053020408 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
20409 NO_SESSION, pHddCtx->isWiphySuspended));
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053020410
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053020411 if (pHddCtx->is_ap_mode_wow_supported)
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053020412 {
20413 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20414 "%s: Resume SoftAP", __func__);
20415 hdd_set_wlan_suspend_mode(false);
20416 }
20417
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020418 spin_lock(&pHddCtx->schedScan_lock);
20419 pHddCtx->isWiphySuspended = FALSE;
20420 if (TRUE != pHddCtx->isSchedScanUpdatePending)
20421 {
20422 spin_unlock(&pHddCtx->schedScan_lock);
20423 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20424 "%s: Return resume is not due to PNO indication", __func__);
20425 return 0;
20426 }
20427 // Reset flag to avoid updatating cfg80211 data old results again
20428 pHddCtx->isSchedScanUpdatePending = FALSE;
20429 spin_unlock(&pHddCtx->schedScan_lock);
20430
20431 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
20432
20433 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
20434 {
20435 pAdapter = pAdapterNode->pAdapter;
20436 if ( (NULL != pAdapter) &&
20437 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
20438 {
20439 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053020440 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020441 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
20442 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053020443 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020444 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053020445 {
20446 /* Acquire wakelock to handle the case where APP's tries to
20447 * suspend immediately after updating the scan results. Whis
20448 * results in app's is in suspended state and not able to
20449 * process the connect request to AP
20450 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053020451 hdd_prevent_suspend_timeout(2000,
20452 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020453 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053020454 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020455
20456 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20457 "%s : cfg80211 scan result database updated", __func__);
20458
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020459 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020460 return 0;
20461
20462 }
20463 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
20464 pAdapterNode = pNext;
20465 }
20466
20467 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20468 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020469 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020470 return 0;
20471}
20472
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053020473int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
20474{
20475 int ret;
20476
20477 vos_ssr_protect(__func__);
20478 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
20479 vos_ssr_unprotect(__func__);
20480
20481 return ret;
20482}
20483
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020484/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053020485 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020486 * this is called when cfg80211 driver suspends
20487 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053020488int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020489 struct cfg80211_wowlan *wow)
20490{
20491 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053020492 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020493
20494 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020495
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053020496 ret = wlan_hdd_validate_context(pHddCtx);
20497 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020498 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053020499 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020500 }
20501
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053020502 if (pHddCtx->is_ap_mode_wow_supported) {
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053020503 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20504 "%s: Suspend SoftAP", __func__);
20505 hdd_set_wlan_suspend_mode(true);
20506 }
20507
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053020508
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053020509 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20510 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
20511 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020512 pHddCtx->isWiphySuspended = TRUE;
20513
20514 EXIT();
20515
20516 return 0;
20517}
20518
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053020519int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
20520 struct cfg80211_wowlan *wow)
20521{
20522 int ret;
20523
20524 vos_ssr_protect(__func__);
20525 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
20526 vos_ssr_unprotect(__func__);
20527
20528 return ret;
20529}
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053020530
20531#ifdef FEATURE_OEM_DATA_SUPPORT
20532static void wlan_hdd_cfg80211_oem_data_rsp_ind_new(void *ctx,
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 if (!pMsg)
20543 {
20544 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
20545 return;
20546 }
20547
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053020548 send_oem_data_rsp_msg(evLen, pMsg);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053020549
20550 EXIT();
20551 return;
20552
20553}
20554
20555void wlan_hdd_cfg80211_oemdata_callback(void *ctx, const tANI_U16 evType,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053020556 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053020557{
20558 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
20559
20560 ENTER();
20561
20562 if (wlan_hdd_validate_context(pHddCtx)) {
20563 return;
20564 }
20565
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053020566 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d) evLen %d"), evType, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053020567
20568 switch(evType) {
20569 case SIR_HAL_START_OEM_DATA_RSP_IND_NEW:
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053020570 wlan_hdd_cfg80211_oem_data_rsp_ind_new(ctx, pMsg, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053020571 break;
20572 default:
20573 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
20574 break;
20575 }
20576 EXIT();
20577}
20578#endif
20579
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053020580#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
20581 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053020582/**
20583 * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api
20584 * @wiphy: Pointer to wiphy
20585 * @wdev: Pointer to wireless device structure
20586 *
20587 * This function is used to abort an ongoing scan
20588 *
20589 * Return: None
20590 */
20591static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
20592 struct wireless_dev *wdev)
20593{
20594 struct net_device *dev = wdev->netdev;
20595 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
20596 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
20597 int ret;
20598
20599 ENTER();
20600
20601 if (NULL == adapter) {
20602 hddLog(VOS_TRACE_LEVEL_FATAL, FL("HDD adapter is NULL"));
20603 return;
20604 }
20605
20606 ret = wlan_hdd_validate_context(hdd_ctx);
20607 if (0 != ret)
20608 return;
20609
20610 wlan_hdd_scan_abort(adapter);
20611
20612 return;
20613}
20614
20615/**
20616 * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api
20617 * @wiphy: Pointer to wiphy
20618 * @wdev: Pointer to wireless device structure
20619 *
20620 * Return: None
20621 */
20622void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
20623 struct wireless_dev *wdev)
20624{
20625 vos_ssr_protect(__func__);
20626 __wlan_hdd_cfg80211_abort_scan(wiphy, wdev);
20627 vos_ssr_unprotect(__func__);
20628
20629 return;
20630}
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053020631#endif
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053020632
Jeff Johnson295189b2012-06-20 16:38:30 -070020633/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053020634static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070020635{
20636 .add_virtual_intf = wlan_hdd_add_virtual_intf,
20637 .del_virtual_intf = wlan_hdd_del_virtual_intf,
20638 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
20639 .change_station = wlan_hdd_change_station,
20640#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
20641 .add_beacon = wlan_hdd_cfg80211_add_beacon,
20642 .del_beacon = wlan_hdd_cfg80211_del_beacon,
20643 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070020644#else
20645 .start_ap = wlan_hdd_cfg80211_start_ap,
20646 .change_beacon = wlan_hdd_cfg80211_change_beacon,
20647 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070020648#endif
20649 .change_bss = wlan_hdd_cfg80211_change_bss,
20650 .add_key = wlan_hdd_cfg80211_add_key,
20651 .get_key = wlan_hdd_cfg80211_get_key,
20652 .del_key = wlan_hdd_cfg80211_del_key,
20653 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080020654#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070020655 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080020656#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070020657 .scan = wlan_hdd_cfg80211_scan,
20658 .connect = wlan_hdd_cfg80211_connect,
20659 .disconnect = wlan_hdd_cfg80211_disconnect,
20660 .join_ibss = wlan_hdd_cfg80211_join_ibss,
20661 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
20662 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
20663 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
20664 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070020665 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
20666 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053020667 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070020668#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
20669 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
20670 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
20671 .set_txq_params = wlan_hdd_set_txq_params,
20672#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070020673 .get_station = wlan_hdd_cfg80211_get_station,
20674 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
20675 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070020676 .add_station = wlan_hdd_cfg80211_add_station,
20677#ifdef FEATURE_WLAN_LFR
20678 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
20679 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
20680 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
20681#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070020682#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
20683 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
20684#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020685#ifdef FEATURE_WLAN_TDLS
20686 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
20687 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
20688#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020689#ifdef WLAN_FEATURE_GTK_OFFLOAD
20690 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
20691#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020692#ifdef FEATURE_WLAN_SCAN_PNO
20693 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
20694 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
20695#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020696 .resume = wlan_hdd_cfg80211_resume_wlan,
20697 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020698 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070020699#ifdef WLAN_NL80211_TESTMODE
20700 .testmode_cmd = wlan_hdd_cfg80211_testmode,
20701#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020702 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053020703#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
20704 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053020705 .abort_scan = wlan_hdd_cfg80211_abort_scan,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053020706#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070020707};
20708