blob: 97f65699c6c2d0f428b0b513973d2be5348f34fc [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
5768
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305769static int
5770__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305771 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305772 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305773{
5774 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
5775 uint8_t i, feature_sets, max_feature_sets;
5776 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX + 1];
5777 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305778 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5779 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305780
5781 ENTER();
5782
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305783 ret = wlan_hdd_validate_context(pHddCtx);
5784 if (0 != ret)
5785 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305786 return ret;
5787 }
5788
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305789 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX,
5790 data, data_len, NULL)) {
5791 hddLog(LOGE, FL("Invalid ATTR"));
5792 return -EINVAL;
5793 }
5794
5795 /* Parse and fetch max feature set */
5796 if (!tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
5797 hddLog(LOGE, FL("Attr max feature set size failed"));
5798 return -EINVAL;
5799 }
5800 max_feature_sets = nla_get_u32(
5801 tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
5802 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
5803
5804 /* Fill feature combination matrix */
5805 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305806 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5807 WIFI_FEATURE_P2P;
5808
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305809 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5810 WIFI_FEATURE_SOFT_AP;
5811
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305812 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
5813 WIFI_FEATURE_SOFT_AP;
5814
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305815 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5816 WIFI_FEATURE_SOFT_AP |
5817 WIFI_FEATURE_P2P;
5818
5819 /* Add more feature combinations here */
5820
5821 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
5822 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
5823 hddLog(LOG1, "Feature set matrix");
5824 for (i = 0; i < feature_sets; i++)
5825 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
5826
5827 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
5828 sizeof(u32) * feature_sets +
5829 NLMSG_HDRLEN);
5830
5831 if (reply_skb) {
5832 if (nla_put_u32(reply_skb,
5833 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
5834 feature_sets) ||
5835 nla_put(reply_skb,
5836 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
5837 sizeof(u32) * feature_sets, feature_set_matrix)) {
5838 hddLog(LOGE, FL("nla put fail"));
5839 kfree_skb(reply_skb);
5840 return -EINVAL;
5841 }
5842
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305843 ret = cfg80211_vendor_cmd_reply(reply_skb);
5844 EXIT();
5845 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305846 }
5847 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
5848 return -ENOMEM;
5849
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305850}
5851
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305852static int
5853wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
5854 struct wireless_dev *wdev,
5855 const void *data, int data_len)
5856{
5857 int ret = 0;
5858
5859 vos_ssr_protect(__func__);
5860 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
5861 data_len);
5862 vos_ssr_unprotect(__func__);
5863
5864 return ret;
5865}
5866
c_manjeecfd1efb2015-09-25 19:32:34 +05305867
5868static int
5869__wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5870 struct wireless_dev *wdev,
5871 const void *data, int data_len)
5872{
5873 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5874 int ret;
5875 ENTER();
5876
5877 ret = wlan_hdd_validate_context(pHddCtx);
5878 if (0 != ret)
5879 {
5880 return ret;
5881 }
5882
5883 if( !pHddCtx->cfg_ini->enableFwrMemDump ||
5884 (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
5885 {
5886 hddLog(VOS_TRACE_LEVEL_INFO, FL("FW dump Logging not supported"));
5887 return -EINVAL;
5888 }
5889 /*call common API for FW mem dump req*/
5890 ret = wlan_hdd_fw_mem_dump_req(pHddCtx);
5891
Abhishek Singhc783fa72015-12-09 18:07:34 +05305892 if (!ret)
c_manjee04b4c5c2015-10-13 18:35:01 +05305893 {
5894 /*indicate to userspace the status of fw mem dump */
5895 wlan_indicate_mem_dump_complete(true);
5896 }
5897 else
5898 {
5899 /*else send failure to userspace */
5900 wlan_indicate_mem_dump_complete(false);
5901 }
c_manjeecfd1efb2015-09-25 19:32:34 +05305902 EXIT();
5903 return ret;
5904}
5905
5906/**
5907 * wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump
5908 * @wiphy: pointer to wireless wiphy structure.
5909 * @wdev: pointer to wireless_dev structure.
5910 * @data: Pointer to the NL data.
5911 * @data_len:Length of @data
5912 *
5913 * This is called when wlan driver needs to get the firmware memory dump
5914 * via vendor specific command.
5915 *
5916 * Return: 0 on success, error number otherwise.
5917 */
5918
5919static int
5920wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5921 struct wireless_dev *wdev,
5922 const void *data, int data_len)
Sushant Kaushik8e644982015-09-23 12:18:54 +05305923{
5924 int ret = 0;
5925 vos_ssr_protect(__func__);
5926 ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data,
5927 data_len);
5928 vos_ssr_unprotect(__func__);
5929 return ret;
5930}
c_manjeecfd1efb2015-09-25 19:32:34 +05305931
Sushant Kaushik8e644982015-09-23 12:18:54 +05305932static const struct
5933nla_policy
5934qca_wlan_vendor_wifi_logger_start_policy
5935[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
5936 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
5937 = {.type = NLA_U32 },
5938 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
5939 = {.type = NLA_U32 },
5940 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
5941 = {.type = NLA_U32 },
5942};
5943
5944/**
5945 * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
5946 * or disable the collection of packet statistics from the firmware
5947 * @wiphy: WIPHY structure pointer
5948 * @wdev: Wireless device structure pointer
5949 * @data: Pointer to the data received
5950 * @data_len: Length of the data received
5951 *
5952 * This function is used to enable or disable the collection of packet
5953 * statistics from the firmware
5954 *
5955 * Return: 0 on success and errno on failure
5956 */
5957static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
5958 struct wireless_dev *wdev,
5959 const void *data,
5960 int data_len)
5961{
5962 eHalStatus status;
5963 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5964 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
5965 tAniWifiStartLog start_log;
5966
5967 status = wlan_hdd_validate_context(hdd_ctx);
5968 if (0 != status) {
5969 return -EINVAL;
5970 }
5971
5972 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
5973 data, data_len,
5974 qca_wlan_vendor_wifi_logger_start_policy)) {
5975 hddLog(LOGE, FL("Invalid attribute"));
5976 return -EINVAL;
5977 }
5978
5979 /* Parse and fetch ring id */
5980 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
5981 hddLog(LOGE, FL("attr ATTR failed"));
5982 return -EINVAL;
5983 }
5984 start_log.ringId = nla_get_u32(
5985 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
5986 hddLog(LOG1, FL("Ring ID=%d"), start_log.ringId);
5987
5988 /* Parse and fetch verbose level */
5989 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
5990 hddLog(LOGE, FL("attr verbose_level failed"));
5991 return -EINVAL;
5992 }
5993 start_log.verboseLevel = nla_get_u32(
5994 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
5995 hddLog(LOG1, FL("verbose_level=%d"), start_log.verboseLevel);
5996
5997 /* Parse and fetch flag */
5998 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
5999 hddLog(LOGE, FL("attr flag failed"));
6000 return -EINVAL;
6001 }
6002 start_log.flag = nla_get_u32(
6003 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
6004 hddLog(LOG1, FL("flag=%d"), start_log.flag);
6005
6006 if ((RING_ID_PER_PACKET_STATS == start_log.ringId) &&
Sushant Kaushik33200572015-08-05 16:46:20 +05306007 (!hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable ||
6008 !vos_isPktStatsEnabled()))
6009
Sushant Kaushik8e644982015-09-23 12:18:54 +05306010 {
6011 hddLog(LOGE, FL("per pkt stats not enabled"));
6012 return -EINVAL;
6013 }
Sushant Kaushik8e644982015-09-23 12:18:54 +05306014
Sushant Kaushik33200572015-08-05 16:46:20 +05306015 vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306016 return 0;
6017}
6018
6019/**
6020 * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
6021 * or disable the collection of packet statistics from the firmware
6022 * @wiphy: WIPHY structure pointer
6023 * @wdev: Wireless device structure pointer
6024 * @data: Pointer to the data received
6025 * @data_len: Length of the data received
6026 *
6027 * This function is used to enable or disable the collection of packet
6028 * statistics from the firmware
6029 *
6030 * Return: 0 on success and errno on failure
6031 */
6032static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6033 struct wireless_dev *wdev,
6034 const void *data,
6035 int data_len)
c_manjeecfd1efb2015-09-25 19:32:34 +05306036{
6037 int ret = 0;
6038
6039 vos_ssr_protect(__func__);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306040
6041 ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
6042 wdev, data, data_len);
c_manjeecfd1efb2015-09-25 19:32:34 +05306043 vos_ssr_unprotect(__func__);
6044
6045 return ret;
c_manjeecfd1efb2015-09-25 19:32:34 +05306046}
6047
6048
Agarwal Ashish738843c2014-09-25 12:27:56 +05306049static const struct nla_policy
6050wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
6051 +1] =
6052{
6053 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
6054};
6055
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306056static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306057 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306058 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306059 int data_len)
6060{
6061 struct net_device *dev = wdev->netdev;
6062 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6063 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6064 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6065 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
6066 eHalStatus status;
6067 u32 dfsFlag = 0;
6068
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306069 ENTER();
6070
Agarwal Ashish738843c2014-09-25 12:27:56 +05306071 status = wlan_hdd_validate_context(pHddCtx);
6072 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05306073 return -EINVAL;
6074 }
6075 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
6076 data, data_len,
6077 wlan_hdd_set_no_dfs_flag_config_policy)) {
6078 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6079 return -EINVAL;
6080 }
6081
6082 /* Parse and fetch required bandwidth kbps */
6083 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
6084 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
6085 return -EINVAL;
6086 }
6087
6088 dfsFlag = nla_get_u32(
6089 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
6090 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
6091 dfsFlag);
6092
6093 pHddCtx->disable_dfs_flag = dfsFlag;
6094
6095 sme_disable_dfs_channel(hHal, dfsFlag);
6096 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306097
6098 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05306099 return 0;
6100}
Atul Mittal115287b2014-07-08 13:26:33 +05306101
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306102static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
6103 struct wireless_dev *wdev,
6104 const void *data,
6105 int data_len)
6106{
6107 int ret = 0;
6108
6109 vos_ssr_protect(__func__);
6110 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
6111 vos_ssr_unprotect(__func__);
6112
6113 return ret;
6114
6115}
6116
Mukul Sharma2a271632014-10-13 14:59:01 +05306117const struct
6118nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
6119{
6120 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
6121 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
6122};
6123
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306124static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05306125 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05306126{
6127
6128 u8 bssid[6] = {0};
6129 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6130 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6131 eHalStatus status = eHAL_STATUS_SUCCESS;
6132 v_U32_t isFwrRoamEnabled = FALSE;
6133 int ret;
6134
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306135 ENTER();
6136
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306137 ret = wlan_hdd_validate_context(pHddCtx);
6138 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306139 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05306140 }
6141
6142 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
6143 data, data_len,
6144 qca_wlan_vendor_attr);
6145 if (ret){
6146 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6147 return -EINVAL;
6148 }
6149
6150 /* Parse and fetch Enable flag */
6151 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
6152 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
6153 return -EINVAL;
6154 }
6155
6156 isFwrRoamEnabled = nla_get_u32(
6157 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
6158
6159 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
6160
6161 /* Parse and fetch bssid */
6162 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
6163 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
6164 return -EINVAL;
6165 }
6166
6167 memcpy(bssid, nla_data(
6168 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
6169 sizeof(bssid));
6170 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
6171
6172 //Update roaming
6173 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306174 if (!HAL_STATUS_SUCCESS(status)) {
6175 hddLog(LOGE,
6176 FL("sme_ConfigFwrRoaming failed (err=%d)"), status);
6177 return -EINVAL;
6178 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306179 EXIT();
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306180 return 0;
Mukul Sharma2a271632014-10-13 14:59:01 +05306181}
6182
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306183static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
6184 struct wireless_dev *wdev, const void *data, int data_len)
6185{
6186 int ret = 0;
6187
6188 vos_ssr_protect(__func__);
6189 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
6190 vos_ssr_unprotect(__func__);
6191
6192 return ret;
6193}
6194
Sushant Kaushik847890c2015-09-28 16:05:17 +05306195static const struct
6196nla_policy
6197qca_wlan_vendor_get_wifi_info_policy[
6198 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
6199 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
6200 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
6201};
6202
6203
6204/**
6205 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6206 * @wiphy: pointer to wireless wiphy structure.
6207 * @wdev: pointer to wireless_dev structure.
6208 * @data: Pointer to the data to be passed via vendor interface
6209 * @data_len:Length of the data to be passed
6210 *
6211 * This is called when wlan driver needs to send wifi driver related info
6212 * (driver/fw version) to the user space application upon request.
6213 *
6214 * Return: Return the Success or Failure code.
6215 */
6216static int __wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6217 struct wireless_dev *wdev,
6218 const void *data, int data_len)
6219{
6220 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6221 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
6222 tSirVersionString version;
6223 uint32 version_len;
6224 uint8 attr;
6225 int status;
6226 struct sk_buff *reply_skb = NULL;
6227
6228 if (VOS_FTM_MODE == hdd_get_conparam()) {
6229 hddLog(LOGE, FL("Command not allowed in FTM mode"));
6230 return -EINVAL;
6231 }
6232
6233 status = wlan_hdd_validate_context(hdd_ctx);
6234 if (0 != status) {
6235 hddLog(LOGE, FL("HDD context is not valid"));
6236 return -EINVAL;
6237 }
6238
6239 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
6240 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
6241 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
6242 return -EINVAL;
6243 }
6244
6245 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
6246 hddLog(LOG1, FL("Rcvd req for Driver version Driver version is %s"),
6247 QWLAN_VERSIONSTR);
6248 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
6249 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
6250 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
6251 hddLog(LOG1, FL("Rcvd req for FW version FW version is %s"),
6252 hdd_ctx->fw_Version);
6253 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
6254 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
6255 } else {
6256 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
6257 return -EINVAL;
6258 }
6259
6260 version_len = strlen(version);
6261 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
6262 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
6263 if (!reply_skb) {
6264 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6265 return -ENOMEM;
6266 }
6267
6268 if (nla_put(reply_skb, attr, version_len, version)) {
6269 hddLog(LOGE, FL("nla put fail"));
6270 kfree_skb(reply_skb);
6271 return -EINVAL;
6272 }
6273
6274 return cfg80211_vendor_cmd_reply(reply_skb);
6275}
6276
6277/**
6278 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6279 * @wiphy: pointer to wireless wiphy structure.
6280 * @wdev: pointer to wireless_dev structure.
6281 * @data: Pointer to the data to be passed via vendor interface
6282 * @data_len:Length of the data to be passed
6283 * @data_len: Length of the data received
6284 *
6285 * This function is used to enable or disable the collection of packet
6286 * statistics from the firmware
6287 *
6288 * Return: 0 on success and errno on failure
6289 */
6290
6291static int
6292wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6293 struct wireless_dev *wdev,
6294 const void *data, int data_len)
6295
6296
6297{
6298 int ret = 0;
6299
6300 vos_ssr_protect(__func__);
6301 ret = __wlan_hdd_cfg80211_get_wifi_info(wiphy,
6302 wdev, data, data_len);
6303 vos_ssr_unprotect(__func__);
6304
6305 return ret;
6306}
6307
6308
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306309/*
6310 * define short names for the global vendor params
6311 * used by __wlan_hdd_cfg80211_monitor_rssi()
6312 */
6313#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX
6314#define PARAM_REQUEST_ID QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID
6315#define PARAM_CONTROL QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL
6316#define PARAM_MIN_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI
6317#define PARAM_MAX_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI
6318
6319/**---------------------------------------------------------------------------
6320
6321 \brief hdd_rssi_monitor_start_done - callback to be executed when rssi
6322 monitor start is completed successfully.
6323
6324 \return - None
6325
6326 --------------------------------------------------------------------------*/
6327void hdd_rssi_monitor_start_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6328{
6329 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6330
6331 if (NULL == pHddCtx)
6332 {
6333 hddLog(VOS_TRACE_LEVEL_ERROR,
6334 "%s: HDD context is NULL",__func__);
6335 return;
6336 }
6337
6338 if (VOS_STATUS_SUCCESS == status)
6339 {
6340 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor start successful"));
6341 }
6342 else
6343 {
6344 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor start not successful"));
6345 }
6346
6347 return;
6348}
6349
6350/**---------------------------------------------------------------------------
6351
6352 \brief hdd_rssi_monitor_stop_done - callback to be executed when rssi monitor
6353 stop is completed successfully.
6354
6355 \return - None
6356
6357 --------------------------------------------------------------------------*/
6358void hdd_rssi_monitor_stop_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6359{
6360 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6361
6362 if (NULL == pHddCtx)
6363 {
6364 hddLog(VOS_TRACE_LEVEL_ERROR,
6365 "%s: HDD context is NULL",__func__);
6366 return;
6367 }
6368
6369 if (VOS_STATUS_SUCCESS == status)
6370 {
6371 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor stop successful"));
6372 }
6373 else
6374 {
6375 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor stop not successful"));
6376 }
6377
6378 return;
6379}
6380
6381/**
6382 * __wlan_hdd_cfg80211_monitor_rssi() - monitor rssi
6383 * @wiphy: Pointer to wireless phy
6384 * @wdev: Pointer to wireless device
6385 * @data: Pointer to data
6386 * @data_len: Data length
6387 *
6388 * Return: 0 on success, negative errno on failure
6389 */
6390
6391static int
6392__wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy,
6393 struct wireless_dev *wdev,
6394 const void *data,
6395 int data_len)
6396{
6397 struct net_device *dev = wdev->netdev;
6398 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6399 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6400 hdd_station_ctx_t *pHddStaCtx;
6401 struct nlattr *tb[PARAM_MAX + 1];
6402 tpSirRssiMonitorReq pReq;
6403 eHalStatus status;
6404 int ret;
6405 uint32_t control;
6406 static const struct nla_policy policy[PARAM_MAX + 1] = {
6407 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6408 [PARAM_CONTROL] = { .type = NLA_U32 },
6409 [PARAM_MIN_RSSI] = { .type = NLA_S8 },
6410 [PARAM_MAX_RSSI] = { .type = NLA_S8 },
6411 };
6412
6413 ENTER();
6414
6415 ret = wlan_hdd_validate_context(hdd_ctx);
6416 if (0 != ret) {
6417 return -EINVAL;
6418 }
6419
6420 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6421 hddLog(LOGE, FL("Not in Connected state!"));
6422 return -ENOTSUPP;
6423 }
6424
6425 if (nla_parse(tb, PARAM_MAX, data, data_len, policy)) {
6426 hddLog(LOGE, FL("Invalid ATTR"));
6427 return -EINVAL;
6428 }
6429
6430 if (!tb[PARAM_REQUEST_ID]) {
6431 hddLog(LOGE, FL("attr request id failed"));
6432 return -EINVAL;
6433 }
6434
6435 if (!tb[PARAM_CONTROL]) {
6436 hddLog(LOGE, FL("attr control failed"));
6437 return -EINVAL;
6438 }
6439
6440 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6441
6442 pReq = vos_mem_malloc(sizeof(tSirRssiMonitorReq));
6443 if(NULL == pReq)
6444 {
6445 hddLog(LOGE,
6446 FL("vos_mem_alloc failed "));
6447 return eHAL_STATUS_FAILED_ALLOC;
6448 }
6449 vos_mem_set(pReq, sizeof(tSirRssiMonitorReq), 0);
6450
6451 pReq->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]);
6452 pReq->sessionId = pAdapter->sessionId;
6453 pReq->rssiMonitorCbContext = hdd_ctx;
6454 control = nla_get_u32(tb[PARAM_CONTROL]);
6455 vos_mem_copy( &pReq->currentBssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
6456
6457 hddLog(LOG1, FL("Request Id: %u Session_id: %d Control: %d"),
6458 pReq->requestId, pReq->sessionId, control);
6459
6460 if (control == QCA_WLAN_RSSI_MONITORING_START) {
6461 if (!tb[PARAM_MIN_RSSI]) {
6462 hddLog(LOGE, FL("attr min rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306463 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306464 }
6465
6466 if (!tb[PARAM_MAX_RSSI]) {
6467 hddLog(LOGE, FL("attr max rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306468 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306469 }
6470
6471 pReq->minRssi = nla_get_s8(tb[PARAM_MIN_RSSI]);
6472 pReq->maxRssi = nla_get_s8(tb[PARAM_MAX_RSSI]);
6473 pReq->rssiMonitorCallback = hdd_rssi_monitor_start_done;
6474
6475 if (!(pReq->minRssi < pReq->maxRssi)) {
6476 hddLog(LOGW, FL("min_rssi: %d must be less than max_rssi: %d"),
6477 pReq->minRssi, pReq->maxRssi);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306478 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306479 }
6480 hddLog(LOG1, FL("Min_rssi: %d Max_rssi: %d"),
6481 pReq->minRssi, pReq->maxRssi);
6482 status = sme_StartRssiMonitoring(hdd_ctx->hHal, pReq);
6483
6484 }
6485 else if (control == QCA_WLAN_RSSI_MONITORING_STOP) {
6486 pReq->rssiMonitorCallback = hdd_rssi_monitor_stop_done;
6487 status = sme_StopRssiMonitoring(hdd_ctx->hHal, pReq);
6488 }
6489 else {
6490 hddLog(LOGE, FL("Invalid control cmd: %d"), control);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306491 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306492 }
6493
6494 if (!HAL_STATUS_SUCCESS(status)) {
6495 hddLog(LOGE,
6496 FL("sme_set_rssi_monitoring failed(err=%d)"), status);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306497 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306498 }
6499
6500 return 0;
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306501fail:
6502 vos_mem_free(pReq);
6503 return -EINVAL;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306504}
6505
6506/*
6507 * done with short names for the global vendor params
6508 * used by __wlan_hdd_cfg80211_monitor_rssi()
6509 */
6510#undef PARAM_MAX
6511#undef PARAM_CONTROL
6512#undef PARAM_REQUEST_ID
6513#undef PARAM_MAX_RSSI
6514#undef PARAM_MIN_RSSI
6515
6516/**
6517 * wlan_hdd_cfg80211_monitor_rssi() - SSR wrapper to rssi monitoring
6518 * @wiphy: wiphy structure pointer
6519 * @wdev: Wireless device structure pointer
6520 * @data: Pointer to the data received
6521 * @data_len: Length of @data
6522 *
6523 * Return: 0 on success; errno on failure
6524 */
6525static int
6526wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, struct wireless_dev *wdev,
6527 const void *data, int data_len)
6528{
6529 int ret;
6530
6531 vos_ssr_protect(__func__);
6532 ret = __wlan_hdd_cfg80211_monitor_rssi(wiphy, wdev, data, data_len);
6533 vos_ssr_unprotect(__func__);
6534
6535 return ret;
6536}
6537
6538/**
6539 * hdd_rssi_threshold_breached_cb() - rssi breached NL event
6540 * @hddctx: HDD context
6541 * @data: rssi breached event data
6542 *
6543 * This function reads the rssi breached event %data and fill in the skb with
6544 * NL attributes and send up the NL event.
6545 * This callback execute in atomic context and must not invoke any
6546 * blocking calls.
6547 *
6548 * Return: none
6549 */
6550void hdd_rssi_threshold_breached_cb(void *hddctx,
6551 struct rssi_breach_event *data)
6552{
6553 hdd_context_t *pHddCtx = (hdd_context_t *)hddctx;
6554 int status;
6555 struct sk_buff *skb;
6556
6557 ENTER();
6558 status = wlan_hdd_validate_context(pHddCtx);
6559
6560 if (0 != status) {
6561 return;
6562 }
6563
6564 if (!data) {
6565 hddLog(LOGE, FL("data is null"));
6566 return;
6567 }
6568
6569 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
6570#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
6571 NULL,
6572#endif
6573 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
6574 QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX,
6575 GFP_KERNEL);
6576
6577 if (!skb) {
6578 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
6579 return;
6580 }
6581
6582 hddLog(LOG1, "Req Id: %u Current rssi: %d",
6583 data->request_id, data->curr_rssi);
6584 hddLog(LOG1, "Current BSSID: "MAC_ADDRESS_STR,
6585 MAC_ADDR_ARRAY(data->curr_bssid.bytes));
6586
6587 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
6588 data->request_id) ||
6589 nla_put(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID,
6590 sizeof(data->curr_bssid), data->curr_bssid.bytes) ||
6591 nla_put_s8(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI,
6592 data->curr_rssi)) {
6593 hddLog(LOGE, FL("nla put fail"));
6594 goto fail;
6595 }
6596
6597 cfg80211_vendor_event(skb, GFP_KERNEL);
6598 return;
6599
6600fail:
6601 kfree_skb(skb);
6602 return;
6603}
6604
6605
6606
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306607/**
6608 * __wlan_hdd_cfg80211_setband() - set band
6609 * @wiphy: Pointer to wireless phy
6610 * @wdev: Pointer to wireless device
6611 * @data: Pointer to data
6612 * @data_len: Data length
6613 *
6614 * Return: 0 on success, negative errno on failure
6615 */
6616static int
6617__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6618 struct wireless_dev *wdev,
6619 const void *data,
6620 int data_len)
6621{
6622 struct net_device *dev = wdev->netdev;
6623 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6624 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6625 int ret;
6626 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
6627 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
6628
6629 ENTER();
6630
6631 ret = wlan_hdd_validate_context(hdd_ctx);
6632 if (0 != ret) {
6633 hddLog(LOGE, FL("HDD context is not valid"));
6634 return ret;
6635 }
6636
6637 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
6638 policy)) {
6639 hddLog(LOGE, FL("Invalid ATTR"));
6640 return -EINVAL;
6641 }
6642
6643 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
6644 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
6645 return -EINVAL;
6646 }
6647
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306648 hdd_ctx->isSetBandByNL = TRUE;
6649 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306650 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306651 hdd_ctx->isSetBandByNL = FALSE;
6652
6653 EXIT();
6654 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306655}
6656
6657/**
6658 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
6659 * @wiphy: wiphy structure pointer
6660 * @wdev: Wireless device structure pointer
6661 * @data: Pointer to the data received
6662 * @data_len: Length of @data
6663 *
6664 * Return: 0 on success; errno on failure
6665 */
6666static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6667 struct wireless_dev *wdev,
6668 const void *data,
6669 int data_len)
6670{
6671 int ret = 0;
6672
6673 vos_ssr_protect(__func__);
6674 ret = __wlan_hdd_cfg80211_setband(wiphy,
6675 wdev, data, data_len);
6676 vos_ssr_unprotect(__func__);
6677
6678 return ret;
6679}
6680
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05306681#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
6682/**
6683 * hdd_map_req_id_to_pattern_id() - map request id to pattern id
6684 * @hdd_ctx: HDD context
6685 * @request_id: [input] request id
6686 * @pattern_id: [output] pattern id
6687 *
6688 * This function loops through request id to pattern id array
6689 * if the slot is available, store the request id and return pattern id
6690 * if entry exists, return the pattern id
6691 *
6692 * Return: 0 on success and errno on failure
6693 */
6694static int hdd_map_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
6695 uint32_t request_id,
6696 uint8_t *pattern_id)
6697{
6698 uint32_t i;
6699
6700 mutex_lock(&hdd_ctx->op_ctx.op_lock);
6701 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
6702 {
6703 if (hdd_ctx->op_ctx.op_table[i].request_id == 0)
6704 {
6705 hdd_ctx->op_ctx.op_table[i].request_id = request_id;
6706 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6707 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6708 return 0;
6709 } else if (hdd_ctx->op_ctx.op_table[i].request_id ==
6710 request_id) {
6711 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6712 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6713 return 0;
6714 }
6715 }
6716 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6717 return -EINVAL;
6718}
6719
6720/**
6721 * hdd_unmap_req_id_to_pattern_id() - unmap request id to pattern id
6722 * @hdd_ctx: HDD context
6723 * @request_id: [input] request id
6724 * @pattern_id: [output] pattern id
6725 *
6726 * This function loops through request id to pattern id array
6727 * reset request id to 0 (slot available again) and
6728 * return pattern id
6729 *
6730 * Return: 0 on success and errno on failure
6731 */
6732static int hdd_unmap_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
6733 uint32_t request_id,
6734 uint8_t *pattern_id)
6735{
6736 uint32_t i;
6737
6738 mutex_lock(&hdd_ctx->op_ctx.op_lock);
6739 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
6740 {
6741 if (hdd_ctx->op_ctx.op_table[i].request_id == request_id)
6742 {
6743 hdd_ctx->op_ctx.op_table[i].request_id = 0;
6744 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6745 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6746 return 0;
6747 }
6748 }
6749 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6750 return -EINVAL;
6751}
6752
6753
6754/*
6755 * define short names for the global vendor params
6756 * used by __wlan_hdd_cfg80211_offloaded_packets()
6757 */
6758#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX
6759#define PARAM_REQUEST_ID \
6760 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID
6761#define PARAM_CONTROL \
6762 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL
6763#define PARAM_IP_PACKET \
6764 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA
6765#define PARAM_SRC_MAC_ADDR \
6766 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR
6767#define PARAM_DST_MAC_ADDR \
6768 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR
6769#define PARAM_PERIOD QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD
6770
6771/**
6772 * wlan_hdd_add_tx_ptrn() - add tx pattern
6773 * @adapter: adapter pointer
6774 * @hdd_ctx: hdd context
6775 * @tb: nl attributes
6776 *
6777 * This function reads the NL attributes and forms a AddTxPtrn message
6778 * posts it to SME.
6779 *
6780 */
6781static int
6782wlan_hdd_add_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
6783 struct nlattr **tb)
6784{
6785 struct sSirAddPeriodicTxPtrn *add_req;
6786 eHalStatus status;
6787 uint32_t request_id, ret, len;
6788 uint8_t pattern_id = 0;
6789 v_MACADDR_t dst_addr;
6790 uint16_t eth_type = htons(ETH_P_IP);
6791
6792 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(adapter)))
6793 {
6794 hddLog(LOGE, FL("Not in Connected state!"));
6795 return -ENOTSUPP;
6796 }
6797
6798 add_req = vos_mem_malloc(sizeof(*add_req));
6799 if (!add_req)
6800 {
6801 hddLog(LOGE, FL("memory allocation failed"));
6802 return -ENOMEM;
6803 }
6804
6805 /* Parse and fetch request Id */
6806 if (!tb[PARAM_REQUEST_ID])
6807 {
6808 hddLog(LOGE, FL("attr request id failed"));
6809 goto fail;
6810 }
6811
6812 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
6813 hddLog(LOG1, FL("Request Id: %u"), request_id);
6814 if (request_id == 0)
6815 {
6816 hddLog(LOGE, FL("request_id cannot be zero"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306817 goto fail;
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05306818 }
6819
6820 if (!tb[PARAM_PERIOD])
6821 {
6822 hddLog(LOGE, FL("attr period failed"));
6823 goto fail;
6824 }
6825 add_req->usPtrnIntervalMs = nla_get_u32(tb[PARAM_PERIOD]);
6826 hddLog(LOG1, FL("Period: %u ms"), add_req->usPtrnIntervalMs);
6827 if (add_req->usPtrnIntervalMs == 0)
6828 {
6829 hddLog(LOGE, FL("Invalid interval zero, return failure"));
6830 goto fail;
6831 }
6832
6833 if (!tb[PARAM_SRC_MAC_ADDR])
6834 {
6835 hddLog(LOGE, FL("attr source mac address failed"));
6836 goto fail;
6837 }
6838 nla_memcpy(add_req->macAddress, tb[PARAM_SRC_MAC_ADDR],
6839 VOS_MAC_ADDR_SIZE);
6840 hddLog(LOG1, "input src mac address: "MAC_ADDRESS_STR,
6841 MAC_ADDR_ARRAY(add_req->macAddress));
6842
6843 if (memcmp(add_req->macAddress, adapter->macAddressCurrent.bytes,
6844 VOS_MAC_ADDR_SIZE))
6845 {
6846 hddLog(LOGE,
6847 FL("input src mac address and connected ap bssid are different"));
6848 goto fail;
6849 }
6850
6851 if (!tb[PARAM_DST_MAC_ADDR])
6852 {
6853 hddLog(LOGE, FL("attr dst mac address failed"));
6854 goto fail;
6855 }
6856 nla_memcpy(dst_addr.bytes, tb[PARAM_DST_MAC_ADDR], VOS_MAC_ADDR_SIZE);
6857 hddLog(LOG1, "input dst mac address: "MAC_ADDRESS_STR,
6858 MAC_ADDR_ARRAY(dst_addr.bytes));
6859
6860 if (!tb[PARAM_IP_PACKET])
6861 {
6862 hddLog(LOGE, FL("attr ip packet failed"));
6863 goto fail;
6864 }
6865 add_req->ucPtrnSize = nla_len(tb[PARAM_IP_PACKET]);
6866 hddLog(LOG1, FL("IP packet len: %u"), add_req->ucPtrnSize);
6867
6868 if (add_req->ucPtrnSize < 0 ||
6869 add_req->ucPtrnSize > (PERIODIC_TX_PTRN_MAX_SIZE -
6870 HDD_ETH_HEADER_LEN))
6871 {
6872 hddLog(LOGE, FL("Invalid IP packet len: %d"),
6873 add_req->ucPtrnSize);
6874 goto fail;
6875 }
6876
6877 len = 0;
6878 vos_mem_copy(&add_req->ucPattern[0], dst_addr.bytes, VOS_MAC_ADDR_SIZE);
6879 len += VOS_MAC_ADDR_SIZE;
6880 vos_mem_copy(&add_req->ucPattern[len], add_req->macAddress,
6881 VOS_MAC_ADDR_SIZE);
6882 len += VOS_MAC_ADDR_SIZE;
6883 vos_mem_copy(&add_req->ucPattern[len], &eth_type, 2);
6884 len += 2;
6885
6886 /*
6887 * This is the IP packet, add 14 bytes Ethernet (802.3) header
6888 * ------------------------------------------------------------
6889 * | 14 bytes Ethernet (802.3) header | IP header and payload |
6890 * ------------------------------------------------------------
6891 */
6892 vos_mem_copy(&add_req->ucPattern[len],
6893 nla_data(tb[PARAM_IP_PACKET]),
6894 add_req->ucPtrnSize);
6895 add_req->ucPtrnSize += len;
6896
6897 VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6898 add_req->ucPattern, add_req->ucPtrnSize);
6899
6900 ret = hdd_map_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
6901 if (ret)
6902 {
6903 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
6904 goto fail;
6905 }
6906 add_req->ucPtrnId = pattern_id;
6907 hddLog(LOG1, FL("pattern id: %d"), add_req->ucPtrnId);
6908
6909 status = sme_AddPeriodicTxPtrn(hdd_ctx->hHal, add_req);
6910 if (!HAL_STATUS_SUCCESS(status))
6911 {
6912 hddLog(LOGE,
6913 FL("sme_AddPeriodicTxPtrn failed (err=%d)"), status);
6914 goto fail;
6915 }
6916
6917 EXIT();
6918 vos_mem_free(add_req);
6919 return 0;
6920
6921fail:
6922 vos_mem_free(add_req);
6923 return -EINVAL;
6924}
6925
6926/**
6927 * wlan_hdd_del_tx_ptrn() - delete tx pattern
6928 * @adapter: adapter pointer
6929 * @hdd_ctx: hdd context
6930 * @tb: nl attributes
6931 *
6932 * This function reads the NL attributes and forms a DelTxPtrn message
6933 * posts it to SME.
6934 *
6935 */
6936static int
6937wlan_hdd_del_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
6938 struct nlattr **tb)
6939{
6940 struct sSirDelPeriodicTxPtrn *del_req;
6941 eHalStatus status;
6942 uint32_t request_id, ret;
6943 uint8_t pattern_id = 0;
6944
6945 /* Parse and fetch request Id */
6946 if (!tb[PARAM_REQUEST_ID])
6947 {
6948 hddLog(LOGE, FL("attr request id failed"));
6949 return -EINVAL;
6950 }
6951 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
6952 if (request_id == 0)
6953 {
6954 hddLog(LOGE, FL("request_id cannot be zero"));
6955 return -EINVAL;
6956 }
6957
6958 ret = hdd_unmap_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
6959 if (ret)
6960 {
6961 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
6962 return -EINVAL;
6963 }
6964
6965 del_req = vos_mem_malloc(sizeof(*del_req));
6966 if (!del_req)
6967 {
6968 hddLog(LOGE, FL("memory allocation failed"));
6969 return -ENOMEM;
6970 }
6971
6972 vos_mem_set(del_req, sizeof(*del_req), 0);
6973 vos_mem_copy(del_req->macAddress, adapter->macAddressCurrent.bytes,
6974 VOS_MAC_ADDR_SIZE);
6975 hddLog(LOG1, MAC_ADDRESS_STR, MAC_ADDR_ARRAY(del_req->macAddress));
6976 del_req->ucPatternIdBitmap |= (0x1 << pattern_id);
6977 hddLog(LOG1, FL("Request Id: %u Pattern id: %d, bitmap %04x"),
6978 request_id, pattern_id, del_req->ucPatternIdBitmap);
6979
6980 status = sme_DelPeriodicTxPtrn(hdd_ctx->hHal, del_req);
6981 if (!HAL_STATUS_SUCCESS(status))
6982 {
6983 hddLog(LOGE,
6984 FL("sme_DelPeriodicTxPtrn failed (err=%d)"), status);
6985 goto fail;
6986 }
6987
6988 EXIT();
6989 vos_mem_free(del_req);
6990 return 0;
6991
6992fail:
6993 vos_mem_free(del_req);
6994 return -EINVAL;
6995}
6996
6997
6998/**
6999 * __wlan_hdd_cfg80211_offloaded_packets() - send offloaded packets
7000 * @wiphy: Pointer to wireless phy
7001 * @wdev: Pointer to wireless device
7002 * @data: Pointer to data
7003 * @data_len: Data length
7004 *
7005 * Return: 0 on success, negative errno on failure
7006 */
7007static int
7008__wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7009 struct wireless_dev *wdev,
7010 const void *data,
7011 int data_len)
7012{
7013 struct net_device *dev = wdev->netdev;
7014 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7015 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7016 struct nlattr *tb[PARAM_MAX + 1];
7017 uint8_t control;
7018 int ret;
7019 static const struct nla_policy policy[PARAM_MAX + 1] =
7020 {
7021 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
7022 [PARAM_CONTROL] = { .type = NLA_U32 },
7023 [PARAM_SRC_MAC_ADDR] = { .type = NLA_BINARY,
7024 .len = VOS_MAC_ADDR_SIZE },
7025 [PARAM_DST_MAC_ADDR] = { .type = NLA_BINARY,
7026 .len = VOS_MAC_ADDR_SIZE },
7027 [PARAM_PERIOD] = { .type = NLA_U32 },
7028 };
7029
7030 ENTER();
7031
7032 ret = wlan_hdd_validate_context(hdd_ctx);
7033 if (0 != ret)
7034 {
7035 hddLog(LOGE, FL("HDD context is not valid"));
7036 return ret;
7037 }
7038
7039 if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN))
7040 {
7041 hddLog(LOGE,
7042 FL("Periodic Tx Pattern Offload feature is not supported in FW!"));
7043 return -ENOTSUPP;
7044 }
7045
7046 if (nla_parse(tb, PARAM_MAX, data, data_len, policy))
7047 {
7048 hddLog(LOGE, FL("Invalid ATTR"));
7049 return -EINVAL;
7050 }
7051
7052 if (!tb[PARAM_CONTROL])
7053 {
7054 hddLog(LOGE, FL("attr control failed"));
7055 return -EINVAL;
7056 }
7057 control = nla_get_u32(tb[PARAM_CONTROL]);
7058 hddLog(LOG1, FL("Control: %d"), control);
7059
7060 if (control == WLAN_START_OFFLOADED_PACKETS)
7061 return wlan_hdd_add_tx_ptrn(adapter, hdd_ctx, tb);
7062 else if (control == WLAN_STOP_OFFLOADED_PACKETS)
7063 return wlan_hdd_del_tx_ptrn(adapter, hdd_ctx, tb);
7064 else
7065 {
7066 hddLog(LOGE, FL("Invalid control: %d"), control);
7067 return -EINVAL;
7068 }
7069}
7070
7071/*
7072 * done with short names for the global vendor params
7073 * used by __wlan_hdd_cfg80211_offloaded_packets()
7074 */
7075#undef PARAM_MAX
7076#undef PARAM_REQUEST_ID
7077#undef PARAM_CONTROL
7078#undef PARAM_IP_PACKET
7079#undef PARAM_SRC_MAC_ADDR
7080#undef PARAM_DST_MAC_ADDR
7081#undef PARAM_PERIOD
7082
7083/**
7084 * wlan_hdd_cfg80211_offloaded_packets() - Wrapper to offload packets
7085 * @wiphy: wiphy structure pointer
7086 * @wdev: Wireless device structure pointer
7087 * @data: Pointer to the data received
7088 * @data_len: Length of @data
7089 *
7090 * Return: 0 on success; errno on failure
7091 */
7092static int wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7093 struct wireless_dev *wdev,
7094 const void *data,
7095 int data_len)
7096{
7097 int ret = 0;
7098
7099 vos_ssr_protect(__func__);
7100 ret = __wlan_hdd_cfg80211_offloaded_packets(wiphy,
7101 wdev, data, data_len);
7102 vos_ssr_unprotect(__func__);
7103
7104 return ret;
7105}
7106#endif
7107
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307108static const struct
7109nla_policy
7110qca_wlan_vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
7111 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
7112};
7113
7114/**
7115 * wlan_hdd_cfg80211_get_link_properties() - This function is used to
7116 * get link properties like nss, rate flags and operating frequency for
7117 * the connection with the given peer.
7118 * @wiphy: WIPHY structure pointer
7119 * @wdev: Wireless device structure pointer
7120 * @data: Pointer to the data received
7121 * @data_len: Length of the data received
7122 *
7123 * This function return the above link properties on success.
7124 *
7125 * Return: 0 on success and errno on failure
7126 */
7127static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
7128 struct wireless_dev *wdev,
7129 const void *data,
7130 int data_len)
7131{
7132 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7133 struct net_device *dev = wdev->netdev;
7134 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7135 hdd_station_ctx_t *hdd_sta_ctx;
7136 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX+1];
7137 uint8_t peer_mac[VOS_MAC_ADDR_SIZE];
7138 uint32_t sta_id;
7139 struct sk_buff *reply_skb;
7140 uint32_t rate_flags = 0;
7141 uint8_t nss;
7142 uint8_t final_rate_flags = 0;
7143 uint32_t freq;
7144 v_CONTEXT_t pVosContext = NULL;
7145 ptSapContext pSapCtx = NULL;
7146
7147 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
7148 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
7149 return -EINVAL;
7150 }
7151
7152 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7153 qca_wlan_vendor_attr_policy)) {
7154 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid attribute"));
7155 return -EINVAL;
7156 }
7157
7158 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
7159 hddLog(VOS_TRACE_LEVEL_ERROR,
7160 FL("Attribute peerMac not provided for mode=%d"),
7161 adapter->device_mode);
7162 return -EINVAL;
7163 }
7164
7165 memcpy(peer_mac, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
7166 sizeof(peer_mac));
7167 hddLog(VOS_TRACE_LEVEL_INFO,
7168 FL("peerMac="MAC_ADDRESS_STR" for device_mode:%d"),
7169 MAC_ADDR_ARRAY(peer_mac), adapter->device_mode);
7170
7171 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
7172 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
7173 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
7174 if ((hdd_sta_ctx->conn_info.connState !=
7175 eConnectionState_Associated) ||
7176 !vos_mem_compare(hdd_sta_ctx->conn_info.bssId, peer_mac,
7177 VOS_MAC_ADDRESS_LEN)) {
7178 hddLog(VOS_TRACE_LEVEL_ERROR,
7179 FL("Not Associated to mac "MAC_ADDRESS_STR),
7180 MAC_ADDR_ARRAY(peer_mac));
7181 return -EINVAL;
7182 }
7183
7184 nss = 1; //pronto supports only one spatial stream
7185 freq = vos_chan_to_freq(
7186 hdd_sta_ctx->conn_info.operationChannel);
7187 rate_flags = hdd_sta_ctx->conn_info.rate_flags;
7188
7189 } else if (adapter->device_mode == WLAN_HDD_P2P_GO ||
7190 adapter->device_mode == WLAN_HDD_SOFTAP) {
7191
7192 pVosContext = ( WLAN_HDD_GET_CTX(adapter))->pvosContext;
7193 pSapCtx = VOS_GET_SAP_CB(pVosContext);
7194 if(pSapCtx == NULL){
7195 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7196 FL("psapCtx is NULL"));
7197 return -ENOENT;
7198 }
7199
7200
7201 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
7202 if (pSapCtx->aStaInfo[sta_id].isUsed &&
7203 !vos_is_macaddr_broadcast(
7204 &pSapCtx->aStaInfo[sta_id].macAddrSTA) &&
7205 vos_mem_compare(
7206 &pSapCtx->aStaInfo[sta_id].macAddrSTA,
7207 peer_mac, VOS_MAC_ADDRESS_LEN))
7208 break;
7209 }
7210
7211 if (WLAN_MAX_STA_COUNT == sta_id) {
7212 hddLog(VOS_TRACE_LEVEL_ERROR,
7213 FL("No active peer with mac="MAC_ADDRESS_STR),
7214 MAC_ADDR_ARRAY(peer_mac));
7215 return -EINVAL;
7216 }
7217
7218 nss = 1; //pronto supports only one spatial stream
7219 freq = vos_chan_to_freq(
7220 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operatingChannel);
7221 rate_flags = pSapCtx->aStaInfo[sta_id].rate_flags;
7222 } else {
7223 hddLog(VOS_TRACE_LEVEL_ERROR,
7224 FL("Not Associated! with mac"MAC_ADDRESS_STR),
7225 MAC_ADDR_ARRAY(peer_mac));
7226 return -EINVAL;
7227 }
7228
7229 if (!(rate_flags & eHAL_TX_RATE_LEGACY)) {
7230 if (rate_flags & eHAL_TX_RATE_VHT80) {
7231 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7232 final_rate_flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
7233 } else if (rate_flags & eHAL_TX_RATE_VHT40) {
7234 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7235 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7236 } else if (rate_flags & eHAL_TX_RATE_VHT20) {
7237 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7238 } else if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40)) {
7239 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7240 if (rate_flags & eHAL_TX_RATE_HT40)
7241 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7242 }
7243
7244 if (rate_flags & eHAL_TX_RATE_SGI) {
7245 if (!(final_rate_flags & RATE_INFO_FLAGS_VHT_MCS))
7246 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7247 final_rate_flags |= RATE_INFO_FLAGS_SHORT_GI;
7248 }
7249 }
7250
7251 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7252 sizeof(u8) + sizeof(u8) + sizeof(u32) + NLMSG_HDRLEN);
7253
7254 if (NULL == reply_skb) {
7255 hddLog(VOS_TRACE_LEVEL_ERROR,
7256 FL("getLinkProperties: skb alloc failed"));
7257 return -EINVAL;
7258 }
7259
7260 if (nla_put_u8(reply_skb,
7261 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS,
7262 nss) ||
7263 nla_put_u8(reply_skb,
7264 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS,
7265 final_rate_flags) ||
7266 nla_put_u32(reply_skb,
7267 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ,
7268 freq)) {
7269 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_put failed"));
7270 kfree_skb(reply_skb);
7271 return -EINVAL;
7272 }
7273
7274 return cfg80211_vendor_cmd_reply(reply_skb);
7275}
7276
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307277#define BEACON_MISS_THRESH_2_4 \
7278 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24
7279#define BEACON_MISS_THRESH_5_0 \
7280 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307281#define PARAM_WIFICONFIG_MAX QCA_WLAN_VENDOR_ATTR_CONFIG_MAX
7282#define PARAM_MODULATED_DTIM QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM
7283#define PARAM_STATS_AVG_FACTOR QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR
7284#define PARAM_GUARD_TIME QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307285#define PARAM_BCNMISS_PENALTY_PARAM_COUNT \
7286 QCA_WLAN_VENDOR_ATTR_CONFIG_PENALIZE_AFTER_NCONS_BEACON_MISS
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307287
7288/**
7289 * __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7290 * vendor command
7291 *
7292 * @wiphy: wiphy device pointer
7293 * @wdev: wireless device pointer
7294 * @data: Vendor command data buffer
7295 * @data_len: Buffer length
7296 *
7297 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7298 *
7299 * Return: EOK or other error codes.
7300 */
7301
7302static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7303 struct wireless_dev *wdev,
7304 const void *data,
7305 int data_len)
7306{
7307 struct net_device *dev = wdev->netdev;
7308 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7309 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7310 hdd_station_ctx_t *pHddStaCtx;
7311 struct nlattr *tb[PARAM_WIFICONFIG_MAX + 1];
7312 tpSetWifiConfigParams pReq;
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307313 tModifyRoamParamsReqParams modifyRoamParamsReq;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307314 eHalStatus status;
7315 int ret_val;
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307316 uint8_t hb_thresh_val;
7317
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307318 static const struct nla_policy policy[PARAM_WIFICONFIG_MAX + 1] = {
7319 [PARAM_STATS_AVG_FACTOR] = { .type = NLA_U16 },
7320 [PARAM_MODULATED_DTIM] = { .type = NLA_U32 },
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307321 [PARAM_GUARD_TIME] = { .type = NLA_U32},
7322 [PARAM_BCNMISS_PENALTY_PARAM_COUNT] =
7323 { .type = NLA_U32},
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307324 [BEACON_MISS_THRESH_2_4] = { .type = NLA_U8 },
7325 [BEACON_MISS_THRESH_5_0] = { .type = NLA_U8 },
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307326 };
7327
7328 ENTER();
7329
7330 if (VOS_FTM_MODE == hdd_get_conparam()) {
7331 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7332 return -EINVAL;
7333 }
7334
7335 ret_val = wlan_hdd_validate_context(pHddCtx);
7336 if (ret_val) {
7337 return ret_val;
7338 }
7339
7340 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7341
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307342 if (nla_parse(tb, PARAM_WIFICONFIG_MAX, data, data_len, policy)) {
7343 hddLog(LOGE, FL("Invalid ATTR"));
7344 return -EINVAL;
7345 }
7346
7347 /* check the Wifi Capability */
7348 if ( (TRUE != pHddCtx->cfg_ini->fEnableWifiConfig) &&
7349 (TRUE != sme_IsFeatureSupportedByFW(WIFI_CONFIG)))
7350 {
7351 hddLog(VOS_TRACE_LEVEL_ERROR,
7352 FL("WIFICONFIG not supported by Firmware"));
7353 return -EINVAL;
7354 }
7355
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307356 if (tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]) {
7357 modifyRoamParamsReq.param = WIFI_CONFIG_SET_BCNMISS_PENALTY_COUNT;
7358 modifyRoamParamsReq.value =
7359 nla_get_u32(tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]);
7360
7361 if (eHAL_STATUS_SUCCESS !=
7362 sme_setBcnMissPenaltyCount(pHddCtx->hHal,&modifyRoamParamsReq))
7363 {
7364 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed", __func__);
7365 ret_val = -EINVAL;
7366 }
7367 return ret_val;
7368 }
7369
7370 /* Moved this down in order to provide provision to set beacon
7371 * miss penalty count irrespective of connection state.
7372 */
7373 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
7374 hddLog(LOGE, FL("Not in Connected state!"));
7375 return -ENOTSUPP;
7376 }
7377
7378 pReq = vos_mem_malloc(sizeof(tSetWifiConfigParams));
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307379
7380 if (!pReq) {
7381 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7382 "%s: Not able to allocate memory for tSetWifiConfigParams",
7383 __func__);
7384 return eHAL_STATUS_E_MALLOC_FAILED;
7385 }
7386
7387 vos_mem_set(pReq, sizeof(tSetWifiConfigParams), 0);
7388
7389 pReq->sessionId = pAdapter->sessionId;
7390 vos_mem_copy( &pReq->bssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
7391
7392 if (tb[PARAM_MODULATED_DTIM]) {
7393 pReq->paramValue = nla_get_u32(
7394 tb[PARAM_MODULATED_DTIM]);
7395 hddLog(LOG1, FL("Modulated DTIM: pReq->paramValue:%d "),
7396 pReq->paramValue);
Arun Khandavalli876886f2015-11-23 11:42:27 +05307397 pHddCtx->cfg_ini->enableDynamicDTIM = pReq->paramValue;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307398 hdd_set_pwrparams(pHddCtx);
7399 if (BMPS == pmcGetPmcState(pHddCtx->hHal)) {
7400 hddLog( LOG1, FL("WifiConfig: Requesting FullPower!"));
7401
7402 sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
7403 iw_full_power_cbfn, pAdapter,
7404 eSME_FULL_PWR_NEEDED_BY_HDD);
7405 }
7406 else
7407 {
7408 hddLog( LOG1, FL("WifiConfig Not in BMPS state"));
7409 }
7410 }
7411
7412 if (tb[PARAM_STATS_AVG_FACTOR]) {
7413 pReq->paramType = WIFI_CONFIG_SET_AVG_STATS_FACTOR;
7414 pReq->paramValue = nla_get_u16(
7415 tb[PARAM_STATS_AVG_FACTOR]);
7416 hddLog(LOG1, FL("AVG_STATS_FACTOR pReq->paramType:%d,pReq->paramValue:%d "),
7417 pReq->paramType, pReq->paramValue);
7418 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7419
7420 if (eHAL_STATUS_SUCCESS != status)
7421 {
7422 vos_mem_free(pReq);
7423 pReq = NULL;
7424 ret_val = -EPERM;
7425 return ret_val;
7426 }
7427 }
7428
7429
7430 if (tb[PARAM_GUARD_TIME]) {
7431 pReq->paramType = WIFI_CONFIG_SET_GUARD_TIME;
7432 pReq->paramValue = nla_get_u32(
7433 tb[PARAM_GUARD_TIME]);
7434 hddLog(LOG1, FL("GUARD_TIME pReq->paramType:%d,pReq->paramValue:%d "),
7435 pReq->paramType, pReq->paramValue);
7436 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7437
7438 if (eHAL_STATUS_SUCCESS != status)
7439 {
7440 vos_mem_free(pReq);
7441 pReq = NULL;
7442 ret_val = -EPERM;
7443 return ret_val;
7444 }
7445
7446 }
7447
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307448 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]) {
7449 hb_thresh_val = nla_get_u8(
7450 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]);
7451
7452 hddLog(LOG1, "WLAN set heartbeat threshold for 2.4Ghz %d",
7453 hb_thresh_val);
7454 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7455 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
7456 NULL, eANI_BOOLEAN_FALSE);
7457
7458 status = sme_update_hb_threshold(
7459 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
7460 WNI_CFG_HEART_BEAT_THRESHOLD,
7461 hb_thresh_val, eCSR_BAND_24);
7462 if (eHAL_STATUS_SUCCESS != status) {
7463 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
7464 vos_mem_free(pReq);
7465 pReq = NULL;
7466 return -EPERM;
7467 }
7468 }
7469
7470 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]) {
7471 hb_thresh_val = nla_get_u8(
7472 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]);
7473
7474 hddLog(LOG1, "WLAN set heartbeat threshold for 5Ghz %d",
7475 hb_thresh_val);
7476 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7477 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
7478 NULL, eANI_BOOLEAN_FALSE);
7479
7480 status = sme_update_hb_threshold(
7481 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
7482 WNI_CFG_HEART_BEAT_THRESHOLD,
7483 hb_thresh_val, eCSR_BAND_5G);
7484 if (eHAL_STATUS_SUCCESS != status) {
7485 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
7486 vos_mem_free(pReq);
7487 pReq = NULL;
7488 return -EPERM;
7489 }
7490 }
7491
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307492 EXIT();
7493 return ret_val;
7494}
7495
7496/**
7497 * wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7498 * vendor command
7499 *
7500 * @wiphy: wiphy device pointer
7501 * @wdev: wireless device pointer
7502 * @data: Vendor command data buffer
7503 * @data_len: Buffer length
7504 *
7505 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7506 *
7507 * Return: EOK or other error codes.
7508 */
7509static int wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7510 struct wireless_dev *wdev,
7511 const void *data,
7512 int data_len)
7513{
7514 int ret;
7515
7516 vos_ssr_protect(__func__);
7517 ret = __wlan_hdd_cfg80211_wifi_configuration_set(wiphy, wdev,
7518 data, data_len);
7519 vos_ssr_unprotect(__func__);
7520
7521 return ret;
7522}
Anurag Chouhan6ee81542017-02-09 18:09:27 +05307523
7524/*
7525 * define short names for the global vendor params
7526 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
7527 */
7528#define STATS_SET_INVALID \
7529 QCA_ATTR_NUD_STATS_SET_INVALID
7530#define STATS_SET_START \
7531 QCA_ATTR_NUD_STATS_SET_START
7532#define STATS_GW_IPV4 \
7533 QCA_ATTR_NUD_STATS_GW_IPV4
7534#define STATS_SET_MAX \
7535 QCA_ATTR_NUD_STATS_SET_MAX
7536
7537const struct nla_policy
7538qca_wlan_vendor_set_nud_stats[STATS_SET_MAX +1] =
7539{
7540 [STATS_SET_START] = {.type = NLA_FLAG },
7541 [STATS_GW_IPV4] = {.type = NLA_U32 },
7542};
7543
7544/**
7545 * hdd_set_nud_stats_cb() - hdd callback api to get status
7546 * @data: pointer to adapter
7547 * @rsp: status
7548 *
7549 * Return: None
7550 */
7551static void hdd_set_nud_stats_cb(void *data, VOS_STATUS rsp)
7552{
7553
7554 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
7555
7556 if (NULL == adapter)
7557 return;
7558
7559 if (VOS_STATUS_SUCCESS == rsp) {
7560 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7561 "%s success received STATS_SET_START", __func__);
7562 } else {
7563 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7564 "%s STATS_SET_START Failed!!", __func__);
7565 }
7566 return;
7567}
7568
7569/**
7570 * __wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
7571 * @wiphy: pointer to wireless wiphy structure.
7572 * @wdev: pointer to wireless_dev structure.
7573 * @data: pointer to apfind configuration data.
7574 * @data_len: the length in byte of apfind data.
7575 *
7576 * This is called when wlan driver needs to send arp stats to
7577 * firmware.
7578 *
7579 * Return: An error code or 0 on success.
7580 */
7581static int __wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
7582 struct wireless_dev *wdev,
7583 const void *data, int data_len)
7584{
7585 struct nlattr *tb[STATS_SET_MAX + 1];
7586 struct net_device *dev = wdev->netdev;
7587 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7588 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05307589 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
Anurag Chouhan6ee81542017-02-09 18:09:27 +05307590 setArpStatsParams arp_stats_params;
7591 int err = 0;
7592
7593 ENTER();
7594
7595 err = wlan_hdd_validate_context(hdd_ctx);
7596 if (0 != err)
7597 return err;
7598
7599 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
7600 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7601 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
7602 return -EINVAL;
7603 }
7604
7605 err = nla_parse(tb, STATS_SET_MAX, data, data_len,
7606 qca_wlan_vendor_set_nud_stats);
7607 if (err)
7608 {
7609 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7610 "%s STATS_SET_START ATTR", __func__);
7611 return err;
7612 }
7613
7614 if (tb[STATS_SET_START])
7615 {
7616 if (!tb[STATS_GW_IPV4]) {
7617 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7618 "%s STATS_SET_START CMD", __func__);
7619 return -EINVAL;
7620 }
7621 arp_stats_params.flag = true;
7622 arp_stats_params.ip_addr = nla_get_u32(tb[STATS_GW_IPV4]);
7623 } else {
7624 arp_stats_params.flag = false;
7625 }
Anurag Chouhan630c5562017-03-23 14:51:47 +05307626 if (arp_stats_params.flag)
Anurag Chouhan6ee81542017-02-09 18:09:27 +05307627 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7628 "%s STATS_SET_START Cleared!!", __func__);
Anurag Chouhan630c5562017-03-23 14:51:47 +05307629 vos_mem_zero(&adapter->hdd_stats.hddArpStats,
7630 sizeof(adapter->hdd_stats.hddArpStats));
Anurag Chouhan6ee81542017-02-09 18:09:27 +05307631
7632 arp_stats_params.pkt_type = 1; // ARP packet type
7633
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05307634 if (arp_stats_params.flag) {
7635 hdd_ctx->track_arp_ip = arp_stats_params.ip_addr;
7636 WLANTL_SetARPFWDatapath(pVosContext, true);
7637 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7638 "%s Set FW in data path for ARP with tgt IP :%d",
7639 __func__, hdd_ctx->track_arp_ip);
7640 }
7641 else {
7642 WLANTL_SetARPFWDatapath(pVosContext, false);
7643 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7644 "%s Remove FW from data path", __func__);
7645 }
7646
Anurag Chouhan6ee81542017-02-09 18:09:27 +05307647 arp_stats_params.rsp_cb_fn = hdd_set_nud_stats_cb;
7648 arp_stats_params.data_ctx = adapter;
7649
7650 if (eHAL_STATUS_SUCCESS !=
7651 sme_set_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
7652 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7653 "%s STATS_SET_START CMD Failed!!", __func__);
7654 return -EINVAL;
7655 }
7656
7657 EXIT();
7658
7659 return err;
7660}
7661
7662/**
7663 * wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
7664 * @wiphy: pointer to wireless wiphy structure.
7665 * @wdev: pointer to wireless_dev structure.
7666 * @data: pointer to apfind configuration data.
7667 * @data_len: the length in byte of apfind data.
7668 *
7669 * This is called when wlan driver needs to send arp stats to
7670 * firmware.
7671 *
7672 * Return: An error code or 0 on success.
7673 */
7674static int wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
7675 struct wireless_dev *wdev,
7676 const void *data, int data_len)
7677{
7678 int ret;
7679
7680 vos_ssr_protect(__func__);
7681 ret = __wlan_hdd_cfg80211_set_nud_stats(wiphy, wdev, data, data_len);
7682 vos_ssr_unprotect(__func__);
7683
7684 return ret;
7685}
7686#undef STATS_SET_INVALID
7687#undef STATS_SET_START
7688#undef STATS_GW_IPV4
7689#undef STATS_SET_MAX
7690
7691/*
7692 * define short names for the global vendor params
7693 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
7694 */
7695#define STATS_GET_INVALID \
7696 QCA_ATTR_NUD_STATS_SET_INVALID
7697#define COUNT_FROM_NETDEV \
7698 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
7699#define COUNT_TO_LOWER_MAC \
7700 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
7701#define RX_COUNT_BY_LOWER_MAC \
7702 QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
7703#define COUNT_TX_SUCCESS \
7704 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
7705#define RSP_RX_COUNT_BY_LOWER_MAC \
7706 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
7707#define RSP_RX_COUNT_BY_UPPER_MAC \
7708 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
7709#define RSP_COUNT_TO_NETDEV \
7710 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
7711#define RSP_COUNT_OUT_OF_ORDER_DROP \
7712 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
7713#define AP_LINK_ACTIVE \
7714 QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
7715#define AP_LINK_DAD \
7716 QCA_ATTR_NUD_STATS_AP_LINK_DAD
7717#define STATS_GET_MAX \
7718 QCA_ATTR_NUD_STATS_GET_MAX
7719
7720const struct nla_policy
7721qca_wlan_vendor_get_nud_stats[STATS_GET_MAX +1] =
7722{
7723 [COUNT_FROM_NETDEV] = {.type = NLA_U16 },
7724 [COUNT_TO_LOWER_MAC] = {.type = NLA_U16 },
7725 [RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
7726 [COUNT_TX_SUCCESS] = {.type = NLA_U16 },
7727 [RSP_RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
7728 [RSP_RX_COUNT_BY_UPPER_MAC] = {.type = NLA_U16 },
7729 [RSP_COUNT_TO_NETDEV] = {.type = NLA_U16 },
7730 [RSP_COUNT_OUT_OF_ORDER_DROP] = {.type = NLA_U16 },
7731 [AP_LINK_ACTIVE] = {.type = NLA_FLAG },
7732 [AP_LINK_DAD] = {.type = NLA_FLAG },
7733};
7734
7735static void hdd_get_nud_stats_cb(void *data, rsp_stats *rsp)
7736{
7737
7738 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
7739 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
7740 struct hdd_nud_stats_context *context;
7741 int status;
7742
7743 ENTER();
7744
7745 if (NULL == adapter)
7746 return;
7747
7748 status = wlan_hdd_validate_context(hdd_ctx);
7749 if (0 != status) {
7750 return;
7751 }
7752
7753 if (!rsp) {
7754 hddLog(LOGE, FL("data is null"));
7755 return;
7756 }
7757
7758 adapter->hdd_stats.hddArpStats.tx_fw_cnt = rsp->tx_fw_cnt;
7759 adapter->hdd_stats.hddArpStats.rx_fw_cnt = rsp->rx_fw_cnt;
7760 adapter->hdd_stats.hddArpStats.tx_ack_cnt = rsp->tx_ack_cnt;
7761 adapter->dad |= rsp->dad;
7762
7763 spin_lock(&hdd_context_lock);
7764 context = &hdd_ctx->nud_stats_context;
7765 complete(&context->response_event);
7766 spin_unlock(&hdd_context_lock);
7767
7768 return;
7769}
7770static int __wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
7771 struct wireless_dev *wdev,
7772 const void *data, int data_len)
7773{
7774 int err = 0;
7775 unsigned long rc;
7776 struct hdd_nud_stats_context *context;
7777 struct net_device *dev = wdev->netdev;
7778 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7779 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7780 getArpStatsParams arp_stats_params;
7781 struct sk_buff *skb;
7782
7783 ENTER();
7784
7785 err = wlan_hdd_validate_context(hdd_ctx);
7786 if (0 != err)
7787 return err;
7788
7789 arp_stats_params.pkt_type = WLAN_NUD_STATS_ARP_PKT_TYPE;
7790 arp_stats_params.get_rsp_cb_fn = hdd_get_nud_stats_cb;
7791 arp_stats_params.data_ctx = adapter;
7792
7793 spin_lock(&hdd_context_lock);
7794 context = &hdd_ctx->nud_stats_context;
7795 INIT_COMPLETION(context->response_event);
7796 spin_unlock(&hdd_context_lock);
7797
7798 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
7799 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7800 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
7801 return -EINVAL;
7802 }
7803
7804 if (eHAL_STATUS_SUCCESS !=
7805 sme_get_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
7806 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7807 "%s STATS_SET_START CMD Failed!!", __func__);
7808 return -EINVAL;
7809 }
7810
7811 rc = wait_for_completion_timeout(&context->response_event,
7812 msecs_to_jiffies(WLAN_WAIT_TIME_NUD_STATS));
7813 if (!rc)
7814 {
7815 hddLog(LOGE,
7816 FL("Target response timed out request "));
7817 return -ETIMEDOUT;
7818 }
7819
7820 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7821 WLAN_NUD_STATS_LEN);
7822 if (!skb)
7823 {
7824 hddLog(VOS_TRACE_LEVEL_ERROR,
7825 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
7826 __func__);
7827 return -ENOMEM;
7828 }
7829
7830 if (nla_put_u16(skb, COUNT_FROM_NETDEV,
7831 adapter->hdd_stats.hddArpStats.txCount) ||
7832 nla_put_u16(skb, COUNT_TO_LOWER_MAC,
7833 adapter->hdd_stats.hddArpStats.tx_host_fw_sent) ||
7834 nla_put_u16(skb, RX_COUNT_BY_LOWER_MAC,
7835 adapter->hdd_stats.hddArpStats.tx_fw_cnt) ||
7836 nla_put_u16(skb, COUNT_TX_SUCCESS,
7837 adapter->hdd_stats.hddArpStats.tx_ack_cnt) ||
7838 nla_put_u16(skb, RSP_RX_COUNT_BY_LOWER_MAC,
7839 adapter->hdd_stats.hddArpStats.rx_fw_cnt) ||
7840 nla_put_u16(skb, RSP_RX_COUNT_BY_UPPER_MAC,
7841 adapter->hdd_stats.hddArpStats.rxCount) ||
7842 nla_put_u16(skb, RSP_COUNT_TO_NETDEV,
7843 adapter->hdd_stats.hddArpStats.rxDelivered) ||
7844 nla_put_u16(skb, RSP_COUNT_OUT_OF_ORDER_DROP,
7845 adapter->hdd_stats.hddArpStats.rx_host_drop_reorder)) {
7846 hddLog(LOGE, FL("nla put fail"));
7847 kfree_skb(skb);
7848 return -EINVAL;
7849 }
7850 if (adapter->con_status)
7851 nla_put_flag(skb, AP_LINK_ACTIVE);
7852 if (adapter->dad)
7853 nla_put_flag(skb, AP_LINK_DAD);
7854
7855 cfg80211_vendor_cmd_reply(skb);
7856 return err;
7857}
7858
7859static int wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
7860 struct wireless_dev *wdev,
7861 const void *data, int data_len)
7862{
7863 int ret;
7864
7865 vos_ssr_protect(__func__);
7866 ret = __wlan_hdd_cfg80211_get_nud_stats(wiphy, wdev, data, data_len);
7867 vos_ssr_unprotect(__func__);
7868
7869 return ret;
7870}
7871
7872#undef QCA_ATTR_NUD_STATS_SET_INVALID
7873#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
7874#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
7875#undef QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
7876#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
7877#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
7878#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
7879#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
7880#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
7881#undef QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
7882#undef QCA_ATTR_NUD_STATS_GET_MAX
7883
7884
7885
Kapil Guptaee33bf12016-12-20 18:27:37 +05307886#ifdef WLAN_FEATURE_APFIND
7887/**
7888 * __wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
7889 * @wiphy: pointer to wireless wiphy structure.
7890 * @wdev: pointer to wireless_dev structure.
7891 * @data: pointer to apfind configuration data.
7892 * @data_len: the length in byte of apfind data.
7893 *
7894 * This is called when wlan driver needs to send APFIND configurations to
7895 * firmware.
7896 *
7897 * Return: An error code or 0 on success.
7898 */
7899static int __wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
7900 struct wireless_dev *wdev,
7901 const void *data, int data_len)
7902{
7903 struct sme_ap_find_request_req apfind_req;
7904 VOS_STATUS status;
7905 int ret_val;
7906 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7907
7908 ENTER();
7909
7910 ret_val = wlan_hdd_validate_context(hdd_ctx);
7911 if (ret_val)
7912 return ret_val;
7913
7914 if (VOS_FTM_MODE == hdd_get_conparam()) {
7915 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7916 return -EPERM;
7917 }
7918
7919 apfind_req.request_data_len = data_len;
7920 apfind_req.request_data = data;
7921
7922 status = sme_apfind_set_cmd(&apfind_req);
7923 if (VOS_STATUS_SUCCESS != status) {
7924 ret_val = -EIO;
7925 }
7926 return ret_val;
7927}
7928
7929/**
7930 * wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
7931 * @wiphy: pointer to wireless wiphy structure.
7932 * @wdev: pointer to wireless_dev structure.
7933 * @data: pointer to apfind configuration data.
7934 * @data_len: the length in byte of apfind data.
7935 *
7936 * This is called when wlan driver needs to send APFIND configurations to
7937 * firmware.
7938 *
7939 * Return: An error code or 0 on success.
7940 */
7941static int wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
7942 struct wireless_dev *wdev,
7943 const void *data, int data_len)
7944{
7945 int ret;
7946
7947 vos_ssr_protect(__func__);
7948 ret = __wlan_hdd_cfg80211_apfind_cmd(wiphy, wdev, data, data_len);
7949 vos_ssr_unprotect(__func__);
7950
7951 return ret;
7952}
7953#endif /* WLAN_FEATURE_APFIND */
Sunil Duttc69bccb2014-05-26 21:30:20 +05307954const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
7955{
Mukul Sharma2a271632014-10-13 14:59:01 +05307956 {
7957 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7958 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
7959 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7960 WIPHY_VENDOR_CMD_NEED_NETDEV |
7961 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307962 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05307963 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05307964
7965 {
7966 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7967 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
7968 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7969 WIPHY_VENDOR_CMD_NEED_NETDEV |
7970 WIPHY_VENDOR_CMD_NEED_RUNNING,
7971 .doit = wlan_hdd_cfg80211_nan_request
7972 },
7973
Sunil Duttc69bccb2014-05-26 21:30:20 +05307974#ifdef WLAN_FEATURE_LINK_LAYER_STATS
7975 {
7976 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7977 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
7978 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7979 WIPHY_VENDOR_CMD_NEED_NETDEV |
7980 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307981 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05307982 },
7983
7984 {
7985 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7986 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
7987 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7988 WIPHY_VENDOR_CMD_NEED_NETDEV |
7989 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307990 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05307991 },
7992
7993 {
7994 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7995 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
7996 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7997 WIPHY_VENDOR_CMD_NEED_NETDEV |
7998 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307999 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05308000 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308001#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308002#ifdef WLAN_FEATURE_EXTSCAN
8003 {
8004 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8005 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
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_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05308010 },
8011 {
8012 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8013 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
8014 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8015 WIPHY_VENDOR_CMD_NEED_NETDEV |
8016 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308017 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05308018 },
8019 {
8020 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8021 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
8022 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8023 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308024 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05308025 },
8026 {
8027 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8028 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
8029 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8030 WIPHY_VENDOR_CMD_NEED_NETDEV |
8031 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308032 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05308033 },
8034 {
8035 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8036 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
8037 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8038 WIPHY_VENDOR_CMD_NEED_NETDEV |
8039 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308040 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05308041 },
8042 {
8043 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8044 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
8045 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8046 WIPHY_VENDOR_CMD_NEED_NETDEV |
8047 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308048 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308049 },
8050 {
8051 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8052 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
8053 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8054 WIPHY_VENDOR_CMD_NEED_NETDEV |
8055 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308056 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308057 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05308058 {
8059 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8060 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST,
8061 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8062 WIPHY_VENDOR_CMD_NEED_NETDEV |
8063 WIPHY_VENDOR_CMD_NEED_RUNNING,
8064 .doit = wlan_hdd_cfg80211_extscan_set_ssid_hotlist
8065 },
8066 {
8067 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8068 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST,
8069 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8070 WIPHY_VENDOR_CMD_NEED_NETDEV |
8071 WIPHY_VENDOR_CMD_NEED_RUNNING,
8072 .doit = wlan_hdd_cfg80211_extscan_reset_ssid_hotlist
8073 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308074#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308075/*EXT TDLS*/
8076 {
8077 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8078 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
8079 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8080 WIPHY_VENDOR_CMD_NEED_NETDEV |
8081 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308082 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05308083 },
8084 {
8085 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8086 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
8087 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8088 WIPHY_VENDOR_CMD_NEED_NETDEV |
8089 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308090 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05308091 },
8092 {
8093 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8094 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
8095 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8096 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308097 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05308098 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05308099 {
8100 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8101 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
8102 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8103 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308104 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05308105 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05308106 {
8107 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8108 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
8109 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8110 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308111 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05308112 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308113 {
8114 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8115 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
8116 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8117 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308118 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308119 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308120 {
8121 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8122 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
8123 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8124 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308125 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308126 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308127 {
8128 .info.vendor_id = QCA_NL80211_VENDOR_ID,
c_manjeecfd1efb2015-09-25 19:32:34 +05308129 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
8130 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8131 WIPHY_VENDOR_CMD_NEED_NETDEV |
8132 WIPHY_VENDOR_CMD_NEED_RUNNING,
8133 .doit = wlan_hdd_cfg80211_get_fw_mem_dump
8134 },
8135 {
8136 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308137 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
8138 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8139 WIPHY_VENDOR_CMD_NEED_NETDEV |
8140 WIPHY_VENDOR_CMD_NEED_RUNNING,
8141 .doit = wlan_hdd_cfg80211_setband
Sushant Kaushik8e644982015-09-23 12:18:54 +05308142 },
8143 {
8144 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8145 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
8146 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8147 WIPHY_VENDOR_CMD_NEED_NETDEV,
8148 .doit = wlan_hdd_cfg80211_wifi_logger_start
8149 },
Sushant Kaushik847890c2015-09-28 16:05:17 +05308150 {
8151 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8152 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
8153 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8154 WIPHY_VENDOR_CMD_NEED_NETDEV|
8155 WIPHY_VENDOR_CMD_NEED_RUNNING,
8156 .doit = wlan_hdd_cfg80211_get_wifi_info
Sachin Ahujac08f72a2015-09-22 15:25:47 +05308157 },
8158 {
8159 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8160 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
8161 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8162 WIPHY_VENDOR_CMD_NEED_NETDEV |
8163 WIPHY_VENDOR_CMD_NEED_RUNNING,
8164 .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308165 },
8166 {
8167 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8168 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,
8169 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8170 WIPHY_VENDOR_CMD_NEED_NETDEV |
8171 WIPHY_VENDOR_CMD_NEED_RUNNING,
8172 .doit = wlan_hdd_cfg80211_monitor_rssi
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308173 },
8174#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
8175 {
8176 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8177 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS,
8178 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8179 WIPHY_VENDOR_CMD_NEED_NETDEV |
8180 WIPHY_VENDOR_CMD_NEED_RUNNING,
8181 .doit = wlan_hdd_cfg80211_offloaded_packets
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308182 },
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308183#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308184 {
8185 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8186 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
8187 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8188 WIPHY_VENDOR_CMD_NEED_NETDEV |
8189 WIPHY_VENDOR_CMD_NEED_RUNNING,
8190 .doit = wlan_hdd_cfg80211_get_link_properties
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05308191 },
8192 {
8193 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8194 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION,
8195 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8196 WIPHY_VENDOR_CMD_NEED_NETDEV |
8197 WIPHY_VENDOR_CMD_NEED_RUNNING,
8198 .doit = wlan_hdd_cfg80211_wifi_configuration_set
Kapil Guptaee33bf12016-12-20 18:27:37 +05308199 },
8200#ifdef WLAN_FEATURE_APFIND
8201 {
8202 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8203 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_APFIND,
8204 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8205 WIPHY_VENDOR_CMD_NEED_NETDEV,
8206 .doit = wlan_hdd_cfg80211_apfind_cmd
8207 },
8208#endif /* WLAN_FEATURE_APFIND */
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308209 {
8210 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8211 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET,
8212 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8213 WIPHY_VENDOR_CMD_NEED_NETDEV |
8214 WIPHY_VENDOR_CMD_NEED_RUNNING,
8215 .doit = wlan_hdd_cfg80211_set_nud_stats
8216 },
8217 {
8218 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8219 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8220 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8221 WIPHY_VENDOR_CMD_NEED_NETDEV |
8222 WIPHY_VENDOR_CMD_NEED_RUNNING,
8223 .doit = wlan_hdd_cfg80211_get_nud_stats
8224 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308225};
8226
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008227/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05308228static const
8229struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008230{
8231#ifdef FEATURE_WLAN_CH_AVOID
8232 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05308233 .vendor_id = QCA_NL80211_VENDOR_ID,
8234 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008235 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308236#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
8237#ifdef WLAN_FEATURE_LINK_LAYER_STATS
8238 {
8239 /* Index = 1*/
8240 .vendor_id = QCA_NL80211_VENDOR_ID,
8241 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
8242 },
8243 {
8244 /* Index = 2*/
8245 .vendor_id = QCA_NL80211_VENDOR_ID,
8246 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
8247 },
8248 {
8249 /* Index = 3*/
8250 .vendor_id = QCA_NL80211_VENDOR_ID,
8251 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
8252 },
8253 {
8254 /* Index = 4*/
8255 .vendor_id = QCA_NL80211_VENDOR_ID,
8256 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
8257 },
8258 {
8259 /* Index = 5*/
8260 .vendor_id = QCA_NL80211_VENDOR_ID,
8261 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
8262 },
8263 {
8264 /* Index = 6*/
8265 .vendor_id = QCA_NL80211_VENDOR_ID,
8266 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
8267 },
8268#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308269#ifdef WLAN_FEATURE_EXTSCAN
8270 {
8271 .vendor_id = QCA_NL80211_VENDOR_ID,
8272 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
8273 },
8274 {
8275 .vendor_id = QCA_NL80211_VENDOR_ID,
8276 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
8277 },
8278 {
8279 .vendor_id = QCA_NL80211_VENDOR_ID,
8280 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
8281 },
8282 {
8283 .vendor_id = QCA_NL80211_VENDOR_ID,
8284 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
8285 },
8286 {
8287 .vendor_id = QCA_NL80211_VENDOR_ID,
8288 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
8289 },
8290 {
8291 .vendor_id = QCA_NL80211_VENDOR_ID,
8292 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
8293 },
8294 {
8295 .vendor_id = QCA_NL80211_VENDOR_ID,
8296 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
8297 },
8298 {
8299 .vendor_id = QCA_NL80211_VENDOR_ID,
8300 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
8301 },
8302 {
8303 .vendor_id = QCA_NL80211_VENDOR_ID,
8304 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
8305 },
8306 {
8307 .vendor_id = QCA_NL80211_VENDOR_ID,
8308 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
8309 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05308310 {
8311 .vendor_id = QCA_NL80211_VENDOR_ID,
8312 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST
8313 },
8314 {
8315 .vendor_id = QCA_NL80211_VENDOR_ID,
8316 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST
8317 },
8318 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND_INDEX] = {
8319 .vendor_id = QCA_NL80211_VENDOR_ID,
8320 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND
8321 },
8322 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST_INDEX] = {
8323 .vendor_id = QCA_NL80211_VENDOR_ID,
8324 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST
8325 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308326#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308327/*EXT TDLS*/
8328 {
8329 .vendor_id = QCA_NL80211_VENDOR_ID,
8330 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
8331 },
c_manjeecfd1efb2015-09-25 19:32:34 +05308332 [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
8333 .vendor_id = QCA_NL80211_VENDOR_ID,
8334 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
8335 },
8336
Srinivas Dasari030bad32015-02-18 23:23:54 +05308337
Srinivas Dasaribd1cf642017-01-23 14:54:41 +05308338 [QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX] = {
Srinivas Dasari030bad32015-02-18 23:23:54 +05308339 .vendor_id = QCA_NL80211_VENDOR_ID,
8340 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
8341 },
8342
Sushant Kaushik084f6592015-09-10 13:11:56 +05308343 {
8344 .vendor_id = QCA_NL80211_VENDOR_ID,
8345 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308346 },
8347 [QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = {
8348 .vendor_id = QCA_NL80211_VENDOR_ID,
8349 .subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI
8350 },
Padma, Santhosh Kumar7bbc7d92015-12-08 20:23:19 +05308351 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX] = {
8352 .vendor_id = QCA_NL80211_VENDOR_ID,
8353 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST
8354 },
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308355 [QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET_INDEX] = {
8356 .vendor_id = QCA_NL80211_VENDOR_ID,
8357 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8358 },
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008359};
8360
Jeff Johnson295189b2012-06-20 16:38:30 -07008361/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308362 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308363 * This function is called by hdd_wlan_startup()
8364 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308365 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07008366 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308367struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07008368{
8369 struct wiphy *wiphy;
8370 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308371 /*
8372 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07008373 */
8374 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
8375
8376 if (!wiphy)
8377 {
8378 /* Print error and jump into err label and free the memory */
8379 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
8380 return NULL;
8381 }
8382
Sunil Duttc69bccb2014-05-26 21:30:20 +05308383
Jeff Johnson295189b2012-06-20 16:38:30 -07008384 return wiphy;
8385}
8386
Anurag Chouhan343af7e2016-12-16 13:11:19 +05308387#if (LINUX_VERSION_CODE > KERNEL_VERSION(4,4,0)) || \
8388 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
8389/**
8390 * hdd_config_sched_scan_plans_to_wiphy() - configure sched scan plans to wiphy
8391 * @wiphy: pointer to wiphy
8392 * @config: pointer to config
8393 *
8394 * Return: None
8395 */
8396static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
8397 hdd_config_t *config)
8398{
8399 wiphy->max_sched_scan_plans = MAX_SCHED_SCAN_PLANS;
8400 if (config->max_sched_scan_plan_interval)
8401 wiphy->max_sched_scan_plan_interval =
8402 config->max_sched_scan_plan_interval;
8403 if (config->max_sched_scan_plan_iterations)
8404 wiphy->max_sched_scan_plan_iterations =
8405 config->max_sched_scan_plan_iterations;
8406}
8407#else
8408static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
8409 hdd_config_t *config)
8410{
8411}
8412#endif
8413
Jeff Johnson295189b2012-06-20 16:38:30 -07008414/*
8415 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308416 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07008417 * private ioctl to change the band value
8418 */
8419int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
8420{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308421 int i, j;
8422 eNVChannelEnabledType channelEnabledState;
8423
Jeff Johnsone7245742012-09-05 17:12:55 -07008424 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308425
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308426 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07008427 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308428
8429 if (NULL == wiphy->bands[i])
8430 {
8431 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
8432 __func__, i);
8433 continue;
8434 }
8435
8436 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
8437 {
8438 struct ieee80211_supported_band *band = wiphy->bands[i];
8439
8440 channelEnabledState = vos_nv_getChannelEnabledState(
8441 band->channels[j].hw_value);
8442
8443 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
8444 {
Abhishek Singh678227a2014-11-04 10:52:38 +05308445 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308446 continue;
8447 }
8448 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
8449 {
8450 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8451 continue;
8452 }
8453
8454 if (NV_CHANNEL_DISABLE == channelEnabledState ||
8455 NV_CHANNEL_INVALID == channelEnabledState)
8456 {
8457 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8458 }
8459 else if (NV_CHANNEL_DFS == channelEnabledState)
8460 {
8461 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
8462 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
8463 }
8464 else
8465 {
8466 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
8467 |IEEE80211_CHAN_RADAR);
8468 }
8469 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008470 }
8471 return 0;
8472}
8473/*
8474 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308475 * This function is called by hdd_wlan_startup()
8476 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07008477 * This function is used to initialize and register wiphy structure.
8478 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308479int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07008480 struct wiphy *wiphy,
8481 hdd_config_t *pCfg
8482 )
8483{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308484 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05308485 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
8486
Jeff Johnsone7245742012-09-05 17:12:55 -07008487 ENTER();
8488
Jeff Johnson295189b2012-06-20 16:38:30 -07008489 /* Now bind the underlying wlan device with wiphy */
8490 set_wiphy_dev(wiphy, dev);
8491
8492 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07008493
Kiet Lam6c583332013-10-14 05:37:09 +05308494#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07008495 /* the flag for the other case would be initialzed in
8496 vos_init_wiphy_from_nv_bin */
Manjeet Singh9e19de62016-08-18 18:26:41 +05308497#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
8498 wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
8499#else
Amar Singhal0a402232013-10-11 20:57:16 -07008500 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05308501#endif
Manjeet Singh9e19de62016-08-18 18:26:41 +05308502#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07008503
Amar Singhalfddc28c2013-09-05 13:03:40 -07008504 /* This will disable updating of NL channels from passive to
8505 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308506#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
8507 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
8508#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07008509 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308510#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07008511
Amar Singhala49cbc52013-10-08 18:37:44 -07008512
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008513#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07008514 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
8515 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
8516 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07008517 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308518#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Rajeev Kumar Sirasanagandla0d6dd752016-08-17 15:01:39 +05308519 wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308520#else
8521 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
8522#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008523#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07008524
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08008525#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07008526 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08008527#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07008528 || pCfg->isFastRoamIniFeatureEnabled
8529#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08008530#ifdef FEATURE_WLAN_ESE
8531 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07008532#endif
8533 )
8534 {
8535 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
8536 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08008537#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008538#ifdef FEATURE_WLAN_TDLS
8539 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
8540 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
8541#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308542#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05308543 if (pCfg->configPNOScanSupport)
8544 {
8545 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
8546 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
8547 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
8548 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
8549 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308550#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008551
Abhishek Singh10d85972015-04-17 10:27:23 +05308552#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
8553 wiphy->features |= NL80211_FEATURE_HT_IBSS;
8554#endif
8555
Amar Singhalfddc28c2013-09-05 13:03:40 -07008556#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07008557 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
8558 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07008559 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07008560 driver need to determine what to do with both
8561 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07008562
8563 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07008564#else
8565 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07008566#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008567
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308568 wiphy->max_scan_ssids = MAX_SCAN_SSID;
8569
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05308570 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07008571
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308572 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
8573
Jeff Johnson295189b2012-06-20 16:38:30 -07008574 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05308575 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
8576 | BIT(NL80211_IFTYPE_ADHOC)
8577 | BIT(NL80211_IFTYPE_P2P_CLIENT)
8578 | BIT(NL80211_IFTYPE_P2P_GO)
8579 | BIT(NL80211_IFTYPE_AP);
8580
8581 if (VOS_MONITOR_MODE == hdd_get_conparam())
8582 {
8583 wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
8584 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008585
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308586 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008587 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308588#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
8589 if( pCfg->enableMCC )
8590 {
8591 /* Currently, supports up to two channels */
8592 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008593
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308594 if( !pCfg->allowMCCGODiffBI )
8595 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008596
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308597 }
8598 wiphy->iface_combinations = &wlan_hdd_iface_combination;
8599 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008600#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308601 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008602
Jeff Johnson295189b2012-06-20 16:38:30 -07008603 /* Before registering we need to update the ht capabilitied based
8604 * on ini values*/
8605 if( !pCfg->ShortGI20MhzEnable )
8606 {
8607 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
8608 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
Jeff Johnson295189b2012-06-20 16:38:30 -07008609 }
8610
8611 if( !pCfg->ShortGI40MhzEnable )
8612 {
8613 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
8614 }
8615
8616 if( !pCfg->nChannelBondingMode5GHz )
8617 {
8618 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
8619 }
Agrawal Ashish97dec502015-11-26 20:20:58 +05308620 /*
8621 * In case of static linked driver at the time of driver unload,
8622 * module exit doesn't happens. Module cleanup helps in cleaning
8623 * of static memory.
8624 * If driver load happens statically, at the time of driver unload,
8625 * wiphy flags don't get reset because of static memory.
8626 * It's better not to store channel in static memory.
8627 */
8628 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
8629 wiphy->bands[IEEE80211_BAND_2GHZ]->channels =
8630 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_2_4_GHZ));
8631 if (wiphy->bands[IEEE80211_BAND_2GHZ]->channels == NULL)
8632 {
8633 hddLog(VOS_TRACE_LEVEL_ERROR,
8634 FL("Not enough memory to allocate channels"));
8635 return -ENOMEM;
8636 }
8637 vos_mem_copy(wiphy->bands[IEEE80211_BAND_2GHZ]->channels,
8638 &hdd_channels_2_4_GHZ[0],
8639 sizeof(hdd_channels_2_4_GHZ));
Jeff Johnson295189b2012-06-20 16:38:30 -07008640
Agrawal Ashish97dec502015-11-26 20:20:58 +05308641 if (true == hdd_is_5g_supported(pHddCtx))
8642 {
8643 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
8644 wiphy->bands[IEEE80211_BAND_5GHZ]->channels =
8645 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_5_GHZ));
8646 if (wiphy->bands[IEEE80211_BAND_5GHZ]->channels == NULL)
8647 {
8648 hddLog(VOS_TRACE_LEVEL_ERROR,
8649 FL("Not enough memory to allocate channels"));
8650 vos_mem_free(wiphy->bands[IEEE80211_BAND_2GHZ]->channels);
8651 wiphy->bands[IEEE80211_BAND_2GHZ]->channels = NULL;
8652 return -ENOMEM;
8653 }
8654 vos_mem_copy(wiphy->bands[IEEE80211_BAND_5GHZ]->channels,
8655 &hdd_channels_5_GHZ[0],
8656 sizeof(hdd_channels_5_GHZ));
8657 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308658
8659 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
8660 {
8661
8662 if (NULL == wiphy->bands[i])
8663 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05308664 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308665 __func__, i);
8666 continue;
8667 }
8668
8669 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
8670 {
8671 struct ieee80211_supported_band *band = wiphy->bands[i];
8672
8673 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
8674 {
8675 // Enable social channels for P2P
8676 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
8677 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
8678 else
8679 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8680 continue;
8681 }
8682 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
8683 {
8684 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8685 continue;
8686 }
8687 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008688 }
8689 /*Initialise the supported cipher suite details*/
8690 wiphy->cipher_suites = hdd_cipher_suites;
8691 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
8692
8693 /*signal strength in mBm (100*dBm) */
8694 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
8695
8696#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05308697 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07008698#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008699
Sunil Duttc69bccb2014-05-26 21:30:20 +05308700 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
8701 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008702 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
8703 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
8704
Anurag Chouhan343af7e2016-12-16 13:11:19 +05308705 hdd_config_sched_scan_plans_to_wiphy(wiphy, pCfg);
8706
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308707 EXIT();
8708 return 0;
8709}
8710
8711/* In this function we are registering wiphy. */
8712int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
8713{
8714 ENTER();
8715 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008716 if (0 > wiphy_register(wiphy))
8717 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308718 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07008719 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8720 return -EIO;
8721 }
8722
8723 EXIT();
8724 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308725}
Jeff Johnson295189b2012-06-20 16:38:30 -07008726
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308727/* In this function we are updating channel list when,
8728 regulatory domain is FCC and country code is US.
8729 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
8730 As per FCC smart phone is not a indoor device.
8731 GO should not opeate on indoor channels */
8732void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
8733{
8734 int j;
8735 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
8736 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
8737 //Default counrtycode from NV at the time of wiphy initialization.
8738 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
8739 &defaultCountryCode[0]))
8740 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008741 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308742 }
8743 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
8744 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308745 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
8746 {
8747 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
8748 return;
8749 }
8750 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
8751 {
8752 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
8753 // Mark UNII -1 band channel as passive
8754 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
8755 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
8756 }
8757 }
8758}
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05308759/* This function registers for all frame which supplicant is interested in */
8760void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008761{
Jeff Johnson295189b2012-06-20 16:38:30 -07008762 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8763 /* Register for all P2P action, public action etc frames */
8764 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
Jeff Johnsone7245742012-09-05 17:12:55 -07008765 ENTER();
Abhishek Singh16e05762015-11-30 14:29:27 +05308766 /* Register frame indication call back */
8767 sme_register_mgmt_frame_ind_callback(hHal, hdd_indicate_mgmt_frame);
Jeff Johnson295189b2012-06-20 16:38:30 -07008768 /* Right now we are registering these frame when driver is getting
8769 initialized. Once we will move to 2.6.37 kernel, in which we have
8770 frame register ops, we will move this code as a part of that */
8771 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308772 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07008773 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
8774
8775 /* GAS Initial Response */
8776 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8777 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308778
Jeff Johnson295189b2012-06-20 16:38:30 -07008779 /* GAS Comeback Request */
8780 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8781 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
8782
8783 /* GAS Comeback Response */
8784 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8785 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
8786
8787 /* P2P Public Action */
8788 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308789 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07008790 P2P_PUBLIC_ACTION_FRAME_SIZE );
8791
8792 /* P2P Action */
8793 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8794 (v_U8_t*)P2P_ACTION_FRAME,
8795 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07008796
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05308797 /* WNM BSS Transition Request frame */
8798 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8799 (v_U8_t*)WNM_BSS_ACTION_FRAME,
8800 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07008801
8802 /* WNM-Notification */
8803 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8804 (v_U8_t*)WNM_NOTIFICATION_FRAME,
8805 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008806}
8807
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05308808void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008809{
Jeff Johnson295189b2012-06-20 16:38:30 -07008810 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8811 /* Register for all P2P action, public action etc frames */
8812 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
8813
Jeff Johnsone7245742012-09-05 17:12:55 -07008814 ENTER();
8815
Jeff Johnson295189b2012-06-20 16:38:30 -07008816 /* Right now we are registering these frame when driver is getting
8817 initialized. Once we will move to 2.6.37 kernel, in which we have
8818 frame register ops, we will move this code as a part of that */
8819 /* GAS Initial Request */
8820
8821 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8822 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
8823
8824 /* GAS Initial Response */
8825 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8826 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308827
Jeff Johnson295189b2012-06-20 16:38:30 -07008828 /* GAS Comeback Request */
8829 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8830 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
8831
8832 /* GAS Comeback Response */
8833 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8834 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
8835
8836 /* P2P Public Action */
8837 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308838 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07008839 P2P_PUBLIC_ACTION_FRAME_SIZE );
8840
8841 /* P2P Action */
8842 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8843 (v_U8_t*)P2P_ACTION_FRAME,
8844 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07008845 /* WNM-Notification */
8846 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8847 (v_U8_t*)WNM_NOTIFICATION_FRAME,
8848 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008849}
8850
8851#ifdef FEATURE_WLAN_WAPI
8852void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05308853 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07008854{
8855 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8856 tCsrRoamSetKey setKey;
8857 v_BOOL_t isConnected = TRUE;
8858 int status = 0;
8859 v_U32_t roamId= 0xFF;
8860 tANI_U8 *pKeyPtr = NULL;
8861 int n = 0;
8862
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308863 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
8864 __func__, hdd_device_modetoString(pAdapter->device_mode),
8865 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008866
Gopichand Nakkalae7480202013-02-11 15:24:22 +05308867 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07008868 setKey.keyId = key_index; // Store Key ID
8869 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
8870 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
8871 setKey.paeRole = 0 ; // the PAE role
8872 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
8873 {
8874 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
8875 }
8876 else
8877 {
8878 isConnected = hdd_connIsConnected(pHddStaCtx);
8879 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
8880 }
8881 setKey.keyLength = key_Len;
8882 pKeyPtr = setKey.Key;
8883 memcpy( pKeyPtr, key, key_Len);
8884
Arif Hussain6d2a3322013-11-17 19:50:10 -08008885 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07008886 __func__, key_Len);
8887 for (n = 0 ; n < key_Len; n++)
8888 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
8889 __func__,n,setKey.Key[n]);
8890
8891 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8892 if ( isConnected )
8893 {
8894 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8895 pAdapter->sessionId, &setKey, &roamId );
8896 }
8897 if ( status != 0 )
8898 {
8899 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8900 "[%4d] sme_RoamSetKey returned ERROR status= %d",
8901 __LINE__, status );
8902 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8903 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308904 /* Need to clear any trace of key value in the memory.
8905 * Thus zero out the memory even though it is local
8906 * variable.
8907 */
8908 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07008909}
8910#endif /* FEATURE_WLAN_WAPI*/
8911
8912#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308913int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07008914 beacon_data_t **ppBeacon,
8915 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008916#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308917int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008918 beacon_data_t **ppBeacon,
8919 struct cfg80211_beacon_data *params,
8920 int dtim_period)
8921#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308922{
Jeff Johnson295189b2012-06-20 16:38:30 -07008923 int size;
8924 beacon_data_t *beacon = NULL;
8925 beacon_data_t *old = NULL;
Kapil Gupta137ef892016-12-13 19:38:00 +05308926 int head_len, tail_len, proberesp_ies_len, assocresp_ies_len;
8927 const u8 *head, *tail, *proberesp_ies, *assocresp_ies;
Jeff Johnson295189b2012-06-20 16:38:30 -07008928
Jeff Johnsone7245742012-09-05 17:12:55 -07008929 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008930 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308931 {
8932 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8933 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008934 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308935 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008936
8937 old = pAdapter->sessionCtx.ap.beacon;
8938
8939 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308940 {
8941 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8942 FL("session(%d) old and new heads points to NULL"),
8943 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008944 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308945 }
8946
8947 if (params->tail && !params->tail_len)
8948 {
8949 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8950 FL("tail_len is zero but tail is not NULL"));
8951 return -EINVAL;
8952 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008953
Jeff Johnson295189b2012-06-20 16:38:30 -07008954#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
8955 /* Kernel 3.0 is not updating dtim_period for set beacon */
8956 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308957 {
8958 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8959 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008960 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308961 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008962#endif
8963
Kapil Gupta137ef892016-12-13 19:38:00 +05308964 if (params->head)
8965 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008966 head_len = params->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05308967 head = params->head;
8968 } else
8969 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008970 head_len = old->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05308971 head = old->head;
8972 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008973
Kapil Gupta137ef892016-12-13 19:38:00 +05308974 if (params->tail || !old)
8975 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008976 tail_len = params->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05308977 tail = params->tail;
8978 } else
8979 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008980 tail_len = old->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05308981 tail = old->tail;
8982 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008983
Kapil Gupta137ef892016-12-13 19:38:00 +05308984 if (params->proberesp_ies || !old)
8985 {
8986 proberesp_ies_len = params->proberesp_ies_len;
8987 proberesp_ies = params->proberesp_ies;
8988 } else
8989 {
8990 proberesp_ies_len = old->proberesp_ies_len;
8991 proberesp_ies = old->proberesp_ies;
8992 }
8993
8994 if (params->assocresp_ies || !old)
8995 {
8996 assocresp_ies_len = params->assocresp_ies_len;
8997 assocresp_ies = params->assocresp_ies;
8998 } else
8999 {
9000 assocresp_ies_len = old->assocresp_ies_len;
9001 assocresp_ies = old->assocresp_ies;
9002 }
9003
9004 size = sizeof(beacon_data_t) + head_len + tail_len +
9005 proberesp_ies_len + assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009006
9007 beacon = kzalloc(size, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009008 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309009 {
9010 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9011 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009012 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309013 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009014
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009015#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Kapil Gupta137ef892016-12-13 19:38:00 +05309016 if (params->dtim_period)
Jeff Johnson295189b2012-06-20 16:38:30 -07009017 beacon->dtim_period = params->dtim_period;
9018 else
9019 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009020#else
Kapil Gupta137ef892016-12-13 19:38:00 +05309021 if (dtim_period)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009022 beacon->dtim_period = dtim_period;
9023 else
9024 beacon->dtim_period = old->dtim_period;
9025#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309026
Jeff Johnson295189b2012-06-20 16:38:30 -07009027 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
9028 beacon->tail = beacon->head + head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309029 beacon->proberesp_ies = beacon->tail + tail_len;
9030 beacon->assocresp_ies = beacon->proberesp_ies + proberesp_ies_len;
9031
Jeff Johnson295189b2012-06-20 16:38:30 -07009032 beacon->head_len = head_len;
9033 beacon->tail_len = tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309034 beacon->proberesp_ies_len = proberesp_ies_len;
9035 beacon->assocresp_ies_len= assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009036
c_manjee527ecac2017-01-25 12:25:27 +05309037 if (head && head_len)
9038 memcpy(beacon->head, head, head_len);
9039 if (tail && tail_len)
9040 memcpy(beacon->tail, tail, tail_len);
9041 if (proberesp_ies && proberesp_ies_len)
9042 memcpy(beacon->proberesp_ies, proberesp_ies, proberesp_ies_len);
9043 if (assocresp_ies && assocresp_ies_len)
9044 memcpy(beacon->assocresp_ies, assocresp_ies, assocresp_ies_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009045
9046 *ppBeacon = beacon;
9047
9048 kfree(old);
9049
9050 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009051}
Jeff Johnson295189b2012-06-20 16:38:30 -07009052
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309053v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
9054#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
9055 const v_U8_t *pIes,
9056#else
9057 v_U8_t *pIes,
9058#endif
9059 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009060{
9061 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309062 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07009063 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309064
Jeff Johnson295189b2012-06-20 16:38:30 -07009065 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309066 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009067 elem_id = ptr[0];
9068 elem_len = ptr[1];
9069 left -= 2;
9070 if(elem_len > left)
9071 {
9072 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07009073 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009074 eid,elem_len,left);
9075 return NULL;
9076 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309077 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009078 {
9079 return ptr;
9080 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309081
Jeff Johnson295189b2012-06-20 16:38:30 -07009082 left -= elem_len;
9083 ptr += (elem_len + 2);
9084 }
9085 return NULL;
9086}
9087
Jeff Johnson295189b2012-06-20 16:38:30 -07009088/* Check if rate is 11g rate or not */
9089static int wlan_hdd_rate_is_11g(u8 rate)
9090{
Sanjay Devnani28322e22013-06-21 16:13:40 -07009091 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009092 u8 i;
9093 for (i = 0; i < 8; i++)
9094 {
9095 if(rate == gRateArray[i])
9096 return TRUE;
9097 }
9098 return FALSE;
9099}
9100
9101/* Check for 11g rate and set proper 11g only mode */
9102static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
9103 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
9104{
9105 u8 i, num_rates = pIe[0];
9106
9107 pIe += 1;
9108 for ( i = 0; i < num_rates; i++)
9109 {
9110 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
9111 {
9112 /* If rate set have 11g rate than change the mode to 11G */
9113 *pSapHw_mode = eSAP_DOT11_MODE_11g;
9114 if (pIe[i] & BASIC_RATE_MASK)
9115 {
9116 /* If we have 11g rate as basic rate, it means mode
9117 is 11g only mode.
9118 */
9119 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
9120 *pCheckRatesfor11g = FALSE;
9121 }
9122 }
9123 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
9124 {
9125 *require_ht = TRUE;
9126 }
9127 }
9128 return;
9129}
9130
9131static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
9132{
9133 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9134 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9135 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9136 u8 checkRatesfor11g = TRUE;
9137 u8 require_ht = FALSE;
9138 u8 *pIe=NULL;
9139
9140 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
9141
9142 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
9143 pBeacon->head_len, WLAN_EID_SUPP_RATES);
9144 if (pIe != NULL)
9145 {
9146 pIe += 1;
9147 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9148 &pConfig->SapHw_mode);
9149 }
9150
9151 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9152 WLAN_EID_EXT_SUPP_RATES);
9153 if (pIe != NULL)
9154 {
9155
9156 pIe += 1;
9157 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9158 &pConfig->SapHw_mode);
9159 }
9160
9161 if( pConfig->channel > 14 )
9162 {
9163 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
9164 }
9165
9166 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9167 WLAN_EID_HT_CAPABILITY);
9168
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309169 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009170 {
9171 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
9172 if(require_ht)
9173 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
9174 }
9175}
9176
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309177static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
9178 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
9179{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009180 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309181 v_U8_t *pIe = NULL;
9182 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9183
9184 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
9185 pBeacon->tail, pBeacon->tail_len);
9186
9187 if (pIe)
9188 {
9189 ielen = pIe[1] + 2;
9190 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9191 {
9192 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
9193 }
9194 else
9195 {
9196 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
9197 return -EINVAL;
9198 }
9199 *total_ielen += ielen;
9200 }
9201 return 0;
9202}
9203
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009204static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
9205 v_U8_t *genie, v_U8_t *total_ielen)
9206{
9207 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9208 int left = pBeacon->tail_len;
9209 v_U8_t *ptr = pBeacon->tail;
9210 v_U8_t elem_id, elem_len;
9211 v_U16_t ielen = 0;
9212
9213 if ( NULL == ptr || 0 == left )
9214 return;
9215
9216 while (left >= 2)
9217 {
9218 elem_id = ptr[0];
9219 elem_len = ptr[1];
9220 left -= 2;
9221 if (elem_len > left)
9222 {
9223 hddLog( VOS_TRACE_LEVEL_ERROR,
9224 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
9225 elem_id, elem_len, left);
9226 return;
9227 }
9228 if (IE_EID_VENDOR == elem_id)
9229 {
9230 /* skipping the VSIE's which we don't want to include or
9231 * it will be included by existing code
9232 */
9233 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
9234#ifdef WLAN_FEATURE_WFD
9235 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
9236#endif
9237 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9238 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9239 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
9240 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9241 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
9242 {
9243 ielen = ptr[1] + 2;
9244 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9245 {
9246 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
9247 *total_ielen += ielen;
9248 }
9249 else
9250 {
9251 hddLog( VOS_TRACE_LEVEL_ERROR,
9252 "IE Length is too big "
9253 "IEs eid=%d elem_len=%d total_ie_lent=%d",
9254 elem_id, elem_len, *total_ielen);
9255 }
9256 }
9257 }
9258
9259 left -= elem_len;
9260 ptr += (elem_len + 2);
9261 }
9262 return;
9263}
9264
Kapil Gupta137ef892016-12-13 19:38:00 +05309265int wlan_hdd_cfg80211_update_apies(hdd_adapter_t *pHostapdAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009266{
9267 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309268 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009269 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07009270 int ret = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +05309271 beacon_data_t *pBeacon = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009272
9273 genie = vos_mem_malloc(MAX_GENIE_LEN);
9274
9275 if(genie == NULL) {
9276
9277 return -ENOMEM;
9278 }
9279
Kapil Gupta137ef892016-12-13 19:38:00 +05309280 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309281 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9282 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009283 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309284 hddLog(LOGE,
9285 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309286 ret = -EINVAL;
9287 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009288 }
9289
9290#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309291 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9292 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
9293 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309294 hddLog(LOGE,
9295 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309296 ret = -EINVAL;
9297 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009298 }
9299#endif
9300
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309301 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9302 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009303 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309304 hddLog(LOGE,
9305 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309306 ret = -EINVAL;
9307 goto done;
9308 }
9309
9310 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
9311 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009312 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07009313 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009314
9315 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9316 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
9317 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
9318 {
9319 hddLog(LOGE,
9320 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009321 ret = -EINVAL;
9322 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009323 }
9324
9325 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9326 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
9327 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9328 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9329 ==eHAL_STATUS_FAILURE)
9330 {
9331 hddLog(LOGE,
9332 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009333 ret = -EINVAL;
9334 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009335 }
9336
9337 // Added for ProResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +05309338 if ((pBeacon->proberesp_ies != NULL) && (pBeacon->proberesp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009339 {
Kapil Gupta137ef892016-12-13 19:38:00 +05309340 u16 rem_probe_resp_ie_len = pBeacon->proberesp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009341 u8 probe_rsp_ie_len[3] = {0};
9342 u8 counter = 0;
9343 /* Check Probe Resp Length if it is greater then 255 then Store
9344 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
9345 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
9346 Store More then 255 bytes into One Variable.
9347 */
9348 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
9349 {
9350 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
9351 {
9352 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
9353 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
9354 }
9355 else
9356 {
9357 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
9358 rem_probe_resp_ie_len = 0;
9359 }
9360 }
9361
9362 rem_probe_resp_ie_len = 0;
9363
9364 if (probe_rsp_ie_len[0] > 0)
9365 {
9366 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9367 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
Kapil Gupta137ef892016-12-13 19:38:00 +05309368 (tANI_U8*)&pBeacon->
9369 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07009370 probe_rsp_ie_len[0], NULL,
9371 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9372 {
9373 hddLog(LOGE,
9374 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009375 ret = -EINVAL;
9376 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009377 }
9378 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
9379 }
9380
9381 if (probe_rsp_ie_len[1] > 0)
9382 {
9383 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9384 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
Kapil Gupta137ef892016-12-13 19:38:00 +05309385 (tANI_U8*)&pBeacon->
9386 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07009387 probe_rsp_ie_len[1], NULL,
9388 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9389 {
9390 hddLog(LOGE,
9391 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009392 ret = -EINVAL;
9393 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009394 }
9395 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
9396 }
9397
9398 if (probe_rsp_ie_len[2] > 0)
9399 {
9400 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9401 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
Kapil Gupta137ef892016-12-13 19:38:00 +05309402 (tANI_U8*)&pBeacon->
9403 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07009404 probe_rsp_ie_len[2], NULL,
9405 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9406 {
9407 hddLog(LOGE,
9408 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009409 ret = -EINVAL;
9410 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009411 }
9412 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
9413 }
9414
9415 if (probe_rsp_ie_len[1] == 0 )
9416 {
9417 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9418 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
9419 eANI_BOOLEAN_FALSE) )
9420 {
9421 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009422 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009423 }
9424 }
9425
9426 if (probe_rsp_ie_len[2] == 0 )
9427 {
9428 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9429 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
9430 eANI_BOOLEAN_FALSE) )
9431 {
9432 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009433 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009434 }
9435 }
9436
9437 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9438 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
9439 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9440 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9441 == eHAL_STATUS_FAILURE)
9442 {
9443 hddLog(LOGE,
9444 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009445 ret = -EINVAL;
9446 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009447 }
9448 }
9449 else
9450 {
9451 // Reset WNI_CFG_PROBE_RSP Flags
9452 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
9453
9454 hddLog(VOS_TRACE_LEVEL_INFO,
9455 "%s: No Probe Response IE received in set beacon",
9456 __func__);
9457 }
9458
9459 // Added for AssocResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +05309460 if ((pBeacon->assocresp_ies != NULL) && (pBeacon->assocresp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009461 {
9462 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
Kapil Gupta137ef892016-12-13 19:38:00 +05309463 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)pBeacon->assocresp_ies,
9464 pBeacon->assocresp_ies_len, NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -07009465 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9466 {
9467 hddLog(LOGE,
9468 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009469 ret = -EINVAL;
9470 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009471 }
9472
9473 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9474 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
9475 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9476 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9477 == eHAL_STATUS_FAILURE)
9478 {
9479 hddLog(LOGE,
9480 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009481 ret = -EINVAL;
9482 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009483 }
9484 }
9485 else
9486 {
9487 hddLog(VOS_TRACE_LEVEL_INFO,
9488 "%s: No Assoc Response IE received in set beacon",
9489 __func__);
9490
9491 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9492 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
9493 eANI_BOOLEAN_FALSE) )
9494 {
9495 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009496 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009497 }
9498 }
9499
Jeff Johnsone7245742012-09-05 17:12:55 -07009500done:
Jeff Johnson295189b2012-06-20 16:38:30 -07009501 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309502 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009503}
Jeff Johnson295189b2012-06-20 16:38:30 -07009504
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309505/*
Jeff Johnson295189b2012-06-20 16:38:30 -07009506 * FUNCTION: wlan_hdd_validate_operation_channel
9507 * called by wlan_hdd_cfg80211_start_bss() and
9508 * wlan_hdd_cfg80211_set_channel()
9509 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309510 * channel list.
9511 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07009512VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07009513{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309514
Jeff Johnson295189b2012-06-20 16:38:30 -07009515 v_U32_t num_ch = 0;
9516 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
9517 u32 indx = 0;
9518 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309519 v_U8_t fValidChannel = FALSE, count = 0;
9520 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309521
Jeff Johnson295189b2012-06-20 16:38:30 -07009522 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
9523
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309524 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07009525 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309526 /* Validate the channel */
9527 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07009528 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309529 if ( channel == rfChannels[count].channelNum )
9530 {
9531 fValidChannel = TRUE;
9532 break;
9533 }
9534 }
9535 if (fValidChannel != TRUE)
9536 {
9537 hddLog(VOS_TRACE_LEVEL_ERROR,
9538 "%s: Invalid Channel [%d]", __func__, channel);
9539 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009540 }
9541 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309542 else
Jeff Johnson295189b2012-06-20 16:38:30 -07009543 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309544 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
9545 valid_ch, &num_ch))
9546 {
9547 hddLog(VOS_TRACE_LEVEL_ERROR,
9548 "%s: failed to get valid channel list", __func__);
9549 return VOS_STATUS_E_FAILURE;
9550 }
9551 for (indx = 0; indx < num_ch; indx++)
9552 {
9553 if (channel == valid_ch[indx])
9554 {
9555 break;
9556 }
9557 }
9558
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05309559 if (indx >= num_ch)
9560 {
9561 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
9562 {
9563 eCsrBand band;
9564 unsigned int freq;
9565
9566 sme_GetFreqBand(hHal, &band);
9567
9568 if (eCSR_BAND_5G == band)
9569 {
9570#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
9571 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
9572 {
9573 freq = ieee80211_channel_to_frequency(channel,
9574 IEEE80211_BAND_2GHZ);
9575 }
9576 else
9577 {
9578 freq = ieee80211_channel_to_frequency(channel,
9579 IEEE80211_BAND_5GHZ);
9580 }
9581#else
9582 freq = ieee80211_channel_to_frequency(channel);
9583#endif
9584 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
9585 return VOS_STATUS_SUCCESS;
9586 }
9587 }
9588
9589 hddLog(VOS_TRACE_LEVEL_ERROR,
9590 "%s: Invalid Channel [%d]", __func__, channel);
9591 return VOS_STATUS_E_FAILURE;
9592 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009593 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05309594
Jeff Johnson295189b2012-06-20 16:38:30 -07009595 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309596
Jeff Johnson295189b2012-06-20 16:38:30 -07009597}
9598
Viral Modi3a32cc52013-02-08 11:14:52 -08009599/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309600 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08009601 * This function is used to set the channel number
9602 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309603static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08009604 struct ieee80211_channel *chan,
9605 enum nl80211_channel_type channel_type
9606 )
9607{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309608 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08009609 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07009610 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08009611 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309612 hdd_context_t *pHddCtx;
9613 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009614
9615 ENTER();
9616
9617 if( NULL == dev )
9618 {
9619 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009620 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08009621 return -ENODEV;
9622 }
9623 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309624
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309625 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9626 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
9627 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08009628 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309629 "%s: device_mode = %s (%d) freq = %d", __func__,
9630 hdd_device_modetoString(pAdapter->device_mode),
9631 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309632
9633 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9634 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309635 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08009636 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309637 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009638 }
9639
9640 /*
9641 * Do freq to chan conversion
9642 * TODO: for 11a
9643 */
9644
9645 channel = ieee80211_frequency_to_channel(freq);
9646
9647 /* Check freq range */
9648 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
9649 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
9650 {
9651 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009652 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08009653 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
9654 WNI_CFG_CURRENT_CHANNEL_STAMAX);
9655 return -EINVAL;
9656 }
9657
9658 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
9659
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05309660 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
9661 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08009662 {
9663 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
9664 {
9665 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009666 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08009667 return -EINVAL;
9668 }
9669 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
9670 "%s: set channel to [%d] for device mode =%d",
9671 __func__, channel,pAdapter->device_mode);
9672 }
9673 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08009674 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08009675 )
9676 {
9677 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9678 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
9679 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9680
9681 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
9682 {
9683 /* Link is up then return cant set channel*/
9684 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009685 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08009686 return -EINVAL;
9687 }
9688
9689 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
9690 pHddStaCtx->conn_info.operationChannel = channel;
9691 pRoamProfile->ChannelInfo.ChannelList =
9692 &pHddStaCtx->conn_info.operationChannel;
9693 }
9694 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08009695 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08009696 )
9697 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309698 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
9699 {
9700 if(VOS_STATUS_SUCCESS !=
9701 wlan_hdd_validate_operation_channel(pAdapter,channel))
9702 {
9703 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009704 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309705 return -EINVAL;
9706 }
9707 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
9708 }
9709 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08009710 {
9711 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
9712
9713 /* If auto channel selection is configured as enable/ 1 then ignore
9714 channel set by supplicant
9715 */
9716 if ( cfg_param->apAutoChannelSelection )
9717 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309718 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
9719 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08009720 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309721 "%s: set channel to auto channel (0) for device mode =%s (%d)",
9722 __func__, hdd_device_modetoString(pAdapter->device_mode),
9723 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08009724 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309725 else
9726 {
9727 if(VOS_STATUS_SUCCESS !=
9728 wlan_hdd_validate_operation_channel(pAdapter,channel))
9729 {
9730 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009731 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309732 return -EINVAL;
9733 }
9734 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
9735 }
Viral Modi3a32cc52013-02-08 11:14:52 -08009736 }
9737 }
9738 else
9739 {
9740 hddLog(VOS_TRACE_LEVEL_FATAL,
9741 "%s: Invalid device mode failed to set valid channel", __func__);
9742 return -EINVAL;
9743 }
9744 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309745 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009746}
9747
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309748static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
9749 struct net_device *dev,
9750 struct ieee80211_channel *chan,
9751 enum nl80211_channel_type channel_type
9752 )
9753{
9754 int ret;
9755
9756 vos_ssr_protect(__func__);
9757 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
9758 vos_ssr_unprotect(__func__);
9759
9760 return ret;
9761}
9762
Anurag Chouhan83026002016-12-13 22:46:21 +05309763#ifdef DHCP_SERVER_OFFLOAD
9764void hdd_dhcp_server_offload_done(void *fw_dhcp_srv_offload_cb_context,
9765 VOS_STATUS status)
9766{
9767 hdd_adapter_t* adapter = (hdd_adapter_t*)fw_dhcp_srv_offload_cb_context;
9768
9769 ENTER();
9770
9771 if (NULL == adapter)
9772 {
9773 hddLog(VOS_TRACE_LEVEL_ERROR,
9774 "%s: adapter is NULL",__func__);
9775 return;
9776 }
9777
9778 adapter->dhcp_status.dhcp_offload_status = status;
9779 vos_event_set(&adapter->dhcp_status.vos_event);
9780 return;
9781}
9782
9783/**
9784 * wlan_hdd_set_dhcp_server_offload() - set dhcp server offload
9785 * @hostapd_adapter: pointer to hostapd adapter.
Anurag Chouhan638f5e22017-03-06 12:28:43 +05309786 * @re_init: flag set if api called post ssr
Anurag Chouhan83026002016-12-13 22:46:21 +05309787 *
9788 * Return: None
9789 */
Anurag Chouhan638f5e22017-03-06 12:28:43 +05309790VOS_STATUS wlan_hdd_set_dhcp_server_offload(hdd_adapter_t *hostapd_adapter,
9791 bool re_init)
Anurag Chouhan83026002016-12-13 22:46:21 +05309792{
9793 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter);
9794 sir_dhcp_srv_offload_info dhcp_srv_info;
9795 tANI_U8 num_entries = 0;
9796 tANI_U8 srv_ip[IPADDR_NUM_ENTRIES];
9797 tANI_U8 num;
9798 tANI_U32 temp;
9799 VOS_STATUS ret;
9800
9801 ENTER();
9802
Anurag Chouhan638f5e22017-03-06 12:28:43 +05309803 if (!re_init) {
9804 ret = wlan_hdd_validate_context(hdd_ctx);
9805 if (0 != ret)
9806 return VOS_STATUS_E_INVAL;
9807 }
Anurag Chouhan83026002016-12-13 22:46:21 +05309808
9809 /* Prepare the request to send to SME */
9810 dhcp_srv_info = vos_mem_malloc(sizeof(*dhcp_srv_info));
9811 if (NULL == dhcp_srv_info) {
9812 hddLog(VOS_TRACE_LEVEL_ERROR,
9813 "%s: could not allocate tDhcpSrvOffloadInfo!", __func__);
9814 return VOS_STATUS_E_NOMEM;
9815 }
9816
9817 vos_mem_zero(dhcp_srv_info, sizeof(*dhcp_srv_info));
9818
9819 dhcp_srv_info->bssidx = hostapd_adapter->sessionId;
9820 dhcp_srv_info->dhcp_srv_offload_enabled = TRUE;
9821 dhcp_srv_info->dhcp_client_num = hdd_ctx->cfg_ini->dhcp_max_num_clients;
9822 dhcp_srv_info->start_lsb = hdd_ctx->cfg_ini->dhcp_start_lsb;
9823 dhcp_srv_info->dhcp_offload_callback = hdd_dhcp_server_offload_done;
9824 dhcp_srv_info->dhcp_server_offload_cb_context = hostapd_adapter;
9825
9826 hdd_string_to_u8_array(hdd_ctx->cfg_ini->dhcp_srv_ip,
9827 srv_ip,
9828 &num_entries,
Anurag Chouhanac145c22016-11-22 16:51:47 +05309829 IPADDR_NUM_ENTRIES, ".");
Anurag Chouhan83026002016-12-13 22:46:21 +05309830 if (num_entries != IPADDR_NUM_ENTRIES) {
9831 hddLog(VOS_TRACE_LEVEL_ERROR,
9832 "%s: incorrect IP address (%s) assigned for DHCP server!",
9833 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
9834 vos_mem_free(dhcp_srv_info);
9835 return VOS_STATUS_E_FAILURE;
9836 }
9837
9838 if ((srv_ip[0] >= 224) && (srv_ip[0] <= 239)) {
9839 hddLog(VOS_TRACE_LEVEL_ERROR,
9840 "%s: invalid IP address (%s)! It could NOT be multicast IP address!",
9841 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
9842 vos_mem_free(dhcp_srv_info);
9843 return VOS_STATUS_E_FAILURE;
9844 }
9845
9846 if (srv_ip[IPADDR_NUM_ENTRIES-1] >= DHCP_START_POOL_ADDRESS) {
9847 hddLog(VOS_TRACE_LEVEL_ERROR,
9848 "%s: invalid IP address (%s)! The last field must be less than 100!",
9849 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
9850 vos_mem_free(dhcp_srv_info);
9851 return VOS_STATUS_E_FAILURE;
9852 }
9853
9854 for (num = 0; num < num_entries; num++) {
9855 temp = srv_ip[num];
9856 dhcp_srv_info->dhcp_srv_ip |= (temp << (8 * num));
9857 }
9858
9859 if (eHAL_STATUS_SUCCESS !=
9860 sme_set_dhcp_srv_offload(hdd_ctx->hHal, dhcp_srv_info)) {
9861 hddLog(VOS_TRACE_LEVEL_ERROR,
9862 "%s: sme_set_dhcp_srv_offload fail!", __func__);
9863 vos_mem_free(dhcp_srv_info);
9864 return VOS_STATUS_E_FAILURE;
9865 }
9866
9867 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
9868 "%s: enable DHCP Server offload successfully!", __func__);
9869
9870 vos_mem_free(dhcp_srv_info);
9871 return 0;
9872}
9873#endif /* DHCP_SERVER_OFFLOAD */
9874
Jeff Johnson295189b2012-06-20 16:38:30 -07009875#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9876static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
9877 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009878#else
9879static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
9880 struct cfg80211_beacon_data *params,
9881 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309882 enum nl80211_hidden_ssid hidden_ssid,
9883 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009884#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009885{
9886 tsap_Config_t *pConfig;
9887 beacon_data_t *pBeacon = NULL;
9888 struct ieee80211_mgmt *pMgmt_frame;
9889 v_U8_t *pIe=NULL;
9890 v_U16_t capab_info;
9891 eCsrAuthType RSNAuthType;
9892 eCsrEncryptionType RSNEncryptType;
9893 eCsrEncryptionType mcRSNEncryptType;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +05309894 int status = VOS_STATUS_SUCCESS, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009895 tpWLAN_SAPEventCB pSapEventCallback;
9896 hdd_hostapd_state_t *pHostapdState;
Jeff Johnson295189b2012-06-20 16:38:30 -07009897 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309898 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009899 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309900 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07009901 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08009902 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05309903 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07009904 v_BOOL_t MFPCapable = VOS_FALSE;
9905 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309906 v_BOOL_t sapEnable11AC =
9907 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Kapil Gupta137ef892016-12-13 19:38:00 +05309908 u_int16_t prev_rsn_length = 0;
9909
Jeff Johnson295189b2012-06-20 16:38:30 -07009910 ENTER();
9911
Nitesh Shah9b066282017-06-06 18:05:52 +05309912 wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309913 iniConfig = pHddCtx->cfg_ini;
9914
Jeff Johnson295189b2012-06-20 16:38:30 -07009915 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
9916
9917 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9918
9919 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9920
9921 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9922
9923 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
9924
9925 //channel is already set in the set_channel Call back
9926 //pConfig->channel = pCommitConfig->channel;
9927
9928 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309929 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07009930 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
9931
9932 pConfig->dtim_period = pBeacon->dtim_period;
9933
Arif Hussain6d2a3322013-11-17 19:50:10 -08009934 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07009935 pConfig->dtim_period);
9936
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08009937 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07009938 {
9939 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07009940 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05309941 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
9942 {
9943 tANI_BOOLEAN restartNeeded;
9944 pConfig->ieee80211d = 1;
9945 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
9946 sme_setRegInfo(hHal, pConfig->countryCode);
9947 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
9948 }
9949 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009950 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07009951 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07009952 pConfig->ieee80211d = 1;
9953 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
9954 sme_setRegInfo(hHal, pConfig->countryCode);
9955 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07009956 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07009957 else
9958 {
9959 pConfig->ieee80211d = 0;
9960 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309961 /*
9962 * If auto channel is configured i.e. channel is 0,
9963 * so skip channel validation.
9964 */
9965 if( AUTO_CHANNEL_SELECT != pConfig->channel )
9966 {
9967 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
9968 {
9969 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009970 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309971 return -EINVAL;
9972 }
9973 }
9974 else
9975 {
9976 if(1 != pHddCtx->is_dynamic_channel_range_set)
9977 {
9978 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
9979 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
9980 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
9981 }
9982 pHddCtx->is_dynamic_channel_range_set = 0;
9983 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009984 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07009985 else
Jeff Johnson295189b2012-06-20 16:38:30 -07009986 {
9987 pConfig->ieee80211d = 0;
9988 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309989
9990#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9991 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
9992 pConfig->authType = eSAP_OPEN_SYSTEM;
9993 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
9994 pConfig->authType = eSAP_SHARED_KEY;
9995 else
9996 pConfig->authType = eSAP_AUTO_SWITCH;
9997#else
9998 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
9999 pConfig->authType = eSAP_OPEN_SYSTEM;
10000 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
10001 pConfig->authType = eSAP_SHARED_KEY;
10002 else
10003 pConfig->authType = eSAP_AUTO_SWITCH;
10004#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010005
10006 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010007
10008 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -070010009 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
Agrawal Ashisha8e8a722016-10-18 19:07:45 +053010010#ifdef SAP_AUTH_OFFLOAD
10011 /* In case of sap offload, hostapd.conf is configuted with open mode and
10012 * security is configured from ini file. Due to open mode in hostapd.conf
10013 * privacy bit is set to false which will result in not sending,
10014 * data packets as encrypted.
10015 * If enable_sap_auth_offload is enabled in ini and
10016 * sap_auth_offload_sec_type is type of WPA2-PSK,
10017 * driver will set privacy bit to 1.
10018 */
10019 if (pHddCtx->cfg_ini->enable_sap_auth_offload &&
10020 pHddCtx->cfg_ini->sap_auth_offload_sec_type)
10021 pConfig->privacy = VOS_TRUE;
10022#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010023
10024 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
10025
10026 /*Set wps station to configured*/
10027 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
10028
10029 if(pIe)
10030 {
10031 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
10032 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010033 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -070010034 return -EINVAL;
10035 }
10036 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
10037 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -070010038 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -070010039 /* Check 15 bit of WPS IE as it contain information for wps state
10040 * WPS state
10041 */
10042 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
10043 {
10044 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
10045 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
10046 {
10047 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
10048 }
10049 }
10050 }
10051 else
10052 {
10053 pConfig->wps_state = SAP_WPS_DISABLED;
10054 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010055 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -070010056
c_hpothufe599e92014-06-16 11:38:55 +053010057 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
10058 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
10059 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
10060 eCSR_ENCRYPT_TYPE_NONE;
10061
Jeff Johnson295189b2012-06-20 16:38:30 -070010062 pConfig->RSNWPAReqIELength = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +053010063 memset(&pConfig->RSNWPAReqIE[0], 0, sizeof(pConfig->RSNWPAReqIE));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010064 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070010065 WLAN_EID_RSN);
10066 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010067 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010068 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053010069 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
10070 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
10071 pConfig->RSNWPAReqIELength);
10072 else
10073 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
10074 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010075 /* The actual processing may eventually be more extensive than
10076 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -070010077 * by the app.
10078 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010079 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070010080 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
10081 &RSNEncryptType,
10082 &mcRSNEncryptType,
10083 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080010084 &MFPCapable,
10085 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053010086 pConfig->RSNWPAReqIE[1]+2,
10087 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010088
10089 if( VOS_STATUS_SUCCESS == status )
10090 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010091 /* Now copy over all the security attributes you have
10092 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070010093 * */
10094 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
10095 pConfig->mcRSNEncryptType = mcRSNEncryptType;
10096 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
10097 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010098 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080010099 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070010100 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
10101 }
10102 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010103
Jeff Johnson295189b2012-06-20 16:38:30 -070010104 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
10105 pBeacon->tail, pBeacon->tail_len);
10106
10107 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
10108 {
Kapil Gupta137ef892016-12-13 19:38:00 +053010109 if (pConfig->RSNWPAReqIE[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070010110 {
10111 /*Mixed mode WPA/WPA2*/
Kapil Gupta137ef892016-12-13 19:38:00 +053010112 prev_rsn_length = pConfig->RSNWPAReqIELength;
Jeff Johnson295189b2012-06-20 16:38:30 -070010113 pConfig->RSNWPAReqIELength += pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053010114 if (pConfig->RSNWPAReqIELength <=
10115 (sizeof(pConfig->RSNWPAReqIE) - prev_rsn_length))
10116 memcpy(&pConfig->RSNWPAReqIE[0] + prev_rsn_length, pIe,
10117 pIe[1] + 2);
10118 else
10119 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
10120 pConfig->RSNWPAReqIELength);
10121
Jeff Johnson295189b2012-06-20 16:38:30 -070010122 }
10123 else
10124 {
10125 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053010126 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
10127 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
10128 pConfig->RSNWPAReqIELength);
10129 else
10130 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
10131 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010132 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070010133 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
10134 &RSNEncryptType,
10135 &mcRSNEncryptType,
10136 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080010137 &MFPCapable,
10138 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053010139 pConfig->RSNWPAReqIE[1]+2,
10140 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010141
10142 if( VOS_STATUS_SUCCESS == status )
10143 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010144 /* Now copy over all the security attributes you have
10145 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070010146 * */
10147 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
10148 pConfig->mcRSNEncryptType = mcRSNEncryptType;
10149 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
10150 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010151 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080010152 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070010153 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
10154 }
10155 }
10156 }
10157
Kapil Gupta137ef892016-12-13 19:38:00 +053010158 if (pConfig->RSNWPAReqIELength > sizeof(pConfig->RSNWPAReqIE)) {
Jeff Johnson4416a782013-03-25 14:17:50 -070010159 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
10160 return -EINVAL;
10161 }
10162
Jeff Johnson295189b2012-06-20 16:38:30 -070010163 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
10164
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010165#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010166 if (params->ssid != NULL)
10167 {
10168 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
10169 pConfig->SSIDinfo.ssid.length = params->ssid_len;
10170 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
10171 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
10172 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010173#else
10174 if (ssid != NULL)
10175 {
10176 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
10177 pConfig->SSIDinfo.ssid.length = ssid_len;
10178 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
10179 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
10180 }
10181#endif
10182
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010183 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -070010184 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010185
Jeff Johnson295189b2012-06-20 16:38:30 -070010186 /* default value */
10187 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
10188 pConfig->num_accept_mac = 0;
10189 pConfig->num_deny_mac = 0;
10190
10191 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
10192 pBeacon->tail, pBeacon->tail_len);
10193
10194 /* pIe for black list is following form:
10195 type : 1 byte
10196 length : 1 byte
10197 OUI : 4 bytes
10198 acl type : 1 byte
10199 no of mac addr in black list: 1 byte
10200 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010201 */
10202 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010203 {
10204 pConfig->SapMacaddr_acl = pIe[6];
10205 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080010206 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010207 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053010208 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
10209 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010210 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
10211 for (i = 0; i < pConfig->num_deny_mac; i++)
10212 {
10213 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
10214 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010215 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010216 }
10217 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
10218 pBeacon->tail, pBeacon->tail_len);
10219
10220 /* pIe for white list is following form:
10221 type : 1 byte
10222 length : 1 byte
10223 OUI : 4 bytes
10224 acl type : 1 byte
10225 no of mac addr in white list: 1 byte
10226 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010227 */
10228 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010229 {
10230 pConfig->SapMacaddr_acl = pIe[6];
10231 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080010232 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010233 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053010234 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
10235 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010236 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
10237 for (i = 0; i < pConfig->num_accept_mac; i++)
10238 {
10239 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
10240 acl_entry++;
10241 }
10242 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053010243
Jeff Johnson295189b2012-06-20 16:38:30 -070010244 wlan_hdd_set_sapHwmode(pHostapdAdapter);
10245
Jeff Johnsone7245742012-09-05 17:12:55 -070010246#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080010247 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +053010248 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
10249 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +053010250 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
10251 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080010252 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
10253 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +053010254 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
10255 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -070010256 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053010257 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -070010258 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +053010259 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070010260
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010261 /* If ACS disable and selected channel <= 14
10262 * OR
10263 * ACS enabled and ACS operating band is choosen as 2.4
10264 * AND
10265 * VHT in 2.4G Disabled
10266 * THEN
10267 * Fallback to 11N mode
10268 */
10269 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
10270 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +053010271 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010272 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -070010273 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053010274 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
10275 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070010276 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
10277 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010278 }
10279#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010280
Jeff Johnson295189b2012-06-20 16:38:30 -070010281 // ht_capab is not what the name conveys,this is used for protection bitmap
10282 pConfig->ht_capab =
10283 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
10284
Kapil Gupta137ef892016-12-13 19:38:00 +053010285 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -070010286 {
10287 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
10288 return -EINVAL;
10289 }
10290
10291 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010292 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -070010293 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
10294 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010295 pConfig->obssProtEnabled =
10296 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -070010297
Chet Lanctot8cecea22014-02-11 19:09:36 -080010298#ifdef WLAN_FEATURE_11W
10299 pConfig->mfpCapable = MFPCapable;
10300 pConfig->mfpRequired = MFPRequired;
10301 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
10302 pConfig->mfpCapable, pConfig->mfpRequired);
10303#endif
10304
Arif Hussain6d2a3322013-11-17 19:50:10 -080010305 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -070010306 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -080010307 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
10308 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
10309 (int)pConfig->channel);
10310 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
10311 pConfig->SapHw_mode, pConfig->privacy,
10312 pConfig->authType);
10313 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
10314 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
10315 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
10316 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -070010317
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010318 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -070010319 {
10320 //Bss already started. just return.
10321 //TODO Probably it should update some beacon params.
10322 hddLog( LOGE, "Bss Already started...Ignore the request");
10323 EXIT();
10324 return 0;
10325 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010326
Agarwal Ashish51325b52014-06-16 16:50:49 +053010327 if (vos_max_concurrent_connections_reached()) {
10328 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10329 return -EINVAL;
10330 }
10331
Jeff Johnson295189b2012-06-20 16:38:30 -070010332 pConfig->persona = pHostapdAdapter->device_mode;
10333
Peng Xu2446a892014-09-05 17:21:18 +053010334 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
10335 if ( NULL != psmeConfig)
10336 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053010337 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +053010338 sme_GetConfigParam(hHal, psmeConfig);
10339 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053010340#ifdef WLAN_FEATURE_AP_HT40_24G
10341 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
10342 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
10343 && pHddCtx->cfg_ini->apHT40_24GEnabled)
10344 {
10345 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
10346 sme_UpdateConfig (hHal, psmeConfig);
10347 }
10348#endif
Peng Xu2446a892014-09-05 17:21:18 +053010349 vos_mem_free(psmeConfig);
10350 }
Peng Xuafc34e32014-09-25 13:23:55 +053010351 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +053010352
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010353 set_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
10354
Jeff Johnson295189b2012-06-20 16:38:30 -070010355 pSapEventCallback = hdd_hostapd_SAPEventCB;
10356 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
10357 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
10358 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010359 hddLog(LOGE,FL("SAP Start Bss fail"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010360 ret = -EINVAL;
10361 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070010362 }
10363
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010364 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -070010365 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
10366
10367 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010368
Jeff Johnson295189b2012-06-20 16:38:30 -070010369 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010370 {
10371 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010372 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -070010373 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070010374 VOS_ASSERT(0);
10375 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010376
Jeff Johnson295189b2012-06-20 16:38:30 -070010377 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053010378 if (WLANSAP_get_sessionId(pVosContext, &pHostapdAdapter->sessionId) !=
10379 VOS_STATUS_SUCCESS)
10380 {
10381 hddLog(LOGE,FL("Fail to get Softap sessionID"));
10382 VOS_ASSERT(0);
10383 }
Kaushik, Sushantf6070802014-10-15 15:09:23 +053010384 /* Initialize WMM configuation */
10385 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010386 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010387
Anurag Chouhan83026002016-12-13 22:46:21 +053010388#ifdef DHCP_SERVER_OFFLOAD
10389 /* set dhcp server offload */
10390 if (iniConfig->enable_dhcp_srv_offload &&
10391 sme_IsFeatureSupportedByFW(SAP_OFFLOADS)) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010392 vos_event_reset(&pHostapdAdapter->dhcp_status.vos_event);
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010393 status = wlan_hdd_set_dhcp_server_offload(pHostapdAdapter, false);
Anurag Chouhan83026002016-12-13 22:46:21 +053010394 if (!VOS_IS_STATUS_SUCCESS(status))
10395 {
10396 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10397 ("HDD DHCP Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010398 vos_event_reset(&pHostapdState->vosEvent);
10399 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
10400 status = vos_wait_single_event(&pHostapdState->vosEvent,
10401 10000);
10402 if (!VOS_IS_STATUS_SUCCESS(status)) {
10403 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010404 ret = -EINVAL;
10405 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010406 }
10407 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010408 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010409 status = vos_wait_single_event(&pHostapdAdapter->dhcp_status.vos_event, 2000);
10410 if (!VOS_IS_STATUS_SUCCESS(status) || pHostapdAdapter->dhcp_status.dhcp_offload_status)
10411 {
10412 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10413 ("ERROR: DHCP HDD vos wait for single_event failed!! %d"),
10414 pHostapdAdapter->dhcp_status.dhcp_offload_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010415 vos_event_reset(&pHostapdState->vosEvent);
10416 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
10417 status = vos_wait_single_event(&pHostapdState->vosEvent,
10418 10000);
10419 if (!VOS_IS_STATUS_SUCCESS(status)) {
10420 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010421 ret = -EINVAL;
10422 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010423 }
10424 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010425 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010426#ifdef MDNS_OFFLOAD
10427 if (iniConfig->enable_mdns_offload) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010428 vos_event_reset(&pHostapdAdapter->mdns_status.vos_event);
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010429 status = wlan_hdd_set_mdns_offload(pHostapdAdapter);
10430 if (VOS_IS_STATUS_SUCCESS(status))
10431 {
10432 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10433 ("HDD MDNS Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010434 vos_event_reset(&pHostapdState->vosEvent);
10435 if (VOS_STATUS_SUCCESS ==
10436 WLANSAP_StopBss(pHddCtx->pvosContext)) {
10437 status = vos_wait_single_event(&pHostapdState->vosEvent,
10438 10000);
10439 if (!VOS_IS_STATUS_SUCCESS(status)) {
10440 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010441 ret = -EINVAL;
10442 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010443 }
10444 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010445 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010446 status = vos_wait_single_event(&pHostapdAdapter->
10447 mdns_status.vos_event, 2000);
10448 if (!VOS_IS_STATUS_SUCCESS(status) ||
10449 pHostapdAdapter->mdns_status.mdns_enable_status ||
10450 pHostapdAdapter->mdns_status.mdns_fqdn_status ||
10451 pHostapdAdapter->mdns_status.mdns_resp_status)
10452 {
10453 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10454 ("MDNS HDD vos wait for single_event failed!! enable %d fqdn %d resp %d"),
10455 pHostapdAdapter->mdns_status.mdns_enable_status,
10456 pHostapdAdapter->mdns_status.mdns_fqdn_status,
10457 pHostapdAdapter->mdns_status.mdns_resp_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010458 vos_event_reset(&pHostapdState->vosEvent);
10459 if (VOS_STATUS_SUCCESS ==
10460 WLANSAP_StopBss(pHddCtx->pvosContext)) {
10461 status = vos_wait_single_event(&pHostapdState->vosEvent,
10462 10000);
10463 if (!VOS_IS_STATUS_SUCCESS(status)) {
10464 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010465 ret = -EINVAL;
10466 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010467 }
10468 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010469 }
10470 }
10471#endif /* MDNS_OFFLOAD */
10472 } else {
10473 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10474 ("DHCP Disabled ini %d, FW %d"),
10475 iniConfig->enable_dhcp_srv_offload,
10476 sme_IsFeatureSupportedByFW(SAP_OFFLOADS));
Anurag Chouhan83026002016-12-13 22:46:21 +053010477 }
10478#endif /* DHCP_SERVER_OFFLOAD */
10479
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010480#ifdef WLAN_FEATURE_P2P_DEBUG
10481 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
10482 {
10483 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
10484 {
10485 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
10486 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -080010487 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010488 }
10489 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
10490 {
10491 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
10492 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -080010493 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010494 }
10495 }
10496#endif
Ashish Kumar Dhanotiya42aa5152017-01-03 20:25:57 +053010497 /* Check and restart SAP if it is on Unsafe channel */
10498 hdd_check_for_unsafe_ch(pHostapdAdapter, pHddCtx);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010499
Jeff Johnson295189b2012-06-20 16:38:30 -070010500 pHostapdState->bCommit = TRUE;
10501 EXIT();
10502
10503 return 0;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010504error:
10505 clear_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
10506 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010507}
10508
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010509#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010510static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010511 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070010512 struct beacon_parameters *params)
10513{
10514 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010515 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010516 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010517
10518 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010519
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010520 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10521 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
10522 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010523 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
10524 hdd_device_modetoString(pAdapter->device_mode),
10525 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010526
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010527 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10528 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010529 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010530 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010531 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010532 }
10533
Agarwal Ashish51325b52014-06-16 16:50:49 +053010534 if (vos_max_concurrent_connections_reached()) {
10535 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10536 return -EINVAL;
10537 }
10538
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010539 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010540 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070010541 )
10542 {
10543 beacon_data_t *old,*new;
10544
10545 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010546
Jeff Johnson295189b2012-06-20 16:38:30 -070010547 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010548 {
10549 hddLog(VOS_TRACE_LEVEL_WARN,
10550 FL("already beacon info added to session(%d)"),
10551 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070010552 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010553 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010554
10555 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
10556
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010557 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -070010558 {
10559 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010560 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010561 return -EINVAL;
10562 }
10563
10564 pAdapter->sessionCtx.ap.beacon = new;
10565
10566 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
10567 }
10568
10569 EXIT();
10570 return status;
10571}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010572
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010573static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
10574 struct net_device *dev,
10575 struct beacon_parameters *params)
10576{
10577 int ret;
10578
10579 vos_ssr_protect(__func__);
10580 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
10581 vos_ssr_unprotect(__func__);
10582
10583 return ret;
10584}
10585
10586static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010587 struct net_device *dev,
10588 struct beacon_parameters *params)
10589{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010590 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010591 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10592 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010593 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010594
10595 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010596
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010597 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10598 TRACE_CODE_HDD_CFG80211_SET_BEACON,
10599 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
10600 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10601 __func__, hdd_device_modetoString(pAdapter->device_mode),
10602 pAdapter->device_mode);
10603
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010604 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10605 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010606 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010607 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010608 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010609 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010610
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010611 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010612 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010613 )
Jeff Johnson295189b2012-06-20 16:38:30 -070010614 {
10615 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010616
Jeff Johnson295189b2012-06-20 16:38:30 -070010617 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010618
Jeff Johnson295189b2012-06-20 16:38:30 -070010619 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010620 {
10621 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10622 FL("session(%d) old and new heads points to NULL"),
10623 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070010624 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010625 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010626
10627 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
10628
10629 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010630 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010631 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010632 return -EINVAL;
10633 }
10634
10635 pAdapter->sessionCtx.ap.beacon = new;
10636
10637 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
10638 }
10639
10640 EXIT();
10641 return status;
10642}
10643
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010644static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
10645 struct net_device *dev,
10646 struct beacon_parameters *params)
10647{
10648 int ret;
10649
10650 vos_ssr_protect(__func__);
10651 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
10652 vos_ssr_unprotect(__func__);
10653
10654 return ret;
10655}
10656
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010657#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10658
10659#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010660static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010661 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010662#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010663static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010664 struct net_device *dev)
10665#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010666{
10667 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -070010668 hdd_context_t *pHddCtx = NULL;
10669 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010670 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010671 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010672
10673 ENTER();
10674
10675 if (NULL == pAdapter)
10676 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010677 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010678 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010679 return -ENODEV;
10680 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010681
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010682 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10683 TRACE_CODE_HDD_CFG80211_STOP_AP,
10684 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010685 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10686 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010687 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010688 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010689 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -070010690 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010691
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010692 pScanInfo = &pHddCtx->scan_info;
10693
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010694 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10695 __func__, hdd_device_modetoString(pAdapter->device_mode),
10696 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010697
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010698 ret = wlan_hdd_scan_abort(pAdapter);
10699
Girish Gowli4bf7a632014-06-12 13:42:11 +053010700 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -070010701 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010702 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10703 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010704
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010705 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -070010706 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010707 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10708 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -080010709
Jeff Johnsone7245742012-09-05 17:12:55 -070010710 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010711 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -070010712 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010713 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070010714 }
10715
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010716 /* Delete all associated STAs before stopping AP/P2P GO */
10717 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +053010718 hdd_hostapd_stop(dev);
10719
Jeff Johnson295189b2012-06-20 16:38:30 -070010720 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010721 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070010722 )
10723 {
10724 beacon_data_t *old;
10725
10726 old = pAdapter->sessionCtx.ap.beacon;
10727
10728 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010729 {
10730 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10731 FL("session(%d) beacon data points to NULL"),
10732 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070010733 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010734 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010735
Jeff Johnson295189b2012-06-20 16:38:30 -070010736 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010737
10738 mutex_lock(&pHddCtx->sap_lock);
10739 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
10740 {
Jeff Johnson4416a782013-03-25 14:17:50 -070010741 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -070010742 {
10743 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
10744
10745 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
10746
10747 if (!VOS_IS_STATUS_SUCCESS(status))
10748 {
10749 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010750 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -070010751 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010752 }
10753 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010754 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010755 /* BSS stopped, clear the active sessions for this device mode */
10756 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010757 }
10758 mutex_unlock(&pHddCtx->sap_lock);
10759
10760 if(status != VOS_STATUS_SUCCESS)
10761 {
10762 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010763 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010764 return -EINVAL;
10765 }
10766
Jeff Johnson4416a782013-03-25 14:17:50 -070010767 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070010768 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
10769 ==eHAL_STATUS_FAILURE)
10770 {
10771 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010772 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010773 }
10774
Jeff Johnson4416a782013-03-25 14:17:50 -070010775 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070010776 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
10777 eANI_BOOLEAN_FALSE) )
10778 {
10779 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010780 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010781 }
10782
10783 // Reset WNI_CFG_PROBE_RSP Flags
10784 wlan_hdd_reset_prob_rspies(pAdapter);
10785
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010786 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
10787
Jeff Johnson295189b2012-06-20 16:38:30 -070010788 pAdapter->sessionCtx.ap.beacon = NULL;
10789 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010790#ifdef WLAN_FEATURE_P2P_DEBUG
10791 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
10792 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
10793 {
10794 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
10795 "GO got removed");
10796 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
10797 }
10798#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010799 }
10800 EXIT();
10801 return status;
10802}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010803
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010804#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10805static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
10806 struct net_device *dev)
10807{
10808 int ret;
10809
10810 vos_ssr_protect(__func__);
10811 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
10812 vos_ssr_unprotect(__func__);
10813
10814 return ret;
10815}
10816#else
10817static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
10818 struct net_device *dev)
10819{
10820 int ret;
10821
10822 vos_ssr_protect(__func__);
10823 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
10824 vos_ssr_unprotect(__func__);
10825
10826 return ret;
10827}
10828#endif
10829
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010830#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
10831
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010832static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010833 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010834 struct cfg80211_ap_settings *params)
10835{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010836 hdd_adapter_t *pAdapter;
10837 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010838 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010839
10840 ENTER();
10841
Girish Gowlib143d7a2015-02-18 19:39:55 +053010842 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010843 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010844 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +053010845 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010846 return -ENODEV;
10847 }
10848
10849 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
10850 if (NULL == pAdapter)
10851 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010852 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010853 "%s: HDD adapter is Null", __func__);
10854 return -ENODEV;
10855 }
10856
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010857 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10858 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
10859 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010860 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
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 magic is invalid", __func__);
10864 return -ENODEV;
10865 }
10866
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010867 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
10868
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010869 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010870 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010871 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010872 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010873 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010874 }
10875
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010876 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
10877 __func__, hdd_device_modetoString(pAdapter->device_mode),
10878 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010879
10880 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010881 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010882 )
10883 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010884 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010885
10886 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010887
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010888 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010889 {
10890 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
10891 FL("already beacon info added to session(%d)"),
10892 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010893 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010894 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010895
Girish Gowlib143d7a2015-02-18 19:39:55 +053010896#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10897 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
10898 &new,
10899 &params->beacon);
10900#else
10901 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
10902 &new,
10903 &params->beacon,
10904 params->dtim_period);
10905#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010906
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010907 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010908 {
10909 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010910 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010911 return -EINVAL;
10912 }
10913 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -080010914#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -070010915 wlan_hdd_cfg80211_set_channel(wiphy, dev,
10916#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
10917 params->channel, params->channel_type);
10918#else
10919 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
10920#endif
Viral Modi3a32cc52013-02-08 11:14:52 -080010921#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010922 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010923 params->ssid_len, params->hidden_ssid,
10924 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010925 }
10926
10927 EXIT();
10928 return status;
10929}
10930
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010931static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
10932 struct net_device *dev,
10933 struct cfg80211_ap_settings *params)
10934{
10935 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010936
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010937 vos_ssr_protect(__func__);
10938 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
10939 vos_ssr_unprotect(__func__);
10940
10941 return ret;
10942}
10943
10944static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010945 struct net_device *dev,
10946 struct cfg80211_beacon_data *params)
10947{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010948 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010949 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010950 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010951
10952 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010953
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010954 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10955 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
10956 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -080010957 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010958 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010959
10960 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10961 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010962 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010963 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010964 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010965 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010966
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010967 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010968 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010969 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010970 {
10971 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010972
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010973 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010974
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010975 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010976 {
10977 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10978 FL("session(%d) beacon data points to NULL"),
10979 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010980 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010981 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010982
10983 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
10984
10985 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010986 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010987 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010988 return -EINVAL;
10989 }
10990
10991 pAdapter->sessionCtx.ap.beacon = new;
10992
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010993 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
10994 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010995 }
10996
10997 EXIT();
10998 return status;
10999}
11000
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011001static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
11002 struct net_device *dev,
11003 struct cfg80211_beacon_data *params)
11004{
11005 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011006
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011007 vos_ssr_protect(__func__);
11008 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
11009 vos_ssr_unprotect(__func__);
11010
11011 return ret;
11012}
11013
11014#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011015
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011016static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011017 struct net_device *dev,
11018 struct bss_parameters *params)
11019{
11020 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011021 hdd_context_t *pHddCtx;
11022 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011023
11024 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011025
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011026 if (NULL == pAdapter)
11027 {
11028 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11029 "%s: HDD adapter is Null", __func__);
11030 return -ENODEV;
11031 }
11032 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011033 ret = wlan_hdd_validate_context(pHddCtx);
11034 if (0 != ret)
11035 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011036 return ret;
11037 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011038 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11039 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
11040 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011041 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11042 __func__, hdd_device_modetoString(pAdapter->device_mode),
11043 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011044
11045 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011046 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011047 )
Jeff Johnson295189b2012-06-20 16:38:30 -070011048 {
11049 /* ap_isolate == -1 means that in change bss, upper layer doesn't
11050 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011051 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -070011052 {
11053 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011054 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011055 }
11056
11057 EXIT();
11058 return 0;
11059}
11060
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011061static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
11062 struct net_device *dev,
11063 struct bss_parameters *params)
11064{
11065 int ret;
11066
11067 vos_ssr_protect(__func__);
11068 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
11069 vos_ssr_unprotect(__func__);
11070
11071 return ret;
11072}
Kiet Lam10841362013-11-01 11:36:50 +053011073/* FUNCTION: wlan_hdd_change_country_code_cd
11074* to wait for contry code completion
11075*/
11076void* wlan_hdd_change_country_code_cb(void *pAdapter)
11077{
11078 hdd_adapter_t *call_back_pAdapter = pAdapter;
11079 complete(&call_back_pAdapter->change_country_code);
11080 return NULL;
11081}
11082
Jeff Johnson295189b2012-06-20 16:38:30 -070011083/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053011084 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -070011085 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
11086 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053011087int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011088 struct net_device *ndev,
11089 enum nl80211_iftype type,
11090 u32 *flags,
11091 struct vif_params *params
11092 )
11093{
11094 struct wireless_dev *wdev;
11095 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011096 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -070011097 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011098 tCsrRoamProfile *pRoamProfile = NULL;
11099 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011100 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011101 eMib_dot11DesiredBssType connectedBssType;
11102 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011103 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011104
11105 ENTER();
11106
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011107 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011108 {
11109 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11110 "%s: Adapter context is null", __func__);
11111 return VOS_STATUS_E_FAILURE;
11112 }
11113
11114 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11115 if (!pHddCtx)
11116 {
11117 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11118 "%s: HDD context is null", __func__);
11119 return VOS_STATUS_E_FAILURE;
11120 }
11121
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011122 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11123 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
11124 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011125 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011126 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011127 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011128 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011129 }
11130
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011131 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11132 __func__, hdd_device_modetoString(pAdapter->device_mode),
11133 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011134
Agarwal Ashish51325b52014-06-16 16:50:49 +053011135 if (vos_max_concurrent_connections_reached()) {
11136 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11137 return -EINVAL;
11138 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011139 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070011140 wdev = ndev->ieee80211_ptr;
11141
11142#ifdef WLAN_BTAMP_FEATURE
11143 if((NL80211_IFTYPE_P2P_CLIENT == type)||
11144 (NL80211_IFTYPE_ADHOC == type)||
11145 (NL80211_IFTYPE_AP == type)||
11146 (NL80211_IFTYPE_P2P_GO == type))
11147 {
11148 pHddCtx->isAmpAllowed = VOS_FALSE;
11149 // stop AMP traffic
11150 status = WLANBAP_StopAmp();
11151 if(VOS_STATUS_SUCCESS != status )
11152 {
11153 pHddCtx->isAmpAllowed = VOS_TRUE;
11154 hddLog(VOS_TRACE_LEVEL_FATAL,
11155 "%s: Failed to stop AMP", __func__);
11156 return -EINVAL;
11157 }
11158 }
11159#endif //WLAN_BTAMP_FEATURE
11160 /* Reset the current device mode bit mask*/
11161 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
11162
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +053011163 if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
11164 ((type == NL80211_IFTYPE_P2P_CLIENT) ||
11165 (type == NL80211_IFTYPE_P2P_GO)))
11166 {
11167 /* Notify Mode change in case of concurrency.
11168 * Below function invokes TDLS teardown Functionality Since TDLS is
11169 * not Supported in case of concurrency i.e Once P2P session
11170 * is detected disable offchannel and teardown TDLS links
11171 */
11172 hddLog(LOG1,
11173 FL("Device mode = %d Interface type = %d"),
11174 pAdapter->device_mode, type);
11175 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
11176 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +053011177
Jeff Johnson295189b2012-06-20 16:38:30 -070011178 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070011179 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -070011180 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -070011181 )
11182 {
11183 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011184 if (!pWextState)
11185 {
11186 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11187 "%s: pWextState is null", __func__);
11188 return VOS_STATUS_E_FAILURE;
11189 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011190 pRoamProfile = &pWextState->roamProfile;
11191 LastBSSType = pRoamProfile->BSSType;
11192
11193 switch (type)
11194 {
11195 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070011196 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070011197 hddLog(VOS_TRACE_LEVEL_INFO,
11198 "%s: setting interface Type to INFRASTRUCTURE", __func__);
11199 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -070011200#ifdef WLAN_FEATURE_11AC
11201 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
11202 {
11203 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
11204 }
11205#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011206 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -070011207 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011208 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080011209 //Check for sub-string p2p to confirm its a p2p interface
11210 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011211 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +053011212#ifdef FEATURE_WLAN_TDLS
11213 mutex_lock(&pHddCtx->tdls_lock);
11214 wlan_hdd_tdls_exit(pAdapter, TRUE);
11215 mutex_unlock(&pHddCtx->tdls_lock);
11216#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -080011217 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
11218 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
11219 }
11220 else
11221 {
11222 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070011223 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080011224 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011225 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +053011226
Jeff Johnson295189b2012-06-20 16:38:30 -070011227 case NL80211_IFTYPE_ADHOC:
11228 hddLog(VOS_TRACE_LEVEL_INFO,
11229 "%s: setting interface Type to ADHOC", __func__);
11230 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
11231 pRoamProfile->phyMode =
11232 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -070011233 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011234 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +053011235 hdd_set_ibss_ops( pAdapter );
11236 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +053011237
11238 status = hdd_sta_id_hash_attach(pAdapter);
11239 if (VOS_STATUS_SUCCESS != status) {
11240 hddLog(VOS_TRACE_LEVEL_ERROR,
11241 FL("Failed to initialize hash for IBSS"));
11242 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011243 break;
11244
11245 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070011246 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070011247 {
11248 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
11249 "%s: setting interface Type to %s", __func__,
11250 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
11251
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080011252 //Cancel any remain on channel for GO mode
11253 if (NL80211_IFTYPE_P2P_GO == type)
11254 {
11255 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
11256 }
Mohit Khanna0f232092012-09-11 14:46:08 -070011257 if (NL80211_IFTYPE_AP == type)
11258 {
11259 /* As Loading WLAN Driver one interface being created for p2p device
11260 * address. This will take one HW STA and the max number of clients
11261 * that can connect to softAP will be reduced by one. so while changing
11262 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
11263 * interface as it is not required in SoftAP mode.
11264 */
11265
11266 // Get P2P Adapter
11267 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
11268
11269 if (pP2pAdapter)
11270 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053011271 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +053011272 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -070011273 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
11274 }
11275 }
Swaroop Goltia2e32212014-04-09 23:37:33 +053011276 //Disable IMPS & BMPS for SAP/GO
11277 if(VOS_STATUS_E_FAILURE ==
11278 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
11279 {
11280 //Fail to Exit BMPS
11281 VOS_ASSERT(0);
11282 }
Deepthi Gowri500fc472014-08-11 19:53:10 +053011283
11284 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
11285
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011286#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -070011287
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011288 /* A Mutex Lock is introduced while changing the mode to
11289 * protect the concurrent access for the Adapters by TDLS
11290 * module.
11291 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011292 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011293#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011294 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +053011295 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011296 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -070011297 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
11298 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011299#ifdef FEATURE_WLAN_TDLS
11300 mutex_unlock(&pHddCtx->tdls_lock);
11301#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070011302 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
11303 (pConfig->apRandomBssidEnabled))
11304 {
11305 /* To meet Android requirements create a randomized
11306 MAC address of the form 02:1A:11:Fx:xx:xx */
11307 get_random_bytes(&ndev->dev_addr[3], 3);
11308 ndev->dev_addr[0] = 0x02;
11309 ndev->dev_addr[1] = 0x1A;
11310 ndev->dev_addr[2] = 0x11;
11311 ndev->dev_addr[3] |= 0xF0;
11312 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
11313 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -080011314 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
11315 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070011316 }
11317
Jeff Johnson295189b2012-06-20 16:38:30 -070011318 hdd_set_ap_ops( pAdapter->dev );
11319
Kiet Lam10841362013-11-01 11:36:50 +053011320 /* This is for only SAP mode where users can
11321 * control country through ini.
11322 * P2P GO follows station country code
11323 * acquired during the STA scanning. */
11324 if((NL80211_IFTYPE_AP == type) &&
11325 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
11326 {
11327 int status = 0;
11328 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
11329 "%s: setting country code from INI ", __func__);
11330 init_completion(&pAdapter->change_country_code);
11331 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
11332 (void *)(tSmeChangeCountryCallback)
11333 wlan_hdd_change_country_code_cb,
11334 pConfig->apCntryCode, pAdapter,
11335 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053011336 eSIR_FALSE,
11337 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +053011338 if (eHAL_STATUS_SUCCESS == status)
11339 {
11340 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011341 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +053011342 &pAdapter->change_country_code,
11343 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011344 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +053011345 {
11346 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011347 FL("SME Timed out while setting country code %ld"),
11348 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -080011349
11350 if (pHddCtx->isLogpInProgress)
11351 {
11352 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11353 "%s: LOGP in Progress. Ignore!!!", __func__);
11354 return -EAGAIN;
11355 }
Kiet Lam10841362013-11-01 11:36:50 +053011356 }
11357 }
11358 else
11359 {
11360 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011361 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +053011362 return -EINVAL;
11363 }
11364 }
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +053011365 status = hdd_init_ap_mode(pAdapter, false);
Jeff Johnson295189b2012-06-20 16:38:30 -070011366 if(status != VOS_STATUS_SUCCESS)
11367 {
11368 hddLog(VOS_TRACE_LEVEL_FATAL,
11369 "%s: Error initializing the ap mode", __func__);
11370 return -EINVAL;
11371 }
11372 hdd_set_conparam(1);
11373
Nirav Shah7e3c8132015-06-22 23:51:42 +053011374 status = hdd_sta_id_hash_attach(pAdapter);
11375 if (VOS_STATUS_SUCCESS != status)
11376 {
11377 hddLog(VOS_TRACE_LEVEL_ERROR,
11378 FL("Failed to initialize hash for AP"));
11379 return -EINVAL;
11380 }
11381
Jeff Johnson295189b2012-06-20 16:38:30 -070011382 /*interface type changed update in wiphy structure*/
11383 if(wdev)
11384 {
11385 wdev->iftype = type;
11386 pHddCtx->change_iface = type;
11387 }
11388 else
11389 {
11390 hddLog(VOS_TRACE_LEVEL_ERROR,
11391 "%s: ERROR !!!! Wireless dev is NULL", __func__);
11392 return -EINVAL;
11393 }
11394 goto done;
11395 }
11396
11397 default:
11398 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
11399 __func__);
11400 return -EOPNOTSUPP;
11401 }
11402 }
11403 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011404 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011405 )
11406 {
11407 switch(type)
11408 {
11409 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070011410 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070011411 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +053011412
11413 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011414#ifdef FEATURE_WLAN_TDLS
11415
11416 /* A Mutex Lock is introduced while changing the mode to
11417 * protect the concurrent access for the Adapters by TDLS
11418 * module.
11419 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011420 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011421#endif
c_hpothu002231a2015-02-05 14:58:51 +053011422 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011423 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080011424 //Check for sub-string p2p to confirm its a p2p interface
11425 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -080011426 {
11427 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
11428 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
11429 }
11430 else
11431 {
11432 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070011433 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080011434 }
Agrawal Ashishcfe83282016-09-29 13:03:45 +053011435
11436 /* set con_mode to STA only when no SAP concurrency mode */
11437 if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO)))
11438 hdd_set_conparam(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070011439 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070011440 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
11441 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011442#ifdef FEATURE_WLAN_TDLS
11443 mutex_unlock(&pHddCtx->tdls_lock);
11444#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +053011445 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -070011446 if( VOS_STATUS_SUCCESS != status )
11447 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -070011448 /* In case of JB, for P2P-GO, only change interface will be called,
11449 * This is the right place to enable back bmps_imps()
11450 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053011451 if (pHddCtx->hdd_wlan_suspended)
11452 {
11453 hdd_set_pwrparams(pHddCtx);
11454 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011455 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070011456 goto done;
11457 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070011458 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070011459 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070011460 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
11461 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -070011462 goto done;
11463 default:
11464 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
11465 __func__);
11466 return -EOPNOTSUPP;
11467
11468 }
11469
11470 }
11471 else
11472 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011473 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
11474 __func__, hdd_device_modetoString(pAdapter->device_mode),
11475 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011476 return -EOPNOTSUPP;
11477 }
11478
11479
11480 if(pRoamProfile)
11481 {
11482 if ( LastBSSType != pRoamProfile->BSSType )
11483 {
11484 /*interface type changed update in wiphy structure*/
11485 wdev->iftype = type;
11486
11487 /*the BSS mode changed, We need to issue disconnect
11488 if connected or in IBSS disconnect state*/
11489 if ( hdd_connGetConnectedBssType(
11490 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
11491 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
11492 {
11493 /*need to issue a disconnect to CSR.*/
11494 INIT_COMPLETION(pAdapter->disconnect_comp_var);
11495 if( eHAL_STATUS_SUCCESS ==
11496 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
11497 pAdapter->sessionId,
11498 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
11499 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011500 ret = wait_for_completion_interruptible_timeout(
11501 &pAdapter->disconnect_comp_var,
11502 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
11503 if (ret <= 0)
11504 {
11505 hddLog(VOS_TRACE_LEVEL_ERROR,
11506 FL("wait on disconnect_comp_var failed %ld"), ret);
11507 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011508 }
11509 }
11510 }
11511 }
11512
11513done:
11514 /*set bitmask based on updated value*/
11515 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -070011516
11517 /* Only STA mode support TM now
11518 * all other mode, TM feature should be disabled */
11519 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
11520 (~VOS_STA & pHddCtx->concurrency_mode) )
11521 {
11522 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
11523 }
11524
Jeff Johnson295189b2012-06-20 16:38:30 -070011525#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011526 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053011527 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -070011528 {
11529 //we are ok to do AMP
11530 pHddCtx->isAmpAllowed = VOS_TRUE;
11531 }
11532#endif //WLAN_BTAMP_FEATURE
11533 EXIT();
11534 return 0;
11535}
11536
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053011537/*
11538 * FUNCTION: wlan_hdd_cfg80211_change_iface
11539 * wrapper function to protect the actual implementation from SSR.
11540 */
11541int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
11542 struct net_device *ndev,
11543 enum nl80211_iftype type,
11544 u32 *flags,
11545 struct vif_params *params
11546 )
11547{
11548 int ret;
11549
11550 vos_ssr_protect(__func__);
11551 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
11552 vos_ssr_unprotect(__func__);
11553
11554 return ret;
11555}
11556
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011557#ifdef FEATURE_WLAN_TDLS
11558static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011559 struct net_device *dev,
11560#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
11561 const u8 *mac,
11562#else
11563 u8 *mac,
11564#endif
11565 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011566{
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011567 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011568 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011569 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011570 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053011571 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053011572 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011573
11574 ENTER();
11575
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053011576 if (!dev) {
11577 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
11578 return -EINVAL;
11579 }
11580
11581 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
11582 if (!pAdapter) {
11583 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
11584 return -EINVAL;
11585 }
11586
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053011587 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011588 {
11589 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11590 "Invalid arguments");
11591 return -EINVAL;
11592 }
Hoonki Lee27511902013-03-14 18:19:06 -070011593
11594 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
11595 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
11596 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011597 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070011598 "%s: TDLS mode is disabled OR not enabled in FW."
11599 MAC_ADDRESS_STR " Request declined.",
11600 __func__, MAC_ADDR_ARRAY(mac));
11601 return -ENOTSUPP;
11602 }
11603
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011604 if (pHddCtx->isLogpInProgress)
11605 {
11606 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11607 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053011608 wlan_hdd_tdls_set_link_status(pAdapter,
11609 mac,
11610 eTDLS_LINK_IDLE,
11611 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011612 return -EBUSY;
11613 }
11614
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053011615 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +053011616 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011617
11618 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011619 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011620 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
11621 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053011622 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011623 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070011624 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011625
11626 /* in add station, we accept existing valid staId if there is */
11627 if ((0 == update) &&
11628 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
11629 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011630 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011631 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011632 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011633 " link_status %d. staId %d. add station ignored.",
11634 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011635 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011636 return 0;
11637 }
11638 /* in change station, we accept only when staId is valid */
11639 if ((1 == update) &&
11640 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
11641 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
11642 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011643 tANI_U16 staId = pTdlsPeer->staId;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011644 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011645 "%s: " MAC_ADDRESS_STR
11646 " link status %d. staId %d. change station %s.",
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011647 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, staId,
11648 (TDLS_STA_INDEX_VALID(staId)) ? "ignored" : "declined");
11649 mutex_unlock(&pHddCtx->tdls_lock);
11650 return (TDLS_STA_INDEX_VALID(staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011651 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011652 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070011653
11654 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053011655 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011656 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011657 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11658 "%s: " MAC_ADDRESS_STR
11659 " TDLS setup is ongoing. Request declined.",
11660 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -070011661 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011662 }
11663
11664 /* first to check if we reached to maximum supported TDLS peer.
11665 TODO: for now, return -EPERM looks working fine,
11666 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011667 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
11668 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011669 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011670 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11671 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011672 " TDLS Max peer already connected. Request declined."
11673 " Num of peers (%d), Max allowed (%d).",
11674 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
11675 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070011676 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011677 }
11678 else
11679 {
11680 hddTdlsPeer_t *pTdlsPeer;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011681 mutex_lock(&pHddCtx->tdls_lock);
11682 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011683 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011684 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011685 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011686 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11687 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
11688 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011689 return -EPERM;
11690 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011691 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011692 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011693 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +053011694 wlan_hdd_tdls_set_link_status(pAdapter,
11695 mac,
11696 eTDLS_LINK_CONNECTING,
11697 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011698
Jeff Johnsond75fe012013-04-06 10:53:06 -070011699 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053011700 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011701 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011702 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011703 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -070011704 if(StaParams->htcap_present)
11705 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011706 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070011707 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011708 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070011709 "ht_capa->extended_capabilities: %0x",
11710 StaParams->HTCap.extendedHtCapInfo);
11711 }
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 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011714 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011715 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -070011716 if(StaParams->vhtcap_present)
11717 {
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 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
11720 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
11721 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
11722 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011723 {
11724 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011725 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011726 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011727 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011728 "[%d]: %x ", i, StaParams->supported_rates[i]);
11729 }
Jeff Johnsond75fe012013-04-06 10:53:06 -070011730 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053011731 else if ((1 == update) && (NULL == StaParams))
11732 {
11733 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11734 "%s : update is true, but staParams is NULL. Error!", __func__);
11735 return -EPERM;
11736 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011737
11738 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
11739
11740 if (!update)
11741 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053011742 /*Before adding sta make sure that device exited from BMPS*/
11743 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
11744 {
11745 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11746 "%s: Adding tdls peer sta. Disable BMPS", __func__);
11747 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
11748 if (status != VOS_STATUS_SUCCESS) {
11749 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
11750 }
11751 }
11752
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011753 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011754 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011755 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053011756 hddLog(VOS_TRACE_LEVEL_ERROR,
11757 FL("Failed to add TDLS peer STA. Enable Bmps"));
11758 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011759 return -EPERM;
11760 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011761 }
11762 else
11763 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011764 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011765 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011766 if (ret != eHAL_STATUS_SUCCESS) {
11767 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
11768 return -EPERM;
11769 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011770 }
11771
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011772 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011773 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
11774
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053011775 mutex_lock(&pHddCtx->tdls_lock);
11776 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
11777
Masti, Narayanraddi07262462016-01-19 12:40:06 +053011778 if ((pTdlsPeer != NULL) &&
11779 (pTdlsPeer->link_status == eTDLS_LINK_TEARING))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011780 {
Masti, Narayanraddi07262462016-01-19 12:40:06 +053011781 hddLog(VOS_TRACE_LEVEL_ERROR,
11782 FL("peer link status %u"), pTdlsPeer->link_status);
11783 mutex_unlock(&pHddCtx->tdls_lock);
11784 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011785 }
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053011786 mutex_unlock(&pHddCtx->tdls_lock);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011787
Masti, Narayanraddi07262462016-01-19 12:40:06 +053011788 if (ret <= 0)
11789 {
11790 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11791 "%s: timeout waiting for tdls add station indication %ld",
11792 __func__, ret);
11793 goto error;
11794 }
11795
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011796 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
11797 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011798 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011799 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070011800 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011801 }
11802
11803 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -070011804
11805error:
Atul Mittal115287b2014-07-08 13:26:33 +053011806 wlan_hdd_tdls_set_link_status(pAdapter,
11807 mac,
11808 eTDLS_LINK_IDLE,
11809 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -070011810 return -EPERM;
11811
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011812}
11813#endif
11814
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011815static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011816 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011817#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
11818 const u8 *mac,
11819#else
Jeff Johnson295189b2012-06-20 16:38:30 -070011820 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011821#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011822 struct station_parameters *params)
11823{
11824 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011825 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +053011826 hdd_context_t *pHddCtx;
11827 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011828 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011829 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070011830#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011831 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011832 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011833 tANI_U8 isOffChannelSupported = 0;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011834 tANI_U8 isQosWmmSta = FALSE;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070011835#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070011836
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011837 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011838
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011839 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +053011840 if ((NULL == pAdapter))
11841 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011842 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053011843 "invalid adapter ");
11844 return -EINVAL;
11845 }
11846
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011847 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11848 TRACE_CODE_HDD_CHANGE_STATION,
11849 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +053011850 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +053011851
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011852 ret = wlan_hdd_validate_context(pHddCtx);
11853 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +053011854 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011855 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +053011856 }
11857
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011858 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11859
11860 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011861 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011862 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11863 "invalid HDD station context");
11864 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011865 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011866 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
11867
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011868 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
11869 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -070011870 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011871 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -070011872 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011873 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -070011874 WLANTL_STA_AUTHENTICATED);
11875
Gopichand Nakkala29149562013-05-10 21:43:41 +053011876 if (status != VOS_STATUS_SUCCESS)
11877 {
11878 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11879 "%s: Not able to change TL state to AUTHENTICATED", __func__);
11880 return -EINVAL;
11881 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011882 }
11883 }
Hoonki Leea6d49be2013-04-05 09:43:25 -070011884 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
11885 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +053011886#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011887 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
11888 StaParams.capability = params->capability;
11889 StaParams.uapsd_queues = params->uapsd_queues;
11890 StaParams.max_sp = params->max_sp;
11891
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011892 /* Convert (first channel , number of channels) tuple to
11893 * the total list of channels. This goes with the assumption
11894 * that if the first channel is < 14, then the next channels
11895 * are an incremental of 1 else an incremental of 4 till the number
11896 * of channels.
11897 */
11898 if (0 != params->supported_channels_len) {
11899 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
11900 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
11901 {
11902 int wifi_chan_index;
11903 StaParams.supported_channels[j] = params->supported_channels[i];
11904 wifi_chan_index =
11905 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
11906 no_of_channels = params->supported_channels[i+1];
11907 for(k=1; k <= no_of_channels; k++)
11908 {
11909 StaParams.supported_channels[j+1] =
11910 StaParams.supported_channels[j] + wifi_chan_index;
11911 j+=1;
11912 }
11913 }
11914 StaParams.supported_channels_len = j;
11915 }
SaidiReddy Yenuga0f1a1592017-04-05 13:18:26 +053011916 if (params->supported_oper_classes_len >
11917 SIR_MAC_MAX_SUPP_OPER_CLASSES) {
11918 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11919 "received oper classes:%d, resetting it to max supported %d",
11920 params->supported_oper_classes_len,
11921 SIR_MAC_MAX_SUPP_OPER_CLASSES);
11922 params->supported_oper_classes_len =
11923 SIR_MAC_MAX_SUPP_OPER_CLASSES;
11924 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011925 vos_mem_copy(StaParams.supported_oper_classes,
11926 params->supported_oper_classes,
11927 params->supported_oper_classes_len);
11928 StaParams.supported_oper_classes_len =
11929 params->supported_oper_classes_len;
11930
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053011931 if (params->ext_capab_len > sizeof(StaParams.extn_capability)) {
11932 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11933 "received extn capabilities:%d, resetting it to max supported",
11934 params->ext_capab_len);
11935 params->ext_capab_len = sizeof(StaParams.extn_capability);
11936 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011937 if (0 != params->ext_capab_len)
11938 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053011939 params->ext_capab_len);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011940
11941 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070011942 {
11943 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011944 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070011945 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011946
11947 StaParams.supported_rates_len = params->supported_rates_len;
11948
11949 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
11950 * The supported_rates array , for all the structures propogating till Add Sta
11951 * to the firmware has to be modified , if the supplicant (ieee80211) is
11952 * modified to send more rates.
11953 */
11954
11955 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
11956 */
11957 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
11958 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
11959
11960 if (0 != StaParams.supported_rates_len) {
11961 int i = 0;
11962 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
11963 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011964 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011965 "Supported Rates with Length %d", StaParams.supported_rates_len);
11966 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011967 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011968 "[%d]: %0x", i, StaParams.supported_rates[i]);
11969 }
11970
11971 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070011972 {
11973 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011974 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070011975 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011976
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011977 if (0 != params->ext_capab_len ) {
11978 /*Define A Macro : TODO Sunil*/
11979 if ((1<<4) & StaParams.extn_capability[3]) {
11980 isBufSta = 1;
11981 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011982 /* TDLS Channel Switching Support */
11983 if ((1<<6) & StaParams.extn_capability[3]) {
11984 isOffChannelSupported = 1;
11985 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011986 }
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011987
11988 if (pHddCtx->cfg_ini->fEnableTDLSWmmMode &&
Nitesh Shah48df4c02016-08-12 16:27:33 +053011989 (params->ht_capa || params->vht_capa ||
11990 (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME))))
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011991 /* TDLS Peer is WME/QoS capable */
11992 isQosWmmSta = TRUE;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011993
11994 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11995 "%s: TDLS Peer is QOS capable isQosWmmSta= %d HTcapPresent= %d",
11996 __func__, isQosWmmSta, StaParams.htcap_present);
11997
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011998 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
11999 &StaParams, isBufSta,
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053012000 isOffChannelSupported,
12001 isQosWmmSta);
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012002
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053012003 if (VOS_STATUS_SUCCESS != status) {
12004 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12005 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
12006 return -EINVAL;
12007 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012008 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
12009
12010 if (VOS_STATUS_SUCCESS != status) {
12011 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12012 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
12013 return -EINVAL;
12014 }
12015 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -070012016#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +053012017 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012018 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012019 return status;
12020}
12021
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012022#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
12023static int wlan_hdd_change_station(struct wiphy *wiphy,
12024 struct net_device *dev,
12025 const u8 *mac,
12026 struct station_parameters *params)
12027#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012028static int wlan_hdd_change_station(struct wiphy *wiphy,
12029 struct net_device *dev,
12030 u8 *mac,
12031 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012032#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012033{
12034 int ret;
12035
12036 vos_ssr_protect(__func__);
12037 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
12038 vos_ssr_unprotect(__func__);
12039
12040 return ret;
12041}
12042
Jeff Johnson295189b2012-06-20 16:38:30 -070012043/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012044 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -070012045 * This function is used to initialize the key information
12046 */
12047#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012048static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012049 struct net_device *ndev,
12050 u8 key_index, bool pairwise,
12051 const u8 *mac_addr,
12052 struct key_params *params
12053 )
12054#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012055static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012056 struct net_device *ndev,
12057 u8 key_index, const u8 *mac_addr,
12058 struct key_params *params
12059 )
12060#endif
12061{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012062 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070012063 tCsrRoamSetKey setKey;
12064 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012065 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012066 v_U32_t roamId= 0xFF;
12067 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070012068 hdd_hostapd_state_t *pHostapdState;
12069 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012070 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012071 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012072
12073 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012074
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012075 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12076 TRACE_CODE_HDD_CFG80211_ADD_KEY,
12077 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012078 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12079 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012080 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012081 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012082 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012083 }
12084
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012085 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12086 __func__, hdd_device_modetoString(pAdapter->device_mode),
12087 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012088
12089 if (CSR_MAX_NUM_KEY <= key_index)
12090 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012091 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012092 key_index);
12093
12094 return -EINVAL;
12095 }
12096
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012097 if (CSR_MAX_KEY_LEN < params->key_len)
12098 {
12099 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
12100 params->key_len);
12101
12102 return -EINVAL;
12103 }
12104
12105 hddLog(VOS_TRACE_LEVEL_INFO,
12106 "%s: called with key index = %d & key length %d",
12107 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070012108
12109 /*extract key idx, key len and key*/
12110 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
12111 setKey.keyId = key_index;
12112 setKey.keyLength = params->key_len;
12113 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
12114
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012115 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070012116 {
12117 case WLAN_CIPHER_SUITE_WEP40:
12118 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
12119 break;
12120
12121 case WLAN_CIPHER_SUITE_WEP104:
12122 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
12123 break;
12124
12125 case WLAN_CIPHER_SUITE_TKIP:
12126 {
12127 u8 *pKey = &setKey.Key[0];
12128 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
12129
12130 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
12131
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012132 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -070012133
12134 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012135 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070012136 |--------------|----------|----------|
12137 <---16bytes---><--8bytes--><--8bytes-->
12138
12139 */
12140 /*Sme expects the 32 bytes key to be in the below order
12141
12142 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012143 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070012144 |--------------|----------|----------|
12145 <---16bytes---><--8bytes--><--8bytes-->
12146 */
12147 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012148 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -070012149
12150 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012151 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070012152
12153 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012154 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070012155
12156
12157 break;
12158 }
12159
12160 case WLAN_CIPHER_SUITE_CCMP:
12161 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
12162 break;
12163
12164#ifdef FEATURE_WLAN_WAPI
12165 case WLAN_CIPHER_SUITE_SMS4:
12166 {
12167 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
12168 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
12169 params->key, params->key_len);
12170 return 0;
12171 }
12172#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070012173
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080012174#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070012175 case WLAN_CIPHER_SUITE_KRK:
12176 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
12177 break;
12178#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070012179
12180#ifdef WLAN_FEATURE_11W
12181 case WLAN_CIPHER_SUITE_AES_CMAC:
12182 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -070012183 break;
Chet Lanctot186b5732013-03-18 10:26:30 -070012184#endif
12185
Jeff Johnson295189b2012-06-20 16:38:30 -070012186 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012187 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070012188 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012189 status = -EOPNOTSUPP;
12190 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012191 }
12192
12193 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
12194 __func__, setKey.encType);
12195
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012196 if (
Jeff Johnson295189b2012-06-20 16:38:30 -070012197#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12198 (!pairwise)
12199#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012200 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -070012201#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012202 )
12203 {
12204 /* set group key*/
12205 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12206 "%s- %d: setting Broadcast key",
12207 __func__, __LINE__);
12208 setKey.keyDirection = eSIR_RX_ONLY;
12209 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
12210 }
12211 else
12212 {
12213 /* set pairwise key*/
12214 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12215 "%s- %d: setting pairwise key",
12216 __func__, __LINE__);
12217 setKey.keyDirection = eSIR_TX_RX;
12218 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
12219 }
12220 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
12221 {
12222 setKey.keyDirection = eSIR_TX_RX;
12223 /*Set the group key*/
12224 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
12225 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -070012226
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012227 if ( 0 != status )
12228 {
12229 hddLog(VOS_TRACE_LEVEL_ERROR,
12230 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012231 status = -EINVAL;
12232 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012233 }
12234 /*Save the keys here and call sme_RoamSetKey for setting
12235 the PTK after peer joins the IBSS network*/
12236 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
12237 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012238 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012239 }
Gopichand Nakkala29149562013-05-10 21:43:41 +053012240 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
12241 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
12242 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012243 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012244 if( pHostapdState->bssState == BSS_START )
12245 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012246 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12247 vos_status = wlan_hdd_check_ula_done(pAdapter);
12248
12249 if ( vos_status != VOS_STATUS_SUCCESS )
12250 {
12251 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12252 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
12253 __LINE__, vos_status );
12254
12255 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
12256
12257 status = -EINVAL;
12258 goto end;
12259 }
12260
Jeff Johnson295189b2012-06-20 16:38:30 -070012261 status = WLANSAP_SetKeySta( pVosContext, &setKey);
12262
12263 if ( status != eHAL_STATUS_SUCCESS )
12264 {
12265 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12266 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
12267 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012268 status = -EINVAL;
12269 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012270 }
12271 }
12272
12273 /* Saving WEP keys */
12274 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
12275 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
12276 {
12277 //Save the wep key in ap context. Issue setkey after the BSS is started.
12278 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
12279 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
12280 }
12281 else
12282 {
12283 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012284 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012285 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
12286 }
12287 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012288 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
12289 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012290 {
12291 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12292 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12293
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012294#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12295 if (!pairwise)
12296#else
12297 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
12298#endif
12299 {
12300 /* set group key*/
12301 if (pHddStaCtx->roam_info.deferKeyComplete)
12302 {
12303 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12304 "%s- %d: Perform Set key Complete",
12305 __func__, __LINE__);
12306 hdd_PerformRoamSetKeyComplete(pAdapter);
12307 }
12308 }
12309
Jeff Johnson295189b2012-06-20 16:38:30 -070012310 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
12311
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -080012312 pWextState->roamProfile.Keys.defaultIndex = key_index;
12313
12314
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012315 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070012316 params->key, params->key_len);
12317
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012318
Jeff Johnson295189b2012-06-20 16:38:30 -070012319 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
12320
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012321 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070012322 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012323 __func__, setKey.peerMac[0], setKey.peerMac[1],
12324 setKey.peerMac[2], setKey.peerMac[3],
12325 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070012326 setKey.keyDirection);
12327
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012328 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +053012329
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012330 if ( vos_status != VOS_STATUS_SUCCESS )
12331 {
12332 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012333 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
12334 __LINE__, vos_status );
12335
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012336 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012337
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012338 status = -EINVAL;
12339 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012340
12341 }
12342
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012343#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012344 /* The supplicant may attempt to set the PTK once pre-authentication
12345 is done. Save the key in the UMAC and include it in the ADD BSS
12346 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012347 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012348 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012349 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012350 hddLog(VOS_TRACE_LEVEL_INFO_MED,
12351 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012352 status = 0;
12353 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012354 }
12355 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
12356 {
12357 hddLog(VOS_TRACE_LEVEL_ERROR,
12358 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012359 status = -EINVAL;
12360 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012361 }
12362#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070012363
12364 /* issue set key request to SME*/
12365 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
12366 pAdapter->sessionId, &setKey, &roamId );
12367
12368 if ( 0 != status )
12369 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012370 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012371 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
12372 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012373 status = -EINVAL;
12374 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012375 }
12376
12377
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012378 /* in case of IBSS as there was no information available about WEP keys during
12379 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070012380 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012381 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
12382 !( ( IW_AUTH_KEY_MGMT_802_1X
12383 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070012384 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
12385 )
12386 &&
12387 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
12388 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
12389 )
12390 )
12391 {
12392 setKey.keyDirection = eSIR_RX_ONLY;
12393 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
12394
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012395 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070012396 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012397 __func__, setKey.peerMac[0], setKey.peerMac[1],
12398 setKey.peerMac[2], setKey.peerMac[3],
12399 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070012400 setKey.keyDirection);
12401
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012402 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070012403 pAdapter->sessionId, &setKey, &roamId );
12404
12405 if ( 0 != status )
12406 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012407 hddLog(VOS_TRACE_LEVEL_ERROR,
12408 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012409 __func__, status);
12410 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012411 status = -EINVAL;
12412 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012413 }
12414 }
12415 }
12416
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012417end:
12418 /* Need to clear any trace of key value in the memory.
12419 * Thus zero out the memory even though it is local
12420 * variable.
12421 */
12422 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012423 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012424 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012425}
12426
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012427#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12428static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
12429 struct net_device *ndev,
12430 u8 key_index, bool pairwise,
12431 const u8 *mac_addr,
12432 struct key_params *params
12433 )
12434#else
12435static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
12436 struct net_device *ndev,
12437 u8 key_index, const u8 *mac_addr,
12438 struct key_params *params
12439 )
12440#endif
12441{
12442 int ret;
12443 vos_ssr_protect(__func__);
12444#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12445 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
12446 mac_addr, params);
12447#else
12448 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
12449 params);
12450#endif
12451 vos_ssr_unprotect(__func__);
12452
12453 return ret;
12454}
12455
Jeff Johnson295189b2012-06-20 16:38:30 -070012456/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012457 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070012458 * This function is used to get the key information
12459 */
12460#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012461static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012462 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012463 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012464 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070012465 const u8 *mac_addr, void *cookie,
12466 void (*callback)(void *cookie, struct key_params*)
12467 )
12468#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012469static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012470 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012471 struct net_device *ndev,
12472 u8 key_index, const u8 *mac_addr, void *cookie,
12473 void (*callback)(void *cookie, struct key_params*)
12474 )
12475#endif
12476{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012477 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012478 hdd_wext_state_t *pWextState = NULL;
12479 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012480 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012481 hdd_context_t *pHddCtx;
12482 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012483
12484 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012485
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012486 if (NULL == pAdapter)
12487 {
12488 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12489 "%s: HDD adapter is Null", __func__);
12490 return -ENODEV;
12491 }
12492
12493 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12494 ret = wlan_hdd_validate_context(pHddCtx);
12495 if (0 != ret)
12496 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012497 return ret;
12498 }
12499
12500 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12501 pRoamProfile = &(pWextState->roamProfile);
12502
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012503 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12504 __func__, hdd_device_modetoString(pAdapter->device_mode),
12505 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012506
Jeff Johnson295189b2012-06-20 16:38:30 -070012507 memset(&params, 0, sizeof(params));
12508
12509 if (CSR_MAX_NUM_KEY <= key_index)
12510 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012511 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070012512 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012513 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012514
12515 switch(pRoamProfile->EncryptionType.encryptionType[0])
12516 {
12517 case eCSR_ENCRYPT_TYPE_NONE:
12518 params.cipher = IW_AUTH_CIPHER_NONE;
12519 break;
12520
12521 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
12522 case eCSR_ENCRYPT_TYPE_WEP40:
12523 params.cipher = WLAN_CIPHER_SUITE_WEP40;
12524 break;
12525
12526 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
12527 case eCSR_ENCRYPT_TYPE_WEP104:
12528 params.cipher = WLAN_CIPHER_SUITE_WEP104;
12529 break;
12530
12531 case eCSR_ENCRYPT_TYPE_TKIP:
12532 params.cipher = WLAN_CIPHER_SUITE_TKIP;
12533 break;
12534
12535 case eCSR_ENCRYPT_TYPE_AES:
12536 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
12537 break;
12538
12539 default:
12540 params.cipher = IW_AUTH_CIPHER_NONE;
12541 break;
12542 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012543
c_hpothuaaf19692014-05-17 17:01:48 +053012544 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12545 TRACE_CODE_HDD_CFG80211_GET_KEY,
12546 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012547
Jeff Johnson295189b2012-06-20 16:38:30 -070012548 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
12549 params.seq_len = 0;
12550 params.seq = NULL;
12551 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
12552 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012553 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012554 return 0;
12555}
12556
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012557#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12558static int wlan_hdd_cfg80211_get_key(
12559 struct wiphy *wiphy,
12560 struct net_device *ndev,
12561 u8 key_index, bool pairwise,
12562 const u8 *mac_addr, void *cookie,
12563 void (*callback)(void *cookie, struct key_params*)
12564 )
12565#else
12566static int wlan_hdd_cfg80211_get_key(
12567 struct wiphy *wiphy,
12568 struct net_device *ndev,
12569 u8 key_index, const u8 *mac_addr, void *cookie,
12570 void (*callback)(void *cookie, struct key_params*)
12571 )
12572#endif
12573{
12574 int ret;
12575
12576 vos_ssr_protect(__func__);
12577#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12578 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
12579 mac_addr, cookie, callback);
12580#else
12581 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
12582 callback);
12583#endif
12584 vos_ssr_unprotect(__func__);
12585
12586 return ret;
12587}
12588
Jeff Johnson295189b2012-06-20 16:38:30 -070012589/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012590 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070012591 * This function is used to delete the key information
12592 */
12593#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012594static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012595 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012596 u8 key_index,
12597 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070012598 const u8 *mac_addr
12599 )
12600#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012601static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012602 struct net_device *ndev,
12603 u8 key_index,
12604 const u8 *mac_addr
12605 )
12606#endif
12607{
12608 int status = 0;
12609
12610 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012611 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070012612 //it is observed that this is invalidating peer
12613 //key index whenever re-key is done. This is affecting data link.
12614 //It should be ok to ignore del_key.
12615#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012616 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
12617 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070012618 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
12619 tCsrRoamSetKey setKey;
12620 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012621
Jeff Johnson295189b2012-06-20 16:38:30 -070012622 ENTER();
12623
12624 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
12625 __func__,pAdapter->device_mode);
12626
12627 if (CSR_MAX_NUM_KEY <= key_index)
12628 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012629 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012630 key_index);
12631
12632 return -EINVAL;
12633 }
12634
12635 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
12636 setKey.keyId = key_index;
12637
12638 if (mac_addr)
12639 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
12640 else
12641 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
12642
12643 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
12644
12645 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012646 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012647 )
12648 {
12649
12650 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070012651 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
12652 if( pHostapdState->bssState == BSS_START)
12653 {
12654 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012655
Jeff Johnson295189b2012-06-20 16:38:30 -070012656 if ( status != eHAL_STATUS_SUCCESS )
12657 {
12658 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12659 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
12660 __LINE__, status );
12661 }
12662 }
12663 }
12664 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012665 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070012666 )
12667 {
12668 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12669
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012670 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
12671
12672 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070012673 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012674 __func__, setKey.peerMac[0], setKey.peerMac[1],
12675 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070012676 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012677 if(pAdapter->sessionCtx.station.conn_info.connState ==
12678 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070012679 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012680 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070012681 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012682
Jeff Johnson295189b2012-06-20 16:38:30 -070012683 if ( 0 != status )
12684 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012685 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012686 "%s: sme_RoamSetKey failure, returned %d",
12687 __func__, status);
12688 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
12689 return -EINVAL;
12690 }
12691 }
12692 }
12693#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070012694 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012695 return status;
12696}
12697
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012698#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12699static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
12700 struct net_device *ndev,
12701 u8 key_index,
12702 bool pairwise,
12703 const u8 *mac_addr
12704 )
12705#else
12706static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
12707 struct net_device *ndev,
12708 u8 key_index,
12709 const u8 *mac_addr
12710 )
12711#endif
12712{
12713 int ret;
12714
12715 vos_ssr_protect(__func__);
12716#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12717 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
12718 mac_addr);
12719#else
12720 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
12721#endif
12722 vos_ssr_unprotect(__func__);
12723
12724 return ret;
12725}
12726
Jeff Johnson295189b2012-06-20 16:38:30 -070012727/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012728 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070012729 * This function is used to set the default tx key index
12730 */
12731#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012732static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012733 struct net_device *ndev,
12734 u8 key_index,
12735 bool unicast, bool multicast)
12736#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012737static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012738 struct net_device *ndev,
12739 u8 key_index)
12740#endif
12741{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012742 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012743 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053012744 hdd_wext_state_t *pWextState;
12745 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012746 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012747
12748 ENTER();
12749
Gopichand Nakkala29149562013-05-10 21:43:41 +053012750 if ((NULL == pAdapter))
12751 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012752 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053012753 "invalid adapter");
12754 return -EINVAL;
12755 }
12756
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012757 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12758 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
12759 pAdapter->sessionId, key_index));
12760
Gopichand Nakkala29149562013-05-10 21:43:41 +053012761 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12762 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12763
12764 if ((NULL == pWextState) || (NULL == pHddStaCtx))
12765 {
12766 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12767 "invalid Wext state or HDD context");
12768 return -EINVAL;
12769 }
12770
Arif Hussain6d2a3322013-11-17 19:50:10 -080012771 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012772 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012773
Jeff Johnson295189b2012-06-20 16:38:30 -070012774 if (CSR_MAX_NUM_KEY <= key_index)
12775 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012776 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012777 key_index);
12778
12779 return -EINVAL;
12780 }
12781
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012782 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12783 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012784 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012785 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012786 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012787 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012788
Jeff Johnson295189b2012-06-20 16:38:30 -070012789 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070012790 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012791 )
Jeff Johnson295189b2012-06-20 16:38:30 -070012792 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053012793 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080012794 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012795 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080012796 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070012797 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012798 {
12799 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070012800 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012801
Jeff Johnson295189b2012-06-20 16:38:30 -070012802 tCsrRoamSetKey setKey;
12803 v_U32_t roamId= 0xFF;
12804 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012805
12806 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012807 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012808
Jeff Johnson295189b2012-06-20 16:38:30 -070012809 Keys->defaultIndex = (u8)key_index;
12810 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
12811 setKey.keyId = key_index;
12812 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012813
12814 vos_mem_copy(&setKey.Key[0],
12815 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070012816 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012817
Gopichand Nakkala29149562013-05-10 21:43:41 +053012818 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012819
12820 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070012821 &pHddStaCtx->conn_info.bssId[0],
12822 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012823
Gopichand Nakkala29149562013-05-10 21:43:41 +053012824 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
12825 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
12826 eCSR_ENCRYPT_TYPE_WEP104)
12827 {
12828 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
12829 even though ap is configured for WEP-40 encryption. In this canse the key length
12830 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
12831 type(104) and switching encryption type to 40*/
12832 pWextState->roamProfile.EncryptionType.encryptionType[0] =
12833 eCSR_ENCRYPT_TYPE_WEP40;
12834 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
12835 eCSR_ENCRYPT_TYPE_WEP40;
12836 }
12837
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012838 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070012839 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012840
Jeff Johnson295189b2012-06-20 16:38:30 -070012841 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012842 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070012843 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012844
Jeff Johnson295189b2012-06-20 16:38:30 -070012845 if ( 0 != status )
12846 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012847 hddLog(VOS_TRACE_LEVEL_ERROR,
12848 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012849 status);
12850 return -EINVAL;
12851 }
12852 }
12853 }
12854
12855 /* In SoftAp mode setting key direction for default mode */
12856 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
12857 {
12858 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
12859 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
12860 (eCSR_ENCRYPT_TYPE_AES !=
12861 pWextState->roamProfile.EncryptionType.encryptionType[0])
12862 )
12863 {
12864 /* Saving key direction for default key index to TX default */
12865 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
12866 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
12867 }
12868 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012869 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012870 return status;
12871}
12872
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012873#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12874static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
12875 struct net_device *ndev,
12876 u8 key_index,
12877 bool unicast, bool multicast)
12878#else
12879static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
12880 struct net_device *ndev,
12881 u8 key_index)
12882#endif
12883{
12884 int ret;
12885 vos_ssr_protect(__func__);
12886#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12887 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
12888 multicast);
12889#else
12890 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
12891#endif
12892 vos_ssr_unprotect(__func__);
12893
12894 return ret;
12895}
12896
Jeff Johnson295189b2012-06-20 16:38:30 -070012897/*
12898 * FUNCTION: wlan_hdd_cfg80211_inform_bss
12899 * This function is used to inform the BSS details to nl80211 interface.
12900 */
12901static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
12902 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
12903{
12904 struct net_device *dev = pAdapter->dev;
12905 struct wireless_dev *wdev = dev->ieee80211_ptr;
12906 struct wiphy *wiphy = wdev->wiphy;
12907 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
12908 int chan_no;
12909 int ie_length;
12910 const char *ie;
12911 unsigned int freq;
12912 struct ieee80211_channel *chan;
12913 int rssi = 0;
12914 struct cfg80211_bss *bss = NULL;
12915
Jeff Johnson295189b2012-06-20 16:38:30 -070012916 if( NULL == pBssDesc )
12917 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012918 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012919 return bss;
12920 }
12921
12922 chan_no = pBssDesc->channelId;
12923 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
12924 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
12925
12926 if( NULL == ie )
12927 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012928 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012929 return bss;
12930 }
12931
12932#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
12933 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
12934 {
12935 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
12936 }
12937 else
12938 {
12939 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
12940 }
12941#else
12942 freq = ieee80211_channel_to_frequency(chan_no);
12943#endif
12944
12945 chan = __ieee80211_get_channel(wiphy, freq);
12946
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053012947 if (!chan) {
12948 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
12949 return NULL;
12950 }
12951
Abhishek Singhaee43942014-06-16 18:55:47 +053012952 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070012953
Anand N Sunkad9f80b742015-07-30 20:05:51 +053012954 return cfg80211_inform_bss(wiphy, chan,
12955#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12956 CFG80211_BSS_FTYPE_UNKNOWN,
12957#endif
12958 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012959 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070012960 pBssDesc->capabilityInfo,
12961 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053012962 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070012963}
12964
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053012965/*
12966 * wlan_hdd_cfg80211_update_bss_list :to inform nl80211
12967 * interface that BSS might have been lost.
12968 * @pAdapter: adaptor
12969 * @bssid: bssid which might have been lost
12970 *
12971 * Return: bss which is unlinked from kernel cache
12972 */
12973struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_list(
12974 hdd_adapter_t *pAdapter, tSirMacAddr bssid)
12975{
12976 struct net_device *dev = pAdapter->dev;
12977 struct wireless_dev *wdev = dev->ieee80211_ptr;
12978 struct wiphy *wiphy = wdev->wiphy;
12979 struct cfg80211_bss *bss = NULL;
12980
Abhishek Singh5a597e62016-12-05 15:16:30 +053012981 bss = hdd_get_bss_entry(wiphy,
12982 NULL, bssid,
12983 NULL, 0);
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053012984 if (bss == NULL) {
12985 hddLog(LOGE, FL("BSS not present"));
12986 } else {
12987 hddLog(LOG1, FL("cfg80211_unlink_bss called for BSSID "
12988 MAC_ADDRESS_STR), MAC_ADDR_ARRAY(bssid));
12989 cfg80211_unlink_bss(wiphy, bss);
12990 }
12991 return bss;
12992}
Jeff Johnson295189b2012-06-20 16:38:30 -070012993
12994
12995/*
12996 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
12997 * This function is used to inform the BSS details to nl80211 interface.
12998 */
12999struct cfg80211_bss*
13000wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
13001 tSirBssDescription *bss_desc
13002 )
13003{
13004 /*
13005 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
13006 already exists in bss data base of cfg80211 for that particular BSS ID.
13007 Using cfg80211_inform_bss_frame to update the bss entry instead of
13008 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
13009 now there is no possibility to get the mgmt(probe response) frame from PE,
13010 converting bss_desc to ieee80211_mgmt(probe response) and passing to
13011 cfg80211_inform_bss_frame.
13012 */
13013 struct net_device *dev = pAdapter->dev;
13014 struct wireless_dev *wdev = dev->ieee80211_ptr;
13015 struct wiphy *wiphy = wdev->wiphy;
13016 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080013017#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
13018 qcom_ie_age *qie_age = NULL;
13019 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
13020#else
Jeff Johnson295189b2012-06-20 16:38:30 -070013021 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080013022#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013023 const char *ie =
13024 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
13025 unsigned int freq;
13026 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053013027 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013028 struct cfg80211_bss *bss_status = NULL;
13029 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
13030 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070013031 hdd_context_t *pHddCtx;
13032 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070013033#ifdef WLAN_OPEN_SOURCE
13034 struct timespec ts;
13035#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013036
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013037
Wilson Yangf80a0542013-10-07 13:02:37 -070013038 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13039 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070013040 if (0 != status)
13041 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070013042 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070013043 }
13044
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053013045 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070013046 if (!mgmt)
13047 {
13048 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13049 "%s: memory allocation failed ", __func__);
13050 return NULL;
13051 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070013052
Jeff Johnson295189b2012-06-20 16:38:30 -070013053 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070013054
13055#ifdef WLAN_OPEN_SOURCE
13056 /* Android does not want the timestamp from the frame.
13057 Instead it wants a monotonic increasing value */
13058 get_monotonic_boottime(&ts);
13059 mgmt->u.probe_resp.timestamp =
13060 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
13061#else
13062 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070013063 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
13064 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070013065
13066#endif
13067
Jeff Johnson295189b2012-06-20 16:38:30 -070013068 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
13069 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080013070
13071#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
13072 /* GPS Requirement: need age ie per entry. Using vendor specific. */
13073 /* Assuming this is the last IE, copy at the end */
13074 ie_length -=sizeof(qcom_ie_age);
13075 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
13076 qie_age->element_id = QCOM_VENDOR_IE_ID;
13077 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
13078 qie_age->oui_1 = QCOM_OUI1;
13079 qie_age->oui_2 = QCOM_OUI2;
13080 qie_age->oui_3 = QCOM_OUI3;
13081 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
Selvaraj, Sridhar4b3a8362016-10-12 12:34:08 +053013082 /* Lowi expects the timestamp of bss in units of 1/10 ms. In driver all
13083 * bss related timestamp is in units of ms. Due to this when scan results
13084 * are sent to lowi the scan age is high.To address this, send age in units
13085 * of 1/10 ms.
13086 */
13087 qie_age->age = (vos_timer_get_system_time() -
13088 bss_desc->nReceivedTime)/10;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080013089#endif
13090
Jeff Johnson295189b2012-06-20 16:38:30 -070013091 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053013092 if (bss_desc->fProbeRsp)
13093 {
13094 mgmt->frame_control |=
13095 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
13096 }
13097 else
13098 {
13099 mgmt->frame_control |=
13100 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
13101 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013102
13103#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013104 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070013105 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
13106 {
13107 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
13108 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013109 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070013110 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
13111
13112 {
13113 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
13114 }
13115 else
13116 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013117 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
13118 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070013119 kfree(mgmt);
13120 return NULL;
13121 }
13122#else
13123 freq = ieee80211_channel_to_frequency(chan_no);
13124#endif
13125 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080013126 /*when the band is changed on the fly using the GUI, three things are done
13127 * 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)
13128 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
13129 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
13130 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
13131 * and discards the channels correponding to previous band and calls back with zero bss results.
13132 * 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
13133 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
13134 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
13135 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
13136 * So drop the bss and continue to next bss.
13137 */
13138 if(chan == NULL)
13139 {
Deepthi Gowri306657b2016-04-28 17:10:41 +053013140 hddLog(VOS_TRACE_LEVEL_ERROR,
13141 FL("chan pointer is NULL, chan_no: %d freq: %d"),
13142 chan_no, freq);
Chilam Ngc4244af2013-04-01 15:37:32 -070013143 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080013144 return NULL;
13145 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053013146 /*To keep the rssi icon of the connected AP in the scan window
13147 *and the rssi icon of the wireless networks in sync
13148 * */
13149 if (( eConnectionState_Associated ==
13150 pAdapter->sessionCtx.station.conn_info.connState ) &&
13151 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
13152 pAdapter->sessionCtx.station.conn_info.bssId,
13153 WNI_CFG_BSSID_LEN)) &&
13154 (pHddCtx->hdd_wlan_suspended == FALSE))
13155 {
13156 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
13157 rssi = (pAdapter->rssi * 100);
13158 }
13159 else
13160 {
13161 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
13162 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013163
Nirav Shah20ac06f2013-12-12 18:14:06 +053013164 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053013165 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
13166 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053013167
Jeff Johnson295189b2012-06-20 16:38:30 -070013168 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
13169 frame_len, rssi, GFP_KERNEL);
13170 kfree(mgmt);
13171 return bss_status;
13172}
13173
13174/*
13175 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
13176 * This function is used to update the BSS data base of CFG8011
13177 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013178struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070013179 tCsrRoamInfo *pRoamInfo
13180 )
13181{
13182 tCsrRoamConnectedProfile roamProfile;
13183 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13184 struct cfg80211_bss *bss = NULL;
13185
13186 ENTER();
13187
13188 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
13189 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
13190
13191 if (NULL != roamProfile.pBssDesc)
13192 {
Girish Gowlif4b68022014-08-28 23:18:57 +053013193 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
13194 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070013195
13196 if (NULL == bss)
13197 {
13198 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
13199 __func__);
13200 }
13201
13202 sme_RoamFreeConnectProfile(hHal, &roamProfile);
13203 }
13204 else
13205 {
13206 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
13207 __func__);
13208 }
13209 return bss;
13210}
13211
13212/*
13213 * FUNCTION: wlan_hdd_cfg80211_update_bss
13214 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013215static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
13216 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070013217 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013218{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013219 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013220 tCsrScanResultInfo *pScanResult;
13221 eHalStatus status = 0;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013222 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013223 tScanResultHandle pResult;
13224 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070013225 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013226 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070013227 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013228
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013229 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13230 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
13231 NO_SESSION, pAdapter->sessionId));
13232
Wilson Yangf80a0542013-10-07 13:02:37 -070013233 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013234 ret = wlan_hdd_validate_context(pHddCtx);
13235 if (0 != ret)
Jeff Johnson295189b2012-06-20 16:38:30 -070013236 {
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013237 return ret;
Wilson Yangf80a0542013-10-07 13:02:37 -070013238 }
13239
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013240 if (pAdapter->request != NULL)
13241 {
13242 if ((pAdapter->request->n_ssids == 1)
13243 && (pAdapter->request->ssids != NULL)
13244 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
13245 is_p2p_scan = true;
13246 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013247 /*
13248 * start getting scan results and populate cgf80211 BSS database
13249 */
13250 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
13251
13252 /* no scan results */
13253 if (NULL == pResult)
13254 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013255 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
13256 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053013257 wlan_hdd_get_frame_logs(pAdapter,
13258 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070013259 return status;
13260 }
13261
13262 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
13263
13264 while (pScanResult)
13265 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013266 /*
13267 * cfg80211_inform_bss() is not updating ie field of bss entry, if
13268 * entry already exists in bss data base of cfg80211 for that
13269 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
13270 * bss entry instead of cfg80211_inform_bss, But this call expects
13271 * mgmt packet as input. As of now there is no possibility to get
13272 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070013273 * ieee80211_mgmt(probe response) and passing to c
13274 * fg80211_inform_bss_frame.
13275 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013276 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
13277 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
13278 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013279 pScanResult = sme_ScanResultGetNext(hHal, pResult);
13280 continue; //Skip the non p2p bss entries
13281 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013282 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
13283 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013284
Jeff Johnson295189b2012-06-20 16:38:30 -070013285
13286 if (NULL == bss_status)
13287 {
13288 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013289 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013290 }
13291 else
13292 {
Yue Maf49ba872013-08-19 12:04:25 -070013293 cfg80211_put_bss(
13294#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
13295 wiphy,
13296#endif
13297 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070013298 }
13299
13300 pScanResult = sme_ScanResultGetNext(hHal, pResult);
13301 }
13302
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013303 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013304 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013305 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013306}
13307
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013308void
13309hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
13310{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013311 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080013312 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013313} /****** end hddPrintMacAddr() ******/
13314
13315void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070013316hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013317{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013318 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013319 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070013320 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
13321 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
13322 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013323} /****** end hddPrintPmkId() ******/
13324
13325//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
13326//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
13327
13328//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
13329//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
13330
13331#define dump_bssid(bssid) \
13332 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070013333 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
13334 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013335 }
13336
13337#define dump_pmkid(pMac, pmkid) \
13338 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070013339 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
13340 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013341 }
13342
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070013343#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013344/*
13345 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
13346 * This function is used to notify the supplicant of a new PMKSA candidate.
13347 */
13348int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013349 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013350 int index, bool preauth )
13351{
Jeff Johnsone7245742012-09-05 17:12:55 -070013352#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013353 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070013354 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013355
13356 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070013357 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013358
13359 if( NULL == pRoamInfo )
13360 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013361 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013362 return -EINVAL;
13363 }
13364
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070013365 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
13366 {
13367 dump_bssid(pRoamInfo->bssid);
13368 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013369 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070013370 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013371#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013372 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013373}
13374#endif //FEATURE_WLAN_LFR
13375
Yue Maef608272013-04-08 23:09:17 -070013376#ifdef FEATURE_WLAN_LFR_METRICS
13377/*
13378 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
13379 * 802.11r/LFR metrics reporting function to report preauth initiation
13380 *
13381 */
13382#define MAX_LFR_METRICS_EVENT_LENGTH 100
13383VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
13384 tCsrRoamInfo *pRoamInfo)
13385{
13386 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
13387 union iwreq_data wrqu;
13388
13389 ENTER();
13390
13391 if (NULL == pAdapter)
13392 {
13393 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
13394 return VOS_STATUS_E_FAILURE;
13395 }
13396
13397 /* create the event */
13398 memset(&wrqu, 0, sizeof(wrqu));
13399 memset(metrics_notification, 0, sizeof(metrics_notification));
13400
13401 wrqu.data.pointer = metrics_notification;
13402 wrqu.data.length = scnprintf(metrics_notification,
13403 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
13404 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
13405
13406 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
13407
13408 EXIT();
13409
13410 return VOS_STATUS_SUCCESS;
13411}
13412
13413/*
13414 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
13415 * 802.11r/LFR metrics reporting function to report preauth completion
13416 * or failure
13417 */
13418VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
13419 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
13420{
13421 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
13422 union iwreq_data wrqu;
13423
13424 ENTER();
13425
13426 if (NULL == pAdapter)
13427 {
13428 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
13429 return VOS_STATUS_E_FAILURE;
13430 }
13431
13432 /* create the event */
13433 memset(&wrqu, 0, sizeof(wrqu));
13434 memset(metrics_notification, 0, sizeof(metrics_notification));
13435
13436 scnprintf(metrics_notification, sizeof(metrics_notification),
13437 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
13438 MAC_ADDR_ARRAY(pRoamInfo->bssid));
13439
13440 if (1 == preauth_status)
13441 strncat(metrics_notification, " TRUE", 5);
13442 else
13443 strncat(metrics_notification, " FALSE", 6);
13444
13445 wrqu.data.pointer = metrics_notification;
13446 wrqu.data.length = strlen(metrics_notification);
13447
13448 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
13449
13450 EXIT();
13451
13452 return VOS_STATUS_SUCCESS;
13453}
13454
13455/*
13456 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
13457 * 802.11r/LFR metrics reporting function to report handover initiation
13458 *
13459 */
13460VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
13461 tCsrRoamInfo *pRoamInfo)
13462{
13463 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
13464 union iwreq_data wrqu;
13465
13466 ENTER();
13467
13468 if (NULL == pAdapter)
13469 {
13470 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
13471 return VOS_STATUS_E_FAILURE;
13472 }
13473
13474 /* create the event */
13475 memset(&wrqu, 0, sizeof(wrqu));
13476 memset(metrics_notification, 0, sizeof(metrics_notification));
13477
13478 wrqu.data.pointer = metrics_notification;
13479 wrqu.data.length = scnprintf(metrics_notification,
13480 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
13481 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
13482
13483 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
13484
13485 EXIT();
13486
13487 return VOS_STATUS_SUCCESS;
13488}
13489#endif
13490
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013491
13492/**
13493 * wlan_hdd_cfg80211_validate_scan_req - validate scan request
13494 * @scan_req: scan request to be checked
13495 *
13496 * Return: true or false
13497 */
13498#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
13499static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
13500 cfg80211_scan_request
13501 *scan_req)
13502{
13503 if (!scan_req || !scan_req->wiphy) {
13504 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
13505 return false;
13506 }
13507 if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HDD, NULL)) {
13508 hddLog(VOS_TRACE_LEVEL_ERROR, "Load/Unload in progress");
13509 return false;
13510 }
13511 return true;
13512}
13513#else
13514static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
13515 cfg80211_scan_request
13516 *scan_req)
13517{
13518 if (!scan_req || !scan_req->wiphy) {
13519 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
13520 return false;
13521 }
13522 return true;
13523}
13524#endif
13525
13526
Jeff Johnson295189b2012-06-20 16:38:30 -070013527/*
13528 * FUNCTION: hdd_cfg80211_scan_done_callback
13529 * scanning callback function, called after finishing scan
13530 *
13531 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013532static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070013533 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
13534{
13535 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013536 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070013537 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013538 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070013539 struct cfg80211_scan_request *req = NULL;
13540 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053013541 bool aborted = false;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013542#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
13543 bool iface_down = false;
13544#endif
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013545 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013546 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013547 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013548
13549 ENTER();
13550
c_manjee1b4ab9a2016-10-26 11:36:55 +053013551 if (!pAdapter || pAdapter->magic != WLAN_HDD_ADAPTER_MAGIC ||
13552 !pAdapter->dev) {
13553 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Adapter is not valid"));
13554 return 0;
13555 }
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013556 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053013557 if (NULL == pHddCtx) {
13558 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013559 return 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013560 }
13561
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053013562#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
13563 if (!(pAdapter->dev->flags & IFF_UP))
13564 {
13565 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Interface is down"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013566 iface_down = true;
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053013567 }
13568#endif
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013569 pScanInfo = &pHddCtx->scan_info;
13570
Jeff Johnson295189b2012-06-20 16:38:30 -070013571 hddLog(VOS_TRACE_LEVEL_INFO,
13572 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080013573 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013574 __func__, halHandle, pContext, (int) scanId, (int) status);
13575
Kiet Lamac06e2c2013-10-23 16:25:07 +053013576 pScanInfo->mScanPendingCounter = 0;
13577
Jeff Johnson295189b2012-06-20 16:38:30 -070013578 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013579 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070013580 &pScanInfo->scan_req_completion_event,
13581 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013582 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070013583 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013584 hddLog(VOS_TRACE_LEVEL_ERROR,
13585 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070013586 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070013587 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070013588 }
13589
Yue Maef608272013-04-08 23:09:17 -070013590 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070013591 {
13592 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070013593 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070013594 }
13595
13596 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013597 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070013598 {
13599 hddLog(VOS_TRACE_LEVEL_INFO,
13600 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080013601 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070013602 (int) scanId);
13603 }
13604
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053013605#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013606 if (!iface_down)
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053013607#endif
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013608 {
13609 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
13610 pAdapter);
13611 if (0 > ret)
13612 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053013613 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013614
Jeff Johnson295189b2012-06-20 16:38:30 -070013615 /* If any client wait scan result through WEXT
13616 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013617 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070013618 {
13619 /* The other scan request waiting for current scan finish
13620 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013621 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070013622 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013623 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070013624 }
13625 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013626 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070013627 {
13628 struct net_device *dev = pAdapter->dev;
13629 union iwreq_data wrqu;
13630 int we_event;
13631 char *msg;
13632
13633 memset(&wrqu, '\0', sizeof(wrqu));
13634 we_event = SIOCGIWSCAN;
13635 msg = NULL;
13636 wireless_send_event(dev, we_event, &wrqu, msg);
13637 }
13638 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013639 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013640
13641 /* Get the Scan Req */
13642 req = pAdapter->request;
mukul sharmae7041822015-12-03 15:09:21 +053013643 pAdapter->request = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013644
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013645 /* Scan is no longer pending */
13646 pScanInfo->mScanPending = VOS_FALSE;
13647
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013648 if (!wlan_hdd_cfg80211_validate_scan_req(req))
Jeff Johnson295189b2012-06-20 16:38:30 -070013649 {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013650#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
13651 hddLog(VOS_TRACE_LEVEL_ERROR, FL("interface state %s"),
13652 iface_down ? "up" : "down");
13653#endif
13654
13655 if (pAdapter->dev) {
13656 hddLog(VOS_TRACE_LEVEL_ERROR, FL("device name %s"),
13657 pAdapter->dev->name);
13658 }
mukul sharmae7041822015-12-03 15:09:21 +053013659 complete(&pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -070013660 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070013661 }
13662
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013663 /* last_scan_timestamp is used to decide if new scan
13664 * is needed or not on station interface. If last station
13665 * scan time and new station scan time is less then
13666 * last_scan_timestamp ; driver will return cached scan.
13667 */
13668 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
13669 {
13670 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
13671
13672 if ( req->n_channels )
13673 {
13674 for (i = 0; i < req->n_channels ; i++ )
13675 {
13676 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
13677 }
13678 /* store no of channel scanned */
13679 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
13680 }
13681
13682 }
13683
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070013684 /*
13685 * cfg80211_scan_done informing NL80211 about completion
13686 * of scanning
13687 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053013688 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
13689 {
13690 aborted = true;
13691 }
mukul sharmae7041822015-12-03 15:09:21 +053013692
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013693#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
13694 if (!iface_down)
13695#endif
13696 cfg80211_scan_done(req, aborted);
mukul sharmae7041822015-12-03 15:09:21 +053013697
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080013698 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070013699
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013700allow_suspend:
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053013701 if ((pHddCtx->cfg_ini->enableMacSpoofing == MAC_ADDR_SPOOFING_FW_HOST_ENABLE
13702 ) && (pHddCtx->spoofMacAddr.isEnabled
13703 || pHddCtx->spoofMacAddr.isReqDeferred)) {
Siddharth Bhal76972212014-10-15 16:22:51 +053013704 /* Generate new random mac addr for next scan */
13705 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +053013706
13707 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
13708 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhal76972212014-10-15 16:22:51 +053013709 }
13710
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070013711 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013712 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070013713
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070013714 /* Acquire wakelock to handle the case where APP's tries to suspend
13715 * immediatly after the driver gets connect request(i.e after scan)
13716 * from supplicant, this result in app's is suspending and not able
13717 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013718 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070013719
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013720#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
13721 if (!iface_down)
13722#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070013723#ifdef FEATURE_WLAN_TDLS
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013724 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070013725#endif
13726
Jeff Johnson295189b2012-06-20 16:38:30 -070013727 EXIT();
13728 return 0;
13729}
13730
13731/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053013732 * FUNCTION: hdd_isConnectionInProgress
13733 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013734 *
13735 */
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013736v_BOOL_t hdd_isConnectionInProgress(hdd_context_t *pHddCtx, v_U8_t *session_id,
13737 scan_reject_states *reason)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013738{
13739 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
13740 hdd_station_ctx_t *pHddStaCtx = NULL;
13741 hdd_adapter_t *pAdapter = NULL;
13742 VOS_STATUS status = 0;
13743 v_U8_t staId = 0;
13744 v_U8_t *staMac = NULL;
13745
13746 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
13747
13748 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
13749 {
13750 pAdapter = pAdapterNode->pAdapter;
13751
13752 if( pAdapter )
13753 {
13754 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013755 "%s: Adapter with device mode %s (%d) exists",
13756 __func__, hdd_device_modetoString(pAdapter->device_mode),
13757 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013758 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053013759 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
13760 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
13761 (eConnectionState_Connecting ==
13762 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
13763 {
13764 hddLog(VOS_TRACE_LEVEL_ERROR,
13765 "%s: %p(%d) Connection is in progress", __func__,
13766 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013767 if (session_id && reason)
13768 {
13769 *session_id = pAdapter->sessionId;
13770 *reason = eHDD_CONNECTION_IN_PROGRESS;
13771 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053013772 return VOS_TRUE;
13773 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013774 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053013775 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013776 {
13777 hddLog(VOS_TRACE_LEVEL_ERROR,
13778 "%s: %p(%d) Reassociation is in progress", __func__,
13779 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013780 if (session_id && reason)
13781 {
13782 *session_id = pAdapter->sessionId;
13783 *reason = eHDD_REASSOC_IN_PROGRESS;
13784 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013785 return VOS_TRUE;
13786 }
13787 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013788 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
13789 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013790 {
13791 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13792 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013793 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013794 {
13795 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
13796 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080013797 "%s: client " MAC_ADDRESS_STR
13798 " is in the middle of WPS/EAPOL exchange.", __func__,
13799 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013800 if (session_id && reason)
13801 {
13802 *session_id = pAdapter->sessionId;
13803 *reason = eHDD_EAPOL_IN_PROGRESS;
13804 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053013805 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013806 }
13807 }
13808 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
13809 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
13810 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013811 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
13812 ptSapContext pSapCtx = NULL;
13813 pSapCtx = VOS_GET_SAP_CB(pVosContext);
13814 if(pSapCtx == NULL){
13815 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13816 FL("psapCtx is NULL"));
13817 return VOS_FALSE;
13818 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013819 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
13820 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013821 if ((pSapCtx->aStaInfo[staId].isUsed) &&
13822 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013823 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013824 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013825
13826 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080013827 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
13828 "middle of WPS/EAPOL exchange.", __func__,
13829 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013830 if (session_id && reason)
13831 {
13832 *session_id = pAdapter->sessionId;
13833 *reason = eHDD_SAP_EAPOL_IN_PROGRESS;
13834 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053013835 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013836 }
13837 }
13838 }
13839 }
13840 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13841 pAdapterNode = pNext;
13842 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053013843 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013844}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013845
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053013846/**
13847 * csr_scan_request_assign_bssid() - Set the BSSID received from Supplicant
13848 * to the Scan request
13849 * @scanRequest: Pointer to the csr scan request
13850 * @request: Pointer to the scan request from supplicant
13851 *
13852 * Return: None
13853 */
13854#ifdef CFG80211_SCAN_BSSID
13855static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
13856 struct cfg80211_scan_request *request)
13857{
13858 vos_mem_copy(scanRequest->bssid, request->bssid, VOS_MAC_ADDR_SIZE);
13859}
13860#else
13861static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
13862 struct cfg80211_scan_request *request)
13863{
13864}
13865#endif
13866
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013867/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013868 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070013869 * this scan respond to scan trigger and update cfg80211 scan database
13870 * later, scan dump command can be used to recieve scan results
13871 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013872int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080013873#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13874 struct net_device *dev,
13875#endif
13876 struct cfg80211_scan_request *request)
13877{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013878 hdd_adapter_t *pAdapter = NULL;
13879 hdd_context_t *pHddCtx = NULL;
13880 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013881 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013882 tCsrScanRequest scanRequest;
13883 tANI_U8 *channelList = NULL, i;
13884 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013885 int status;
13886 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013887 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013888 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053013889 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013890 bool is_p2p_scan = false;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013891 v_U8_t curr_session_id;
13892 scan_reject_states curr_reason;
Jeff Johnson295189b2012-06-20 16:38:30 -070013893
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013894#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
13895 struct net_device *dev = NULL;
13896 if (NULL == request)
13897 {
13898 hddLog(VOS_TRACE_LEVEL_ERROR,
13899 "%s: scan req param null", __func__);
13900 return -EINVAL;
13901 }
13902 dev = request->wdev->netdev;
13903#endif
13904
13905 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
13906 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
13907 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13908
Jeff Johnson295189b2012-06-20 16:38:30 -070013909 ENTER();
13910
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013911 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13912 __func__, hdd_device_modetoString(pAdapter->device_mode),
13913 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013914
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013915 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013916 if (0 != status)
13917 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013918 return status;
13919 }
13920
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013921 if (NULL == pwextBuf)
13922 {
13923 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
13924 __func__);
13925 return -EIO;
13926 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013927 cfg_param = pHddCtx->cfg_ini;
13928 pScanInfo = &pHddCtx->scan_info;
13929
Jeff Johnson295189b2012-06-20 16:38:30 -070013930#ifdef WLAN_BTAMP_FEATURE
13931 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013932 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070013933 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080013934 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013935 "%s: No scanning when AMP is on", __func__);
13936 return -EOPNOTSUPP;
13937 }
13938#endif
13939 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013940 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070013941 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013942 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013943 "%s: Not scanning on device_mode = %s (%d)",
13944 __func__, hdd_device_modetoString(pAdapter->device_mode),
13945 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013946 return -EOPNOTSUPP;
13947 }
13948
13949 if (TRUE == pScanInfo->mScanPending)
13950 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053013951 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
13952 {
13953 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
13954 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013955 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070013956 }
13957
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053013958 // Don't allow scan if PNO scan is going on.
13959 if (pHddCtx->isPnoEnable)
13960 {
13961 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13962 FL("pno scan in progress"));
13963 return -EBUSY;
13964 }
13965
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013966 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070013967 //Channel and action frame is pending
13968 //Otherwise Cancel Remain On Channel and allow Scan
13969 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013970 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070013971 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053013972 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070013973 return -EBUSY;
13974 }
13975
Jeff Johnson295189b2012-06-20 16:38:30 -070013976 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
13977 {
13978 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080013979 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013980 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013981 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013982 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
13983 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013984 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013985 "%s: MAX TM Level Scan not allowed", __func__);
13986 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013987 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070013988 }
13989 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
13990
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013991 /* Check if scan is allowed at this point of time.
13992 */
Hanumanth Reddy Pothulaec960842016-09-14 19:04:26 +053013993 if (TRUE == pHddCtx->btCoexModeSet)
13994 {
13995 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13996 FL("BTCoex Mode operation in progress"));
13997 return -EBUSY;
13998 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013999 if (hdd_isConnectionInProgress(pHddCtx, &curr_session_id, &curr_reason))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014000 {
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053014001 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Scan not allowed"));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014002 if (pHddCtx->last_scan_reject_session_id != curr_session_id ||
14003 pHddCtx->last_scan_reject_reason != curr_reason ||
14004 !pHddCtx->last_scan_reject_timestamp)
14005 {
14006 pHddCtx->last_scan_reject_session_id = curr_session_id;
14007 pHddCtx->last_scan_reject_reason = curr_reason;
Sreelakshmi Konamkif0646d52016-12-09 12:35:31 +053014008 pHddCtx->last_scan_reject_timestamp = jiffies_to_msecs(jiffies);
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053014009 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014010 else {
Sreelakshmi Konamkif0646d52016-12-09 12:35:31 +053014011 if ((jiffies_to_msecs(jiffies) -
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014012 pHddCtx->last_scan_reject_timestamp) >=
14013 SCAN_REJECT_THRESHOLD_TIME)
14014 {
14015 pHddCtx->last_scan_reject_timestamp = 0;
14016 if (pHddCtx->cfg_ini->enableFatalEvent)
14017 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
14018 WLAN_LOG_INDICATOR_HOST_DRIVER,
14019 WLAN_LOG_REASON_SCAN_NOT_ALLOWED,
14020 FALSE, FALSE);
14021 else
14022 {
14023 hddLog(LOGE, FL("Triggering SSR"));
14024 vos_wlanRestart();
14025 }
14026 }
14027 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014028 return -EBUSY;
14029 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014030 pHddCtx->last_scan_reject_timestamp = 0;
14031 pHddCtx->last_scan_reject_session_id = 0xFF;
14032 pHddCtx->last_scan_reject_reason = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014033
Jeff Johnson295189b2012-06-20 16:38:30 -070014034 vos_mem_zero( &scanRequest, sizeof(scanRequest));
14035
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014036 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
14037 * Becasue of this, driver is assuming that this is not wildcard scan and so
14038 * is not aging out the scan results.
14039 */
14040 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070014041 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014042 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014043 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014044
14045 if ((request->ssids) && (0 < request->n_ssids))
14046 {
14047 tCsrSSIDInfo *SsidInfo;
14048 int j;
14049 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
14050 /* Allocate num_ssid tCsrSSIDInfo structure */
14051 SsidInfo = scanRequest.SSIDs.SSIDList =
14052 ( tCsrSSIDInfo *)vos_mem_malloc(
14053 request->n_ssids*sizeof(tCsrSSIDInfo));
14054
14055 if(NULL == scanRequest.SSIDs.SSIDList)
14056 {
14057 hddLog(VOS_TRACE_LEVEL_ERROR,
14058 "%s: memory alloc failed SSIDInfo buffer", __func__);
14059 return -ENOMEM;
14060 }
14061
14062 /* copy all the ssid's and their length */
14063 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
14064 {
14065 /* get the ssid length */
14066 SsidInfo->SSID.length = request->ssids[j].ssid_len;
14067 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
14068 SsidInfo->SSID.length);
14069 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
14070 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
14071 j, SsidInfo->SSID.ssId);
14072 }
14073 /* set the scan type to active */
14074 scanRequest.scanType = eSIR_ACTIVE_SCAN;
14075 }
14076 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070014077 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053014078 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14079 TRACE_CODE_HDD_CFG80211_SCAN,
14080 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070014081 /* set the scan type to active */
14082 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070014083 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014084 else
14085 {
14086 /*Set the scan type to default type, in this case it is ACTIVE*/
14087 scanRequest.scanType = pScanInfo->scan_mode;
14088 }
14089 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
14090 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070014091
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053014092 csr_scan_request_assign_bssid(&scanRequest, request);
14093
Jeff Johnson295189b2012-06-20 16:38:30 -070014094 /* set BSSType to default type */
14095 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
14096
14097 /*TODO: scan the requested channels only*/
14098
14099 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014100 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070014101 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014102 hddLog(VOS_TRACE_LEVEL_WARN,
14103 "No of Scan Channels exceeded limit: %d", request->n_channels);
14104 request->n_channels = MAX_CHANNEL;
14105 }
14106
14107 hddLog(VOS_TRACE_LEVEL_INFO,
14108 "No of Scan Channels: %d", request->n_channels);
14109
14110
14111 if( request->n_channels )
14112 {
14113 char chList [(request->n_channels*5)+1];
14114 int len;
14115 channelList = vos_mem_malloc( request->n_channels );
14116 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053014117 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014118 hddLog(VOS_TRACE_LEVEL_ERROR,
14119 "%s: memory alloc failed channelList", __func__);
14120 status = -ENOMEM;
14121 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053014122 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014123
14124 for( i = 0, len = 0; i < request->n_channels ; i++ )
14125 {
14126 channelList[i] = request->channels[i]->hw_value;
14127 len += snprintf(chList+len, 5, "%d ", channelList[i]);
14128 }
14129
Nirav Shah20ac06f2013-12-12 18:14:06 +053014130 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014131 "Channel-List: %s ", chList);
14132 }
c_hpothu53512302014-04-15 18:49:53 +053014133
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014134 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
14135 scanRequest.ChannelInfo.ChannelList = channelList;
14136
14137 /* set requestType to full scan */
14138 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
14139
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014140 /* if there is back to back scan happening in driver with in
14141 * nDeferScanTimeInterval interval driver should defer new scan request
14142 * and should provide last cached scan results instead of new channel list.
14143 * This rule is not applicable if scan is p2p scan.
14144 * This condition will work only in case when last request no of channels
14145 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053014146 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053014147 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014148 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014149
Sushant Kaushik86592172015-04-27 16:35:03 +053014150 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
14151 /* if wps ie is NULL , then only defer scan */
14152 if ( pWpsIe == NULL &&
14153 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053014154 {
14155 if ( pScanInfo->last_scan_timestamp !=0 &&
14156 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
14157 {
14158 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
14159 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
14160 vos_mem_compare(pScanInfo->last_scan_channelList,
14161 channelList, pScanInfo->last_scan_numChannels))
14162 {
14163 hddLog(VOS_TRACE_LEVEL_WARN,
14164 " New and old station scan time differ is less then %u",
14165 pHddCtx->cfg_ini->nDeferScanTimeInterval);
14166
14167 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014168 pAdapter);
14169
Agarwal Ashish57e84372014-12-05 18:26:53 +053014170 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053014171 "Return old cached scan as all channels and no of channels are same");
14172
Agarwal Ashish57e84372014-12-05 18:26:53 +053014173 if (0 > ret)
14174 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014175
Agarwal Ashish57e84372014-12-05 18:26:53 +053014176 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053014177
14178 status = eHAL_STATUS_SUCCESS;
14179 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053014180 }
14181 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014182 }
14183
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014184 /* Flush the scan results(only p2p beacons) for STA scan and P2P
14185 * search (Flush on both full scan and social scan but not on single
14186 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
14187 */
14188
14189 /* Supplicant does single channel scan after 8-way handshake
14190 * and in that case driver shoudnt flush scan results. If
14191 * driver flushes the scan results here and unfortunately if
14192 * the AP doesnt respond to our probe req then association
14193 * fails which is not desired
14194 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053014195 if ((request->n_ssids == 1)
14196 && (request->ssids != NULL)
14197 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
14198 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014199
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053014200 if( is_p2p_scan ||
14201 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014202 {
14203 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
14204 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
14205 pAdapter->sessionId );
14206 }
14207
14208 if( request->ie_len )
14209 {
14210 /* save this for future association (join requires this) */
14211 /*TODO: Array needs to be converted to dynamic allocation,
14212 * as multiple ie.s can be sent in cfg80211_scan_request structure
14213 * CR 597966
14214 */
14215 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
14216 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
14217 pScanInfo->scanAddIE.length = request->ie_len;
14218
14219 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
14220 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
14221 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070014222 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014223 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070014224 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014225 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
14226 memcpy( pwextBuf->roamProfile.addIEScan,
14227 request->ie, request->ie_len);
14228 }
14229 else
14230 {
14231 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
14232 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070014233 }
14234
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014235 }
14236 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
14237 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
14238
14239 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
14240 request->ie_len);
14241 if (pP2pIe != NULL)
14242 {
14243#ifdef WLAN_FEATURE_P2P_DEBUG
14244 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
14245 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
14246 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053014247 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014248 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
14249 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
14250 "Go nego completed to Connection is started");
14251 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
14252 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053014253 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014254 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
14255 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070014256 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014257 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
14258 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
14259 "Disconnected state to Connection is started");
14260 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
14261 "for 4way Handshake");
14262 }
14263#endif
14264
14265 /* no_cck will be set during p2p find to disable 11b rates */
14266 if(TRUE == request->no_cck)
14267 {
14268 hddLog(VOS_TRACE_LEVEL_INFO,
14269 "%s: This is a P2P Search", __func__);
14270 scanRequest.p2pSearch = 1;
14271
14272 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053014273 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014274 /* set requestType to P2P Discovery */
14275 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
14276 }
14277
14278 /*
14279 Skip Dfs Channel in case of P2P Search
14280 if it is set in ini file
14281 */
14282 if(cfg_param->skipDfsChnlInP2pSearch)
14283 {
14284 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053014285 }
14286 else
14287 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014288 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053014289 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014290
Agarwal Ashish4f616132013-12-30 23:32:50 +053014291 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014292 }
14293 }
14294
14295 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
14296
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014297#ifdef FEATURE_WLAN_TDLS
14298 /* if tdls disagree scan right now, return immediately.
14299 tdls will schedule the scan when scan is allowed. (return SUCCESS)
14300 or will reject the scan if any TDLS is in progress. (return -EBUSY)
14301 */
14302 status = wlan_hdd_tdls_scan_callback (pAdapter,
14303 wiphy,
14304#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
14305 dev,
14306#endif
14307 request);
Abhishek Singhe2b63952016-01-05 18:27:29 +053014308 if (status <= 0)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014309 {
Abhishek Singhe2b63952016-01-05 18:27:29 +053014310 if (!status)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014311 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
14312 "scan rejected %d", __func__, status);
14313 else
14314 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
14315 __func__, status);
Abhishek Singhe2b63952016-01-05 18:27:29 +053014316 hdd_wlan_block_scan_by_tdls();
Gupta, Kapil2ebf3e02016-03-17 19:45:19 +053014317 goto free_mem;
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014318 }
14319#endif
14320
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070014321 /* acquire the wakelock to avoid the apps suspend during the scan. To
14322 * address the following issues.
14323 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
14324 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
14325 * for long time, this result in apps running at full power for long time.
14326 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
14327 * be stuck in full power because of resume BMPS
14328 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014329 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070014330
Nirav Shah20ac06f2013-12-12 18:14:06 +053014331 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
14332 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014333 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
14334 scanRequest.requestType, scanRequest.scanType,
14335 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053014336 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
14337
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053014338 if (pHddCtx->spoofMacAddr.isEnabled &&
14339 pHddCtx->cfg_ini->enableMacSpoofing == 1)
Siddharth Bhal76972212014-10-15 16:22:51 +053014340 {
14341 hddLog(VOS_TRACE_LEVEL_INFO,
14342 "%s: MAC Spoofing enabled for current scan", __func__);
14343 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
14344 * to fill TxBds for probe request during current scan
14345 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053014346 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053014347 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053014348
14349 if(status != VOS_STATUS_SUCCESS)
14350 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014351 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053014352 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053014353#ifdef FEATURE_WLAN_TDLS
14354 wlan_hdd_tdls_scan_done_callback(pAdapter);
14355#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053014356 goto free_mem;
14357 }
Siddharth Bhal76972212014-10-15 16:22:51 +053014358 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053014359 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070014360 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070014361 pAdapter->sessionId, &scanRequest, &scanId,
14362 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070014363
Jeff Johnson295189b2012-06-20 16:38:30 -070014364 if (eHAL_STATUS_SUCCESS != status)
14365 {
14366 hddLog(VOS_TRACE_LEVEL_ERROR,
14367 "%s: sme_ScanRequest returned error %d", __func__, status);
14368 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070014369 if(eHAL_STATUS_RESOURCES == status)
14370 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014371 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
14372 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070014373 status = -EBUSY;
14374 } else {
14375 status = -EIO;
14376 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014377 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014378
14379#ifdef FEATURE_WLAN_TDLS
14380 wlan_hdd_tdls_scan_done_callback(pAdapter);
14381#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014382 goto free_mem;
14383 }
14384
14385 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053014386 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070014387 pAdapter->request = request;
14388 pScanInfo->scanId = scanId;
14389
14390 complete(&pScanInfo->scan_req_completion_event);
14391
14392free_mem:
14393 if( scanRequest.SSIDs.SSIDList )
14394 {
14395 vos_mem_free(scanRequest.SSIDs.SSIDList);
14396 }
14397
14398 if( channelList )
14399 vos_mem_free( channelList );
14400
14401 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014402 return status;
14403}
14404
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014405int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
14406#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
14407 struct net_device *dev,
14408#endif
14409 struct cfg80211_scan_request *request)
14410{
14411 int ret;
14412
14413 vos_ssr_protect(__func__);
14414 ret = __wlan_hdd_cfg80211_scan(wiphy,
14415#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
14416 dev,
14417#endif
14418 request);
14419 vos_ssr_unprotect(__func__);
14420
14421 return ret;
14422}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014423
14424void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
14425{
14426 v_U8_t iniDot11Mode =
14427 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
14428 eHddDot11Mode hddDot11Mode = iniDot11Mode;
14429
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014430 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
14431 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014432 switch ( iniDot11Mode )
14433 {
14434 case eHDD_DOT11_MODE_AUTO:
14435 case eHDD_DOT11_MODE_11ac:
14436 case eHDD_DOT11_MODE_11ac_ONLY:
14437#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053014438 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
14439 sme_IsFeatureSupportedByFW(DOT11AC) )
14440 hddDot11Mode = eHDD_DOT11_MODE_11ac;
14441 else
14442 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014443#else
14444 hddDot11Mode = eHDD_DOT11_MODE_11n;
14445#endif
14446 break;
14447 case eHDD_DOT11_MODE_11n:
14448 case eHDD_DOT11_MODE_11n_ONLY:
14449 hddDot11Mode = eHDD_DOT11_MODE_11n;
14450 break;
14451 default:
14452 hddDot11Mode = iniDot11Mode;
14453 break;
14454 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053014455#ifdef WLAN_FEATURE_AP_HT40_24G
14456 if (operationChannel > SIR_11B_CHANNEL_END)
14457#endif
14458 {
14459 /* This call decides required channel bonding mode */
14460 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014461 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
14462 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053014463 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014464}
14465
Jeff Johnson295189b2012-06-20 16:38:30 -070014466/*
14467 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014468 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070014469 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014470int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053014471 const u8 *ssid, size_t ssid_len, const u8 *bssid,
14472 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070014473{
14474 int status = 0;
14475 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080014476 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014477 v_U32_t roamId;
14478 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070014479 eCsrAuthType RSNAuthType;
14480
14481 ENTER();
14482
14483 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080014484 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14485
14486 status = wlan_hdd_validate_context(pHddCtx);
14487 if (status)
14488 {
Yue Mae36e3552014-03-05 17:06:20 -080014489 return status;
14490 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014491
Jeff Johnson295189b2012-06-20 16:38:30 -070014492 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
14493 {
14494 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
14495 return -EINVAL;
14496 }
14497
Nitesh Shah9b066282017-06-06 18:05:52 +053014498 wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
14499
Jeff Johnson295189b2012-06-20 16:38:30 -070014500 pRoamProfile = &pWextState->roamProfile;
14501
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014502 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070014503 {
Jeff Johnsone7245742012-09-05 17:12:55 -070014504 hdd_station_ctx_t *pHddStaCtx;
14505 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Abhishek Singh6782c9e2017-06-06 13:37:45 +053014506 pHddStaCtx->get_mgmt_log_sent = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014507
Siddharth Bhalda0d1622015-04-24 15:47:49 +053014508 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
14509
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014510 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070014511 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
14512 {
14513 /*QoS not enabled in cfg file*/
14514 pRoamProfile->uapsd_mask = 0;
14515 }
14516 else
14517 {
14518 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014519 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070014520 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
14521 }
14522
14523 pRoamProfile->SSIDs.numOfSSIDs = 1;
14524 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
14525 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014526 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070014527 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
14528 ssid, ssid_len);
14529
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014530 vos_mem_zero(pRoamProfile->BSSIDs.bssid, WNI_CFG_BSSID_LEN);
14531 vos_mem_zero(pRoamProfile->bssid_hint, WNI_CFG_BSSID_LEN);
14532
Jeff Johnson295189b2012-06-20 16:38:30 -070014533 if (bssid)
14534 {
14535 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014536 vos_mem_copy(pRoamProfile->BSSIDs.bssid, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070014537 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014538 /* Save BSSID in seperate variable as well, as RoamProfile
14539 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070014540 case of join failure we should send valid BSSID to supplicant
14541 */
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014542 vos_mem_copy(pWextState->req_bssId, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070014543 WNI_CFG_BSSID_LEN);
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014544
Jeff Johnson295189b2012-06-20 16:38:30 -070014545 }
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014546 else if (bssid_hint)
Dhanashri Atre51981c62013-06-13 11:47:57 -070014547 {
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014548 /* Store bssid_hint to use in the scan filter. */
14549 vos_mem_copy(pRoamProfile->bssid_hint, bssid_hint,
14550 WNI_CFG_BSSID_LEN);
14551 /*
14552 * Save BSSID in seperate variable as well, as RoamProfile
14553 * BSSID is getting zeroed out in the association process. And in
14554 * case of join failure we should send valid BSSID to supplicant
14555 */
14556 vos_mem_copy(pWextState->req_bssId, bssid_hint,
14557 WNI_CFG_BSSID_LEN);
14558 hddLog(LOG1, FL(" bssid_hint: "MAC_ADDRESS_STR),
14559 MAC_ADDR_ARRAY(pRoamProfile->bssid_hint));
Dhanashri Atre51981c62013-06-13 11:47:57 -070014560 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014561
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014562
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014563 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
14564 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070014565 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
14566 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014567 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014568 /*set gen ie*/
14569 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
14570 /*set auth*/
14571 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
14572 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014573#ifdef FEATURE_WLAN_WAPI
14574 if (pAdapter->wapi_info.nWapiMode)
14575 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014576 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014577 switch (pAdapter->wapi_info.wapiAuthMode)
14578 {
14579 case WAPI_AUTH_MODE_PSK:
14580 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014581 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014582 pAdapter->wapi_info.wapiAuthMode);
14583 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
14584 break;
14585 }
14586 case WAPI_AUTH_MODE_CERT:
14587 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014588 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014589 pAdapter->wapi_info.wapiAuthMode);
14590 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
14591 break;
14592 }
14593 } // End of switch
14594 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
14595 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
14596 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014597 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014598 pRoamProfile->AuthType.numEntries = 1;
14599 pRoamProfile->EncryptionType.numEntries = 1;
14600 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
14601 pRoamProfile->mcEncryptionType.numEntries = 1;
14602 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
14603 }
14604 }
14605#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014606#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014607 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014608 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
14609 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
14610 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014611 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
14612 sizeof (tSirGtkOffloadParams));
14613 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014614 }
14615#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014616 pRoamProfile->csrPersona = pAdapter->device_mode;
14617
Jeff Johnson32d95a32012-09-10 13:15:23 -070014618 if( operatingChannel )
14619 {
14620 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
14621 pRoamProfile->ChannelInfo.numOfChannels = 1;
14622 }
Chet Lanctot186b5732013-03-18 10:26:30 -070014623 else
14624 {
14625 pRoamProfile->ChannelInfo.ChannelList = NULL;
14626 pRoamProfile->ChannelInfo.numOfChannels = 0;
14627 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014628 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
14629 {
14630 hdd_select_cbmode(pAdapter,operatingChannel);
14631 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014632
Agarwal Ashish40f9b872015-09-01 16:17:35 +053014633 /*
14634 * Change conn_state to connecting before sme_RoamConnect(),
14635 * because sme_RoamConnect() has a direct path to call
14636 * hdd_smeRoamCallback(), which will change the conn_state
14637 * If direct path, conn_state will be accordingly changed
14638 * to NotConnected or Associated by either
14639 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
14640 * in sme_RoamCallback()
14641 * if sme_RomConnect is to be queued,
14642 * Connecting state will remain until it is completed.
14643 * If connection state is not changed,
14644 * connection state will remain in eConnectionState_NotConnected state.
14645 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
14646 * if conn state is eConnectionState_NotConnected.
14647 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
14648 * informed of connect result indication which is an issue.
14649 */
14650
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053014651 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
14652 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053014653 {
14654 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053014655 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080014656 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
14657 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053014658 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014659 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070014660 pAdapter->sessionId, pRoamProfile, &roamId);
14661
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053014662 if ((eHAL_STATUS_SUCCESS != status) &&
14663 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
14664 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053014665
14666 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053014667 hddLog(VOS_TRACE_LEVEL_ERROR,
14668 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
14669 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080014670 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053014671 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080014672 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053014673 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080014674
14675 pRoamProfile->ChannelInfo.ChannelList = NULL;
14676 pRoamProfile->ChannelInfo.numOfChannels = 0;
14677
Jeff Johnson295189b2012-06-20 16:38:30 -070014678 }
14679 else
14680 {
14681 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
14682 return -EINVAL;
14683 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080014684 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014685 return status;
14686}
14687
14688/*
14689 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
14690 * This function is used to set the authentication type (OPEN/SHARED).
14691 *
14692 */
14693static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
14694 enum nl80211_auth_type auth_type)
14695{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014696 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014697 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14698
14699 ENTER();
14700
14701 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014702 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070014703 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014704 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053014705 hddLog(VOS_TRACE_LEVEL_INFO,
14706 "%s: set authentication type to AUTOSWITCH", __func__);
14707 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
14708 break;
14709
14710 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014711#ifdef WLAN_FEATURE_VOWIFI_11R
14712 case NL80211_AUTHTYPE_FT:
14713#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014714 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070014715 "%s: set authentication type to OPEN", __func__);
14716 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
14717 break;
14718
14719 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014720 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070014721 "%s: set authentication type to SHARED", __func__);
14722 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
14723 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080014724#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070014725 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014726 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070014727 "%s: set authentication type to CCKM WPA", __func__);
14728 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
14729 break;
14730#endif
14731
14732
14733 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014734 hddLog(VOS_TRACE_LEVEL_ERROR,
14735 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014736 auth_type);
14737 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
14738 return -EINVAL;
14739 }
14740
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014741 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070014742 pHddStaCtx->conn_info.authType;
14743 return 0;
14744}
14745
14746/*
14747 * FUNCTION: wlan_hdd_set_akm_suite
14748 * This function is used to set the key mgmt type(PSK/8021x).
14749 *
14750 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014751static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014752 u32 key_mgmt
14753 )
14754{
14755 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
14756 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053014757 /* Should be in ieee802_11_defs.h */
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053014758#ifndef WLAN_AKM_SUITE_8021X_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053014759#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053014760#endif
14761#ifndef WLAN_AKM_SUITE_PSK_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053014762#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053014763#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014764 /*set key mgmt type*/
14765 switch(key_mgmt)
14766 {
14767 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053014768 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053014769#ifdef WLAN_FEATURE_VOWIFI_11R
14770 case WLAN_AKM_SUITE_FT_PSK:
14771#endif
14772 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070014773 __func__);
14774 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
14775 break;
14776
14777 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053014778 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053014779#ifdef WLAN_FEATURE_VOWIFI_11R
14780 case WLAN_AKM_SUITE_FT_8021X:
14781#endif
14782 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070014783 __func__);
14784 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
14785 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080014786#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070014787#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
14788#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
14789 case WLAN_AKM_SUITE_CCKM:
14790 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
14791 __func__);
14792 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
14793 break;
14794#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070014795#ifndef WLAN_AKM_SUITE_OSEN
14796#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
14797 case WLAN_AKM_SUITE_OSEN:
14798 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
14799 __func__);
14800 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
14801 break;
14802#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014803
14804 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014805 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014806 __func__, key_mgmt);
14807 return -EINVAL;
14808
14809 }
14810 return 0;
14811}
14812
14813/*
14814 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014815 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070014816 * (NONE/WEP40/WEP104/TKIP/CCMP).
14817 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014818static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
14819 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070014820 bool ucast
14821 )
14822{
14823 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014824 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014825 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14826
14827 ENTER();
14828
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014829 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070014830 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053014831 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070014832 __func__, cipher);
14833 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
14834 }
14835 else
14836 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014837
Jeff Johnson295189b2012-06-20 16:38:30 -070014838 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014839 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070014840 {
14841 case IW_AUTH_CIPHER_NONE:
14842 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
14843 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014844
Jeff Johnson295189b2012-06-20 16:38:30 -070014845 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053014846 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070014847 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014848
Jeff Johnson295189b2012-06-20 16:38:30 -070014849 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053014850 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070014851 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014852
Jeff Johnson295189b2012-06-20 16:38:30 -070014853 case WLAN_CIPHER_SUITE_TKIP:
14854 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
14855 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014856
Jeff Johnson295189b2012-06-20 16:38:30 -070014857 case WLAN_CIPHER_SUITE_CCMP:
14858 encryptionType = eCSR_ENCRYPT_TYPE_AES;
14859 break;
14860#ifdef FEATURE_WLAN_WAPI
14861 case WLAN_CIPHER_SUITE_SMS4:
14862 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
14863 break;
14864#endif
14865
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080014866#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070014867 case WLAN_CIPHER_SUITE_KRK:
14868 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
14869 break;
14870#endif
14871 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014872 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014873 __func__, cipher);
14874 return -EOPNOTSUPP;
14875 }
14876 }
14877
14878 if (ucast)
14879 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014880 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014881 __func__, encryptionType);
14882 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
14883 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014884 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070014885 encryptionType;
14886 }
14887 else
14888 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014889 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014890 __func__, encryptionType);
14891 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
14892 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
14893 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
14894 }
14895
14896 return 0;
14897}
14898
14899
14900/*
14901 * FUNCTION: wlan_hdd_cfg80211_set_ie
14902 * This function is used to parse WPA/RSN IE's.
14903 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014904int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014905#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14906 const u8 *ie,
14907#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014908 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014909#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014910 size_t ie_len
14911 )
14912{
14913 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014914#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14915 const u8 *genie = ie;
14916#else
Jeff Johnson295189b2012-06-20 16:38:30 -070014917 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014918#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014919 v_U16_t remLen = ie_len;
14920#ifdef FEATURE_WLAN_WAPI
14921 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
14922 u16 *tmp;
14923 v_U16_t akmsuiteCount;
14924 int *akmlist;
14925#endif
14926 ENTER();
14927
14928 /* clear previous assocAddIE */
14929 pWextState->assocAddIE.length = 0;
14930 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070014931 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014932
14933 while (remLen >= 2)
14934 {
14935 v_U16_t eLen = 0;
14936 v_U8_t elementId;
14937 elementId = *genie++;
14938 eLen = *genie++;
14939 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014940
Nachiket Kukade4aba5f02017-06-09 15:43:48 +053014941 /* Sanity check on eLen */
14942 if (eLen > remLen) {
14943 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid IE length[%d] for IE[0x%X]",
14944 __func__, eLen, elementId);
14945 VOS_ASSERT(0);
14946 return -EINVAL;
14947 }
14948
Arif Hussain6d2a3322013-11-17 19:50:10 -080014949 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070014950 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014951
14952 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070014953 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014954 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014955 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 -070014956 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014957 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014958 "%s: Invalid WPA IE", __func__);
14959 return -EINVAL;
14960 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014961 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070014962 {
14963 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014964 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070014965 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014966
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014967 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070014968 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014969 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
14970 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070014971 VOS_ASSERT(0);
14972 return -ENOMEM;
14973 }
14974 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
14975 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14976 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014977
Jeff Johnson295189b2012-06-20 16:38:30 -070014978 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
14979 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14980 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14981 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014982 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
14983 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014984 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
14985 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
14986 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
14987 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
14988 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
14989 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014990 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053014991 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070014992 {
14993 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014994 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070014995 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014996
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014997 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070014998 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014999 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15000 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070015001 VOS_ASSERT(0);
15002 return -ENOMEM;
15003 }
15004 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
15005 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15006 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015007
Jeff Johnson295189b2012-06-20 16:38:30 -070015008 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15009 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15010 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015011#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015012 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
15013 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015014 /*Consider WFD IE, only for P2P Client */
15015 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
15016 {
15017 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015018 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070015019 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015020
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015021 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015022 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015023 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15024 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070015025 VOS_ASSERT(0);
15026 return -ENOMEM;
15027 }
15028 // WFD IE is saved to Additional IE ; it should be accumulated to handle
15029 // WPS IE + P2P IE + WFD IE
15030 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15031 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015032
Jeff Johnson295189b2012-06-20 16:38:30 -070015033 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15034 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15035 }
15036#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015037 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015038 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015039 HS20_OUI_TYPE_SIZE)) )
15040 {
15041 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015042 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015043 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015044
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015045 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015046 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015047 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15048 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015049 VOS_ASSERT(0);
15050 return -ENOMEM;
15051 }
15052 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15053 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015054
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015055 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15056 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15057 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070015058 /* Appending OSEN Information Element in Assiciation Request */
15059 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
15060 OSEN_OUI_TYPE_SIZE)) )
15061 {
15062 v_U16_t curAddIELen = pWextState->assocAddIE.length;
15063 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
15064 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015065
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015066 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070015067 {
15068 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15069 "Need bigger buffer space");
15070 VOS_ASSERT(0);
15071 return -ENOMEM;
15072 }
15073 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15074 pWextState->assocAddIE.length += eLen + 2;
15075
15076 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
15077 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15078 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15079 }
15080
Abhishek Singh4322e622015-06-10 15:42:54 +053015081 /* Update only for WPA IE */
15082 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
15083 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070015084
15085 /* populating as ADDIE in beacon frames */
15086 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015087 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070015088 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
15089 {
15090 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
15091 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
15092 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
15093 {
15094 hddLog(LOGE,
15095 "Coldn't pass "
15096 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
15097 }
15098 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
15099 else
15100 hddLog(LOGE,
15101 "Could not pass on "
15102 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
15103
15104 /* IBSS mode doesn't contain params->proberesp_ies still
15105 beaconIE's need to be populated in probe response frames */
15106 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
15107 {
15108 u16 rem_probe_resp_ie_len = eLen + 2;
15109 u8 probe_rsp_ie_len[3] = {0};
15110 u8 counter = 0;
15111
15112 /* Check Probe Resp Length if it is greater then 255 then
15113 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
15114 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
15115 not able Store More then 255 bytes into One Variable */
15116
15117 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
15118 {
15119 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
15120 {
15121 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
15122 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
15123 }
15124 else
15125 {
15126 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
15127 rem_probe_resp_ie_len = 0;
15128 }
15129 }
15130
15131 rem_probe_resp_ie_len = 0;
15132
15133 if (probe_rsp_ie_len[0] > 0)
15134 {
15135 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
15136 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
15137 (tANI_U8*)(genie - 2),
15138 probe_rsp_ie_len[0], NULL,
15139 eANI_BOOLEAN_FALSE)
15140 == eHAL_STATUS_FAILURE)
15141 {
15142 hddLog(LOGE,
15143 "Could not pass"
15144 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
15145 }
15146 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
15147 }
15148
15149 if (probe_rsp_ie_len[1] > 0)
15150 {
15151 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
15152 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
15153 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
15154 probe_rsp_ie_len[1], NULL,
15155 eANI_BOOLEAN_FALSE)
15156 == eHAL_STATUS_FAILURE)
15157 {
15158 hddLog(LOGE,
15159 "Could not pass"
15160 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
15161 }
15162 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
15163 }
15164
15165 if (probe_rsp_ie_len[2] > 0)
15166 {
15167 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
15168 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
15169 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
15170 probe_rsp_ie_len[2], NULL,
15171 eANI_BOOLEAN_FALSE)
15172 == eHAL_STATUS_FAILURE)
15173 {
15174 hddLog(LOGE,
15175 "Could not pass"
15176 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
15177 }
15178 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
15179 }
15180
15181 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
15182 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
15183 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
15184 {
15185 hddLog(LOGE,
15186 "Could not pass"
15187 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
15188 }
15189 }
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070015190 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070015191 break;
15192 case DOT11F_EID_RSN:
15193 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
15194 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
15195 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
15196 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
15197 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
15198 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053015199
Abhishek Singhb16f3562016-01-20 11:08:32 +053015200 /* Appending extended capabilities with Interworking or
15201 * bsstransition bit set in Assoc Req.
Abhishek Singh15d95602015-03-24 15:52:57 +053015202 *
15203 * In assoc req this EXT Cap will only be taken into account if
Abhishek Singhb16f3562016-01-20 11:08:32 +053015204 * interworkingService or bsstransition bit is set to 1.
15205 * Driver is only interested in interworkingService and
15206 * bsstransition capability from supplicant.
15207 * If in future any other EXT Cap info is
Abhishek Singh15d95602015-03-24 15:52:57 +053015208 * required from supplicat, it needs to be handled while
15209 * sending Assoc Req in LIM.
15210 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015211 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015212 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015213 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015214 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015215 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015216
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015217 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015218 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015219 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15220 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015221 VOS_ASSERT(0);
15222 return -ENOMEM;
15223 }
15224 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15225 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015226
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015227 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15228 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15229 break;
15230 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015231#ifdef FEATURE_WLAN_WAPI
15232 case WLAN_EID_WAPI:
15233 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070015234 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070015235 pAdapter->wapi_info.nWapiMode);
15236 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015237 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070015238 akmsuiteCount = WPA_GET_LE16(tmp);
15239 tmp = tmp + 1;
15240 akmlist = (int *)(tmp);
15241 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
15242 {
15243 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
15244 }
15245 else
15246 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015247 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070015248 VOS_ASSERT(0);
15249 return -EINVAL;
15250 }
15251
15252 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
15253 {
15254 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015255 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015256 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015257 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015258 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015259 {
Jeff Johnson295189b2012-06-20 16:38:30 -070015260 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015261 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015262 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
15263 }
15264 break;
15265#endif
15266 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015267 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015268 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015269 /* when Unknown IE is received we should break and continue
15270 * to the next IE in the buffer instead we were returning
15271 * so changing this to break */
15272 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070015273 }
15274 genie += eLen;
15275 remLen -= eLen;
15276 }
15277 EXIT();
15278 return 0;
15279}
15280
15281/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053015282 * FUNCTION: hdd_isWPAIEPresent
15283 * Parse the received IE to find the WPA IE
15284 *
15285 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015286static bool hdd_isWPAIEPresent(
15287#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
15288 const u8 *ie,
15289#else
15290 u8 *ie,
15291#endif
15292 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053015293{
15294 v_U8_t eLen = 0;
15295 v_U16_t remLen = ie_len;
15296 v_U8_t elementId = 0;
15297
15298 while (remLen >= 2)
15299 {
15300 elementId = *ie++;
15301 eLen = *ie++;
15302 remLen -= 2;
15303 if (eLen > remLen)
15304 {
15305 hddLog(VOS_TRACE_LEVEL_ERROR,
15306 "%s: IE length is wrong %d", __func__, eLen);
15307 return FALSE;
15308 }
15309 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
15310 {
15311 /* OUI - 0x00 0X50 0XF2
15312 WPA Information Element - 0x01
15313 WPA version - 0x01*/
15314 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
15315 return TRUE;
15316 }
15317 ie += eLen;
15318 remLen -= eLen;
15319 }
15320 return FALSE;
15321}
15322
15323/*
Jeff Johnson295189b2012-06-20 16:38:30 -070015324 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015325 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070015326 * parameters during connect operation.
15327 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015328int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070015329 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015330 )
Jeff Johnson295189b2012-06-20 16:38:30 -070015331{
15332 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015333 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070015334 ENTER();
15335
15336 /*set wpa version*/
15337 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
15338
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015339 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070015340 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053015341 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070015342 {
15343 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
15344 }
15345 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
15346 {
15347 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
15348 }
15349 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015350
15351 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015352 pWextState->wpaVersion);
15353
15354 /*set authentication type*/
15355 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
15356
15357 if (0 > status)
15358 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015359 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015360 "%s: failed to set authentication type ", __func__);
15361 return status;
15362 }
15363
15364 /*set key mgmt type*/
15365 if (req->crypto.n_akm_suites)
15366 {
15367 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
15368 if (0 > status)
15369 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015370 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070015371 __func__);
15372 return status;
15373 }
15374 }
15375
15376 /*set pairwise cipher type*/
15377 if (req->crypto.n_ciphers_pairwise)
15378 {
15379 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
15380 req->crypto.ciphers_pairwise[0], true);
15381 if (0 > status)
15382 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015383 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015384 "%s: failed to set unicast cipher type", __func__);
15385 return status;
15386 }
15387 }
15388 else
15389 {
15390 /*Reset previous cipher suite to none*/
15391 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
15392 if (0 > status)
15393 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015394 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015395 "%s: failed to set unicast cipher type", __func__);
15396 return status;
15397 }
15398 }
15399
15400 /*set group cipher type*/
15401 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
15402 false);
15403
15404 if (0 > status)
15405 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015406 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070015407 __func__);
15408 return status;
15409 }
15410
Chet Lanctot186b5732013-03-18 10:26:30 -070015411#ifdef WLAN_FEATURE_11W
15412 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
15413#endif
15414
Jeff Johnson295189b2012-06-20 16:38:30 -070015415 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
15416 if (req->ie_len)
15417 {
15418 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
15419 if ( 0 > status)
15420 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015421 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070015422 __func__);
15423 return status;
15424 }
15425 }
15426
15427 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015428 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070015429 {
15430 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
15431 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
15432 )
15433 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015434 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070015435 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
15436 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015437 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070015438 __func__);
15439 return -EOPNOTSUPP;
15440 }
15441 else
15442 {
15443 u8 key_len = req->key_len;
15444 u8 key_idx = req->key_idx;
15445
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015446 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070015447 && (CSR_MAX_NUM_KEY > key_idx)
15448 )
15449 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015450 hddLog(VOS_TRACE_LEVEL_INFO,
15451 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015452 __func__, key_idx, key_len);
15453 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015454 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070015455 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015456 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070015457 (u8)key_len;
15458 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
15459 }
15460 }
15461 }
15462 }
15463
15464 return status;
15465}
15466
15467/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015468 * FUNCTION: wlan_hdd_try_disconnect
15469 * This function is used to disconnect from previous
15470 * connection
15471 */
Agrawal Ashishc407f192017-01-23 17:18:35 +053015472int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015473{
15474 long ret = 0;
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015475 int status, result = 0;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015476 hdd_station_ctx_t *pHddStaCtx;
15477 eMib_dot11DesiredBssType connectedBssType;
Abhishek Singh19a7dd92015-12-30 16:31:51 +053015478 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015479
Abhishek Singh19a7dd92015-12-30 16:31:51 +053015480 ret = wlan_hdd_validate_context(pHddCtx);
15481 if (0 != ret)
15482 {
15483 return ret;
15484 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015485 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15486
15487 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
15488
15489 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
15490 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
Abhishek Singh630ff592016-01-07 18:15:53 +053015491 (eConnectionState_Connecting == pHddStaCtx->conn_info.connState) ||
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015492 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
15493 {
Abhishek Singh9f4df782017-03-15 17:29:10 +053015494 /* Indicate disconnect to SME so that in-progress connection or preauth
15495 * can be aborted
15496 */
15497 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
15498 pAdapter->sessionId);
Abhishek Singh19a7dd92015-12-30 16:31:51 +053015499 spin_lock_bh(&pAdapter->lock_for_active_session);
15500 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
15501 {
15502 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
15503 }
15504 spin_unlock_bh(&pAdapter->lock_for_active_session);
Abhishek Singhf7962582015-10-23 10:54:06 +053015505 hdd_connSetConnectionState(pHddStaCtx,
15506 eConnectionState_Disconnecting);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015507 /* Issue disconnect to CSR */
15508 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015509 status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015510 pAdapter->sessionId,
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015511 eCSR_DISCONNECT_REASON_UNSPECIFIED);
15512 if(eHAL_STATUS_CMD_NOT_QUEUED == status) {
15513 hddLog(LOG1,
15514 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
15515 } else if ( 0 != status ) {
15516 hddLog(LOGE,
15517 FL("csrRoamDisconnect failure, returned %d"),
15518 (int)status );
15519 result = -EINVAL;
15520 goto disconnected;
15521 }
15522 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015523 &pAdapter->disconnect_comp_var,
15524 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015525 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status)) {
15526 hddLog(LOGE,
15527 "%s: Failed to disconnect, timed out", __func__);
15528 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015529 }
15530 }
15531 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
15532 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015533 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015534 &pAdapter->disconnect_comp_var,
15535 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015536 if (!ret)
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015537 {
15538 hddLog(LOGE, FL("Failed to receive disconnect event"));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015539 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015540 }
15541 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015542disconnected:
15543 hddLog(LOG1,
15544 FL("Set HDD connState to eConnectionState_NotConnected"));
15545 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
15546 return result;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015547}
15548
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053015549/**
15550 * wlan_hdd_reassoc_bssid_hint() - Start reassociation if bssid is present
15551 * @adapter: Pointer to the HDD adapter
15552 * @req: Pointer to the structure cfg_connect_params receieved from user space
15553 *
15554 * This function will start reassociation if bssid hint, channel hint and
15555 * previous bssid parameters are present in the connect request
15556 *
15557 * Return: success if reassociation is happening
15558 * Error code if reassociation is not permitted or not happening
15559 */
15560#ifdef CFG80211_CONNECT_PREV_BSSID
15561static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
15562 struct cfg80211_connect_params *req)
15563{
15564 int status = -EPERM;
15565 if (req->bssid_hint && req->channel_hint && req->prev_bssid) {
15566 hddLog(VOS_TRACE_LEVEL_INFO,
15567 FL("REASSOC Attempt on channel %d to "MAC_ADDRESS_STR),
15568 req->channel_hint->hw_value,
15569 MAC_ADDR_ARRAY(req->bssid_hint));
15570 status = hdd_reassoc(adapter, req->bssid_hint,
15571 req->channel_hint->hw_value,
15572 CONNECT_CMD_USERSPACE);
15573 }
15574 return status;
15575}
15576#else
15577static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
15578 struct cfg80211_connect_params *req)
15579{
15580 return -EPERM;
15581}
15582#endif
15583
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015584/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053015585 * FUNCTION: __wlan_hdd_cfg80211_connect
15586 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070015587 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015588static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015589 struct net_device *ndev,
15590 struct cfg80211_connect_params *req
15591 )
15592{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015593 int status;
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053015594 u16 channel;
Edhar, Mahesh Kumar496c7f72016-03-18 12:47:44 +053015595#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) || \
15596 defined(CFG80211_BSSID_HINT_BACKPORT)
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053015597 const u8 *bssid_hint = req->bssid_hint;
15598#else
15599 const u8 *bssid_hint = NULL;
15600#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015601 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070015602 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053015603 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015604
15605 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015606
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015607 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15608 TRACE_CODE_HDD_CFG80211_CONNECT,
15609 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015610 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015611 "%s: device_mode = %s (%d)", __func__,
15612 hdd_device_modetoString(pAdapter->device_mode),
15613 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015614
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015615 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080015616 if (!pHddCtx)
15617 {
15618 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15619 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053015620 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080015621 }
15622
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015623 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015624 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070015625 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015626 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015627 }
15628
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053015629 status = wlan_hdd_reassoc_bssid_hint(pAdapter, req);
15630 if (0 == status)
15631 return status;
15632
Agarwal Ashish51325b52014-06-16 16:50:49 +053015633
Jeff Johnson295189b2012-06-20 16:38:30 -070015634#ifdef WLAN_BTAMP_FEATURE
15635 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015636 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070015637 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015638 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015639 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080015640 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070015641 }
15642#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015643
15644 //If Device Mode is Station Concurrent Sessions Exit BMps
15645 //P2P Mode will be taken care in Open/close adapter
15646 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053015647 (vos_concurrent_open_sessions_running())) {
15648 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
15649 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015650 }
15651
15652 /*Try disconnecting if already in connected state*/
15653 status = wlan_hdd_try_disconnect(pAdapter);
15654 if ( 0 > status)
15655 {
15656 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
15657 " connection"));
15658 return -EALREADY;
15659 }
Agrawal Ashish559530c2015-12-01 18:04:20 +053015660 /* Check for max concurrent connections after doing disconnect if any*/
15661 if (vos_max_concurrent_connections_reached()) {
15662 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
15663 return -ECONNREFUSED;
15664 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015665
Jeff Johnson295189b2012-06-20 16:38:30 -070015666 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015667 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070015668
15669 if ( 0 > status)
15670 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015671 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070015672 __func__);
15673 return status;
15674 }
Sravan Kumar Kairam589c5722016-01-27 20:28:53 +053015675
15676 if (pHddCtx->spoofMacAddr.isEnabled)
15677 {
15678 hddLog(VOS_TRACE_LEVEL_INFO,
15679 "%s: MAC Spoofing enabled ", __func__);
15680 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
15681 * to fill TxBds for probe request during SSID scan which may happen
15682 * as part of connect command
15683 */
15684 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
15685 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
15686 if (status != VOS_STATUS_SUCCESS)
15687 return -ECONNREFUSED;
15688 }
15689
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053015690 if (req->channel)
15691 channel = req->channel->hw_value;
Mohit Khanna765234a2012-09-11 15:08:35 -070015692 else
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053015693 channel = 0;
Kapil Gupta312028a2016-10-25 14:15:20 +053015694
15695 /* Abort if any scan is going on */
15696 status = wlan_hdd_scan_abort(pAdapter);
15697 if (0 != status)
15698 hddLog(VOS_TRACE_LEVEL_ERROR, FL("scan abort failed"));
15699
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053015700 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
15701 req->ssid_len, req->bssid,
15702 bssid_hint, channel);
Jeff Johnson295189b2012-06-20 16:38:30 -070015703
Sushant Kaushikd7083982015-03-18 14:33:24 +053015704 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070015705 {
15706 //ReEnable BMPS if disabled
15707 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
15708 (NULL != pHddCtx))
15709 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053015710 if (pHddCtx->hdd_wlan_suspended)
15711 {
15712 hdd_set_pwrparams(pHddCtx);
15713 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015714 //ReEnable Bmps and Imps back
15715 hdd_enable_bmps_imps(pHddCtx);
15716 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053015717 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070015718 return status;
15719 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015720 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015721 EXIT();
15722 return status;
15723}
15724
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015725static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
15726 struct net_device *ndev,
15727 struct cfg80211_connect_params *req)
15728{
15729 int ret;
15730 vos_ssr_protect(__func__);
15731 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
15732 vos_ssr_unprotect(__func__);
15733
15734 return ret;
15735}
Jeff Johnson295189b2012-06-20 16:38:30 -070015736
15737/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015738 * FUNCTION: wlan_hdd_disconnect
15739 * This function is used to issue a disconnect request to SME
15740 */
15741int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
15742{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015743 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015744 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015745 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053015746 long ret;
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053015747 eConnectionState prev_conn_state;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015748
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015749 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015750
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015751 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015752 if (0 != status)
15753 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015754 return status;
15755 }
Abhishek Singh07e4a892015-11-23 11:29:57 +053015756 /* Indicate sme of disconnect so that in progress connection or preauth
15757 * can be aborted
15758 */
15759 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
Sushant Kaushikb4834d22015-07-15 15:29:05 +053015760 pAdapter->sessionId);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015761 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053015762
Agarwal Ashish47d18112014-08-04 19:55:07 +053015763 /* Need to apply spin lock before decreasing active sessions
15764 * as there can be chance for double decrement if context switch
15765 * Calls hdd_DisConnectHandler.
15766 */
15767
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053015768 prev_conn_state = pHddStaCtx->conn_info.connState;
15769
Agarwal Ashish47d18112014-08-04 19:55:07 +053015770 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053015771 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
15772 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053015773 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
15774 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053015775 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
15776 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053015777
Abhishek Singhf4669da2014-05-26 15:07:49 +053015778 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053015779 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
15780
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015781 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015782
Mihir Shete182a0b22014-08-18 16:08:48 +053015783 /*
15784 * stop tx queues before deleting STA/BSS context from the firmware.
15785 * tx has to be disabled because the firmware can get busy dropping
15786 * the tx frames after BSS/STA has been deleted and will not send
15787 * back a response resulting in WDI timeout
15788 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053015789 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053015790 netif_tx_disable(pAdapter->dev);
15791 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015792
Mihir Shete182a0b22014-08-18 16:08:48 +053015793 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015794 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
15795 pAdapter->sessionId, reason);
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053015796 if((eHAL_STATUS_CMD_NOT_QUEUED == status) &&
15797 prev_conn_state != eConnectionState_Connecting)
15798 {
15799 hddLog(LOG1,
15800 FL("status = %d, already disconnected"), status);
15801 result = 0;
15802 goto disconnected;
15803 }
15804 /*
15805 * Wait here instead of returning directly, this will block the next
15806 * connect command and allow processing of the scan for ssid and
15807 * the previous connect command in CSR. Else we might hit some
15808 * race conditions leading to SME and HDD out of sync.
15809 */
15810 else if(eHAL_STATUS_CMD_NOT_QUEUED == status)
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015811 {
15812 hddLog(LOG1,
15813 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053015814 }
15815 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015816 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015817 hddLog(LOGE,
15818 FL("csrRoamDisconnect failure, returned %d"),
15819 (int)status);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015820 result = -EINVAL;
15821 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015822 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015823 ret = wait_for_completion_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015824 &pAdapter->disconnect_comp_var,
15825 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015826 if (!ret && (eHAL_STATUS_CMD_NOT_QUEUED != status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015827 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015828 hddLog(LOGE,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053015829 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015830 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053015831 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015832disconnected:
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015833 hddLog(LOG1,
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053015834 FL("Set HDD connState to eConnectionState_NotConnected"));
15835 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Mahesh A Saptasagar936ffc32016-05-25 11:27:43 +053015836#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
15837 /* Sending disconnect event to userspace for kernel version < 3.11
15838 * is handled by __cfg80211_disconnect call to __cfg80211_disconnected
15839 */
15840 hddLog(LOG1, FL("Send disconnected event to userspace"));
15841
Mahesh A Saptasagarf5859b12016-06-01 17:17:50 +053015842 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, true,
Mahesh A Saptasagar936ffc32016-05-25 11:27:43 +053015843 WLAN_REASON_UNSPECIFIED);
15844#endif
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053015845
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015846 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015847 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015848}
15849
15850
15851/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015852 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070015853 * This function is used to issue a disconnect request to SME
15854 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015855static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015856 struct net_device *dev,
15857 u16 reason
15858 )
15859{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015860 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015861 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053015862 tCsrRoamProfile *pRoamProfile;
15863 hdd_station_ctx_t *pHddStaCtx;
15864 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015865#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015866 tANI_U8 staIdx;
15867#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015868
Jeff Johnson295189b2012-06-20 16:38:30 -070015869 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015870
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053015871 if (!pAdapter) {
15872 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
15873 return -EINVAL;
15874 }
15875
15876 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15877 if (!pHddStaCtx) {
15878 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
15879 return -EINVAL;
15880 }
15881
15882 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15883 status = wlan_hdd_validate_context(pHddCtx);
15884 if (0 != status)
15885 {
15886 return status;
15887 }
15888
15889 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
15890
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015891 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15892 TRACE_CODE_HDD_CFG80211_DISCONNECT,
15893 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015894 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
15895 __func__, hdd_device_modetoString(pAdapter->device_mode),
15896 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015897
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015898 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
15899 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070015900
Jeff Johnson295189b2012-06-20 16:38:30 -070015901 if (NULL != pRoamProfile)
15902 {
15903 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053015904 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
15905 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070015906 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015907 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070015908 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015909 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070015910 switch(reason)
15911 {
15912 case WLAN_REASON_MIC_FAILURE:
15913 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
15914 break;
15915
15916 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
15917 case WLAN_REASON_DISASSOC_AP_BUSY:
15918 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
15919 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
15920 break;
15921
15922 case WLAN_REASON_PREV_AUTH_NOT_VALID:
15923 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053015924 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070015925 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
15926 break;
15927
Jeff Johnson295189b2012-06-20 16:38:30 -070015928 default:
15929 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
15930 break;
15931 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015932 pScanInfo = &pHddCtx->scan_info;
15933 if (pScanInfo->mScanPending)
15934 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053015935 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015936 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053015937 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053015938 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015939 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053015940 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015941#ifdef FEATURE_WLAN_TDLS
15942 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080015943 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015944 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080015945 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
15946 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015947 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015948 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080015949 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015950 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015951 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080015952 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015953 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015954 status = sme_DeleteTdlsPeerSta(
15955 WLAN_HDD_GET_HAL_CTX(pAdapter),
15956 pAdapter->sessionId,
15957 mac);
15958 if (status != eHAL_STATUS_SUCCESS) {
15959 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
15960 return -EPERM;
15961 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015962 }
15963 }
15964#endif
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053015965
15966 hddLog(LOG1, FL("Disconnecting with reasoncode:%u connState %d"),
15967 reasonCode,
15968 pHddStaCtx->conn_info.connState);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015969 status = wlan_hdd_disconnect(pAdapter, reasonCode);
15970 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070015971 {
15972 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080015973 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015974 __func__, (int)status );
15975 return -EINVAL;
15976 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015977 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053015978 else
15979 {
15980 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
15981 "called while in %d state", __func__,
15982 pHddStaCtx->conn_info.connState);
15983 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015984 }
15985 else
15986 {
15987 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
15988 }
15989
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015990 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015991 return status;
15992}
15993
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015994static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
15995 struct net_device *dev,
15996 u16 reason
15997 )
15998{
15999 int ret;
16000 vos_ssr_protect(__func__);
16001 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
16002 vos_ssr_unprotect(__func__);
16003
16004 return ret;
16005}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016006
Jeff Johnson295189b2012-06-20 16:38:30 -070016007/*
16008 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016009 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070016010 * settings in IBSS mode.
16011 */
16012static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016013 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070016014 struct cfg80211_ibss_params *params
16015 )
16016{
16017 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016018 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016019 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
16020 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016021
Jeff Johnson295189b2012-06-20 16:38:30 -070016022 ENTER();
16023
16024 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070016025 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070016026
16027 if (params->ie_len && ( NULL != params->ie) )
16028 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016029 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
16030 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070016031 {
16032 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
16033 encryptionType = eCSR_ENCRYPT_TYPE_AES;
16034 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016035 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070016036 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070016037 tDot11fIEWPA dot11WPAIE;
16038 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016039 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070016040
Wilson Yang00256342013-10-10 23:13:38 -070016041 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016042 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
16043 params->ie_len, DOT11F_EID_WPA);
16044 if ( NULL != ie )
16045 {
16046 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
16047 // Unpack the WPA IE
16048 //Skip past the EID byte and length byte - and four byte WiFi OUI
16049 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
16050 &ie[2+4],
16051 ie[1] - 4,
16052 &dot11WPAIE);
16053 /*Extract the multicast cipher, the encType for unicast
16054 cipher for wpa-none is none*/
16055 encryptionType =
16056 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
16057 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016058 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016059
Jeff Johnson295189b2012-06-20 16:38:30 -070016060 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
16061
16062 if (0 > status)
16063 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016064 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070016065 __func__);
16066 return status;
16067 }
16068 }
16069
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016070 pWextState->roamProfile.AuthType.authType[0] =
16071 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070016072 eCSR_AUTH_TYPE_OPEN_SYSTEM;
16073
16074 if (params->privacy)
16075 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016076 /* Security enabled IBSS, At this time there is no information available
16077 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070016078 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016079 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070016080 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016081 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070016082 *enable privacy bit in beacons */
16083
16084 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
16085 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070016086 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
16087 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070016088 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
16089 pWextState->roamProfile.EncryptionType.numEntries = 1;
16090 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070016091 return status;
16092}
16093
16094/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016095 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016096 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070016097 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016098static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016099 struct net_device *dev,
16100 struct cfg80211_ibss_params *params
16101 )
16102{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016103 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070016104 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
16105 tCsrRoamProfile *pRoamProfile;
16106 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016107 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16108 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016109 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070016110
16111 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016112
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016113 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16114 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
16115 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016116 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016117 "%s: device_mode = %s (%d)", __func__,
16118 hdd_device_modetoString(pAdapter->device_mode),
16119 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070016120
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016121 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016122 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070016123 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016124 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016125 }
16126
16127 if (NULL == pWextState)
16128 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016129 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070016130 __func__);
16131 return -EIO;
16132 }
16133
Agarwal Ashish51325b52014-06-16 16:50:49 +053016134 if (vos_max_concurrent_connections_reached()) {
16135 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
16136 return -ECONNREFUSED;
16137 }
16138
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016139 /*Try disconnecting if already in connected state*/
16140 status = wlan_hdd_try_disconnect(pAdapter);
16141 if ( 0 > status)
16142 {
16143 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
16144 " IBSS connection"));
16145 return -EALREADY;
16146 }
16147
Jeff Johnson295189b2012-06-20 16:38:30 -070016148 pRoamProfile = &pWextState->roamProfile;
16149
16150 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
16151 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016152 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080016153 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016154 return -EINVAL;
16155 }
16156
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070016157 /* BSSID is provided by upper layers hence no need to AUTO generate */
16158 if (NULL != params->bssid) {
16159 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
16160 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
16161 hddLog (VOS_TRACE_LEVEL_ERROR,
16162 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
16163 return -EIO;
16164 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016165 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070016166 }
krunal sonie9002db2013-11-25 14:24:17 -080016167 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
16168 {
16169 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
16170 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
16171 {
16172 hddLog (VOS_TRACE_LEVEL_ERROR,
16173 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
16174 return -EIO;
16175 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016176
16177 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080016178 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016179 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080016180 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070016181
Jeff Johnson295189b2012-06-20 16:38:30 -070016182 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070016183 if (NULL !=
16184#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
16185 params->chandef.chan)
16186#else
16187 params->channel)
16188#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016189 {
16190 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016191 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
16192 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
16193 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
16194 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070016195
16196 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016197 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070016198 ieee80211_frequency_to_channel(
16199#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
16200 params->chandef.chan->center_freq);
16201#else
16202 params->channel->center_freq);
16203#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016204
16205 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
16206 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070016207 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016208 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
16209 __func__);
16210 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070016211 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016212
16213 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070016214 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016215 if (channelNum == validChan[indx])
16216 {
16217 break;
16218 }
16219 }
16220 if (indx >= numChans)
16221 {
16222 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016223 __func__, channelNum);
16224 return -EINVAL;
16225 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016226 /* Set the Operational Channel */
16227 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
16228 channelNum);
16229 pRoamProfile->ChannelInfo.numOfChannels = 1;
16230 pHddStaCtx->conn_info.operationChannel = channelNum;
16231 pRoamProfile->ChannelInfo.ChannelList =
16232 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070016233 }
16234
16235 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016236 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070016237 if (status < 0)
16238 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016239 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070016240 __func__);
16241 return status;
16242 }
16243
16244 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016245 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Abhishek Singh4d924682015-11-17 15:23:06 +053016246 params->ssid_len, (const u8 *)&bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016247 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070016248
16249 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070016250 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016251
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016252 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016253 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016254}
16255
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016256static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
16257 struct net_device *dev,
16258 struct cfg80211_ibss_params *params
16259 )
16260{
16261 int ret = 0;
16262
16263 vos_ssr_protect(__func__);
16264 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
16265 vos_ssr_unprotect(__func__);
16266
16267 return ret;
16268}
16269
Jeff Johnson295189b2012-06-20 16:38:30 -070016270/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016271 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016272 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070016273 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016274static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016275 struct net_device *dev
16276 )
16277{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016278 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016279 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
16280 tCsrRoamProfile *pRoamProfile;
16281 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016282 int status;
Abhishek Singh69de3302016-11-11 16:44:32 +053016283 eHalStatus hal_status;
Abhishek Singh7cd040e2016-01-07 10:51:04 +053016284#ifdef WLAN_FEATURE_RMC
16285 tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN] = {0};
16286#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016287
16288 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016289
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016290 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16291 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
16292 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016293 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016294 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016295 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016296 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016297 }
16298
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016299 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
16300 hdd_device_modetoString(pAdapter->device_mode),
16301 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070016302 if (NULL == pWextState)
16303 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016304 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070016305 __func__);
16306 return -EIO;
16307 }
16308
16309 pRoamProfile = &pWextState->roamProfile;
16310
16311 /* Issue disconnect only if interface type is set to IBSS */
16312 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
16313 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016314 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070016315 __func__);
16316 return -EINVAL;
16317 }
16318
Abhishek Singh7cd040e2016-01-07 10:51:04 +053016319#ifdef WLAN_FEATURE_RMC
16320 /* Clearing add IE of beacon */
16321 if (ccmCfgSetStr(pHddCtx->hHal,
16322 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0],
16323 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN,
16324 NULL, eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
16325 {
16326 hddLog (VOS_TRACE_LEVEL_ERROR,
16327 "%s: unable to clear PROBE_RSP_BCN_ADDNIE_DATA", __func__);
16328 return -EINVAL;
16329 }
16330 if (ccmCfgSetInt(pHddCtx->hHal,
16331 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0, NULL,
16332 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
16333 {
16334 hddLog (VOS_TRACE_LEVEL_ERROR,
16335 "%s: unable to clear WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
16336 __func__);
16337 return -EINVAL;
16338 }
16339
16340 // Reset WNI_CFG_PROBE_RSP Flags
16341 wlan_hdd_reset_prob_rspies(pAdapter);
16342
16343 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
16344 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 0,NULL,
16345 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
16346 {
16347 hddLog (VOS_TRACE_LEVEL_ERROR,
16348 "%s: unable to clear WNI_CFG_PROBE_RSP_ADDNIE_FLAG",
16349 __func__);
16350 return -EINVAL;
16351 }
16352#endif
16353
Jeff Johnson295189b2012-06-20 16:38:30 -070016354 /* Issue Disconnect request */
16355 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singh69de3302016-11-11 16:44:32 +053016356 hal_status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
16357 pAdapter->sessionId,
16358 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
16359 if (!HAL_STATUS_SUCCESS(hal_status)) {
16360 hddLog(LOGE,
16361 FL("sme_RoamDisconnect failed hal_status(%d)"),
16362 hal_status);
16363 return -EAGAIN;
16364 }
16365 status = wait_for_completion_timeout(
16366 &pAdapter->disconnect_comp_var,
16367 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
16368 if (!status) {
16369 hddLog(LOGE,
16370 FL("wait on disconnect_comp_var failed"));
16371 return -ETIMEDOUT;
16372 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016373
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016374 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016375 return 0;
16376}
16377
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016378static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
16379 struct net_device *dev
16380 )
16381{
16382 int ret = 0;
16383
16384 vos_ssr_protect(__func__);
16385 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
16386 vos_ssr_unprotect(__func__);
16387
16388 return ret;
16389}
16390
Jeff Johnson295189b2012-06-20 16:38:30 -070016391/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016392 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070016393 * This function is used to set the phy parameters
16394 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
16395 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016396static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016397 u32 changed)
16398{
16399 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
16400 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016401 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016402
16403 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016404
16405 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016406 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
16407 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016408
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016409 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016410 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016411 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016412 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016413 }
16414
Jeff Johnson295189b2012-06-20 16:38:30 -070016415 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
16416 {
16417 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
16418 WNI_CFG_RTS_THRESHOLD_STAMAX :
16419 wiphy->rts_threshold;
16420
16421 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016422 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070016423 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016424 hddLog(VOS_TRACE_LEVEL_ERROR,
16425 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016426 __func__, rts_threshold);
16427 return -EINVAL;
16428 }
16429
16430 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
16431 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016432 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016433 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016434 hddLog(VOS_TRACE_LEVEL_ERROR,
16435 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016436 __func__, rts_threshold);
16437 return -EIO;
16438 }
16439
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016440 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016441 rts_threshold);
16442 }
16443
16444 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
16445 {
16446 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
16447 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
16448 wiphy->frag_threshold;
16449
16450 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016451 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016452 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016453 hddLog(VOS_TRACE_LEVEL_ERROR,
16454 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016455 frag_threshold);
16456 return -EINVAL;
16457 }
16458
16459 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
16460 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016461 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016462 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016463 hddLog(VOS_TRACE_LEVEL_ERROR,
16464 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016465 __func__, frag_threshold);
16466 return -EIO;
16467 }
16468
16469 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
16470 frag_threshold);
16471 }
16472
16473 if ((changed & WIPHY_PARAM_RETRY_SHORT)
16474 || (changed & WIPHY_PARAM_RETRY_LONG))
16475 {
16476 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
16477 wiphy->retry_short :
16478 wiphy->retry_long;
16479
16480 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
16481 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
16482 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016483 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016484 __func__, retry_value);
16485 return -EINVAL;
16486 }
16487
16488 if (changed & WIPHY_PARAM_RETRY_SHORT)
16489 {
16490 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
16491 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016492 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016493 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016494 hddLog(VOS_TRACE_LEVEL_ERROR,
16495 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016496 __func__, retry_value);
16497 return -EIO;
16498 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016499 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016500 __func__, retry_value);
16501 }
16502 else if (changed & WIPHY_PARAM_RETRY_SHORT)
16503 {
16504 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
16505 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016506 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016507 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016508 hddLog(VOS_TRACE_LEVEL_ERROR,
16509 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016510 __func__, retry_value);
16511 return -EIO;
16512 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016513 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016514 __func__, retry_value);
16515 }
16516 }
16517
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016518 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016519 return 0;
16520}
16521
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016522static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
16523 u32 changed)
16524{
16525 int ret;
16526
16527 vos_ssr_protect(__func__);
16528 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
16529 vos_ssr_unprotect(__func__);
16530
16531 return ret;
16532}
16533
Jeff Johnson295189b2012-06-20 16:38:30 -070016534/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016535 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070016536 * This function is used to set the txpower
16537 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016538static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070016539#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16540 struct wireless_dev *wdev,
16541#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016542#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016543 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070016544#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016545 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070016546#endif
16547 int dbm)
16548{
16549 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016550 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070016551 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
16552 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016553 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016554
16555 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016556
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016557 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16558 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
16559 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016560 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016561 if (0 != status)
16562 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016563 return status;
16564 }
16565
16566 hHal = pHddCtx->hHal;
16567
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016568 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
16569 dbm, ccmCfgSetCallback,
16570 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016571 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016572 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016573 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
16574 return -EIO;
16575 }
16576
16577 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
16578 dbm);
16579
16580 switch(type)
16581 {
16582 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
16583 /* Fall through */
16584 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
16585 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
16586 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016587 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
16588 __func__);
16589 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070016590 }
16591 break;
16592 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016593 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070016594 __func__);
16595 return -EOPNOTSUPP;
16596 break;
16597 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016598 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
16599 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070016600 return -EIO;
16601 }
16602
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016603 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016604 return 0;
16605}
16606
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016607static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
16608#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16609 struct wireless_dev *wdev,
16610#endif
16611#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
16612 enum tx_power_setting type,
16613#else
16614 enum nl80211_tx_power_setting type,
16615#endif
16616 int dbm)
16617{
16618 int ret;
16619 vos_ssr_protect(__func__);
16620 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
16621#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16622 wdev,
16623#endif
16624#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
16625 type,
16626#else
16627 type,
16628#endif
16629 dbm);
16630 vos_ssr_unprotect(__func__);
16631
16632 return ret;
16633}
16634
Jeff Johnson295189b2012-06-20 16:38:30 -070016635/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016636 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070016637 * This function is used to read the txpower
16638 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016639static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070016640#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16641 struct wireless_dev *wdev,
16642#endif
16643 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070016644{
16645
16646 hdd_adapter_t *pAdapter;
16647 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016648 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016649
Jeff Johnsone7245742012-09-05 17:12:55 -070016650 ENTER();
16651
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016652 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016653 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016654 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016655 *dbm = 0;
16656 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016657 }
16658
Jeff Johnson295189b2012-06-20 16:38:30 -070016659 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
16660 if (NULL == pAdapter)
16661 {
16662 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
16663 return -ENOENT;
16664 }
16665
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016666 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16667 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
16668 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070016669 wlan_hdd_get_classAstats(pAdapter);
16670 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
16671
Jeff Johnsone7245742012-09-05 17:12:55 -070016672 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016673 return 0;
16674}
16675
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016676static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
16677#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16678 struct wireless_dev *wdev,
16679#endif
16680 int *dbm)
16681{
16682 int ret;
16683
16684 vos_ssr_protect(__func__);
16685 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
16686#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16687 wdev,
16688#endif
16689 dbm);
16690 vos_ssr_unprotect(__func__);
16691
16692 return ret;
16693}
16694
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016695static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016696#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16697 const u8* mac,
16698#else
16699 u8* mac,
16700#endif
16701 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070016702{
16703 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
16704 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16705 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053016706 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070016707
16708 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
16709 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070016710
16711 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
16712 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
16713 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
16714 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
16715 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
16716 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
16717 tANI_U16 maxRate = 0;
16718 tANI_U16 myRate;
16719 tANI_U16 currentRate = 0;
16720 tANI_U8 maxSpeedMCS = 0;
16721 tANI_U8 maxMCSIdx = 0;
16722 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053016723 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070016724 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016725 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016726
Leo Chang6f8870f2013-03-26 18:11:36 -070016727#ifdef WLAN_FEATURE_11AC
16728 tANI_U32 vht_mcs_map;
16729 eDataRate11ACMaxMcs vhtMaxMcs;
16730#endif /* WLAN_FEATURE_11AC */
16731
Jeff Johnsone7245742012-09-05 17:12:55 -070016732 ENTER();
16733
Jeff Johnson295189b2012-06-20 16:38:30 -070016734 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
16735 (0 == ssidlen))
16736 {
16737 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
16738 " Invalid ssidlen, %d", __func__, ssidlen);
16739 /*To keep GUI happy*/
16740 return 0;
16741 }
16742
Mukul Sharma811205f2014-07-09 21:07:30 +053016743 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
16744 {
16745 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16746 "%s: Roaming in progress, so unable to proceed this request", __func__);
Sachin Ahuja81ab1812016-08-19 21:35:58 +053016747 /* return a cached value */
16748 sinfo->signal = pAdapter->rssi;
Mukul Sharma811205f2014-07-09 21:07:30 +053016749 return 0;
16750 }
16751
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016752 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016753 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016754 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016755 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016756 }
16757
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053016758 wlan_hdd_get_station_stats(pAdapter);
16759 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070016760
Kiet Lam3b17fc82013-09-27 05:24:08 +053016761 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
16762 sinfo->filled |= STATION_INFO_SIGNAL;
16763
c_hpothu09f19542014-05-30 21:53:31 +053016764 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053016765 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
16766 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053016767 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053016768 {
16769 rate_flags = pAdapter->maxRateFlags;
16770 }
c_hpothu44ff4e02014-05-08 00:13:57 +053016771
Jeff Johnson295189b2012-06-20 16:38:30 -070016772 //convert to the UI units of 100kbps
16773 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
16774
16775#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070016776 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 -070016777 sinfo->signal,
16778 pCfg->reportMaxLinkSpeed,
16779 myRate,
16780 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070016781 (int) pCfg->linkSpeedRssiMid,
16782 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070016783 (int) rate_flags,
16784 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070016785#endif //LINKSPEED_DEBUG_ENABLED
16786
16787 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
16788 {
16789 // we do not want to necessarily report the current speed
16790 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
16791 {
16792 // report the max possible speed
16793 rssidx = 0;
16794 }
16795 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
16796 {
16797 // report the max possible speed with RSSI scaling
16798 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
16799 {
16800 // report the max possible speed
16801 rssidx = 0;
16802 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070016803 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070016804 {
16805 // report middle speed
16806 rssidx = 1;
16807 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070016808 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
16809 {
16810 // report middle speed
16811 rssidx = 2;
16812 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016813 else
16814 {
16815 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070016816 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070016817 }
16818 }
16819 else
16820 {
16821 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
16822 hddLog(VOS_TRACE_LEVEL_ERROR,
16823 "%s: Invalid value for reportMaxLinkSpeed: %u",
16824 __func__, pCfg->reportMaxLinkSpeed);
16825 rssidx = 0;
16826 }
16827
16828 maxRate = 0;
16829
16830 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053016831 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
16832 OperationalRates, &ORLeng))
16833 {
16834 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
16835 /*To keep GUI happy*/
16836 return 0;
16837 }
16838
Jeff Johnson295189b2012-06-20 16:38:30 -070016839 for (i = 0; i < ORLeng; i++)
16840 {
Jeff Johnsone7245742012-09-05 17:12:55 -070016841 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070016842 {
16843 /* Validate Rate Set */
16844 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
16845 {
16846 currentRate = supported_data_rate[j].supported_rate[rssidx];
16847 break;
16848 }
16849 }
16850 /* Update MAX rate */
16851 maxRate = (currentRate > maxRate)?currentRate:maxRate;
16852 }
16853
16854 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053016855 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
16856 ExtendedRates, &ERLeng))
16857 {
16858 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
16859 /*To keep GUI happy*/
16860 return 0;
16861 }
16862
Jeff Johnson295189b2012-06-20 16:38:30 -070016863 for (i = 0; i < ERLeng; i++)
16864 {
Jeff Johnsone7245742012-09-05 17:12:55 -070016865 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070016866 {
16867 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
16868 {
16869 currentRate = supported_data_rate[j].supported_rate[rssidx];
16870 break;
16871 }
16872 }
16873 /* Update MAX rate */
16874 maxRate = (currentRate > maxRate)?currentRate:maxRate;
16875 }
c_hpothu79aab322014-07-14 21:11:01 +053016876
Kiet Lamb69f8dc2013-11-15 15:34:27 +053016877 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053016878 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053016879 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053016880 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070016881 {
c_hpothu79aab322014-07-14 21:11:01 +053016882 if (rate_flags & eHAL_TX_RATE_VHT80)
16883 mode = 2;
16884 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
16885 mode = 1;
16886 else
16887 mode = 0;
16888
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053016889 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
16890 MCSRates, &MCSLeng))
16891 {
16892 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
16893 /*To keep GUI happy*/
16894 return 0;
16895 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016896 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070016897#ifdef WLAN_FEATURE_11AC
16898 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016899 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070016900 {
Leo Chang6f8870f2013-03-26 18:11:36 -070016901 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016902 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070016903 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070016904 {
Leo Chang6f8870f2013-03-26 18:11:36 -070016905 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070016906 }
Leo Chang6f8870f2013-03-26 18:11:36 -070016907 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070016908 {
Leo Chang6f8870f2013-03-26 18:11:36 -070016909 maxMCSIdx = 7;
16910 }
16911 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
16912 {
16913 maxMCSIdx = 8;
16914 }
16915 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
16916 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016917 //VHT20 is supporting 0~8
16918 if (rate_flags & eHAL_TX_RATE_VHT20)
16919 maxMCSIdx = 8;
16920 else
16921 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070016922 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016923
c_hpothu79aab322014-07-14 21:11:01 +053016924 if (0 != rssidx)/*check for scaled */
16925 {
16926 //get middle rate MCS index if rssi=1/2
16927 for (i=0; i <= maxMCSIdx; i++)
16928 {
16929 if (sinfo->signal <= rssiMcsTbl[mode][i])
16930 {
16931 maxMCSIdx = i;
16932 break;
16933 }
16934 }
16935 }
16936
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016937 if (rate_flags & eHAL_TX_RATE_VHT80)
16938 {
16939 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
16940 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
16941 }
16942 else if (rate_flags & eHAL_TX_RATE_VHT40)
16943 {
16944 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
16945 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
16946 }
16947 else if (rate_flags & eHAL_TX_RATE_VHT20)
16948 {
16949 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
16950 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
16951 }
16952
Leo Chang6f8870f2013-03-26 18:11:36 -070016953 maxSpeedMCS = 1;
16954 if (currentRate > maxRate)
16955 {
16956 maxRate = currentRate;
16957 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016958
Leo Chang6f8870f2013-03-26 18:11:36 -070016959 }
16960 else
16961#endif /* WLAN_FEATURE_11AC */
16962 {
16963 if (rate_flags & eHAL_TX_RATE_HT40)
16964 {
16965 rateFlag |= 1;
16966 }
16967 if (rate_flags & eHAL_TX_RATE_SGI)
16968 {
16969 rateFlag |= 2;
16970 }
16971
Girish Gowli01abcee2014-07-31 20:18:55 +053016972 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053016973 if (rssidx == 1 || rssidx == 2)
16974 {
16975 //get middle rate MCS index if rssi=1/2
16976 for (i=0; i <= 7; i++)
16977 {
16978 if (sinfo->signal <= rssiMcsTbl[mode][i])
16979 {
16980 temp = i+1;
16981 break;
16982 }
16983 }
16984 }
c_hpothu79aab322014-07-14 21:11:01 +053016985
16986 for (i = 0; i < MCSLeng; i++)
16987 {
Leo Chang6f8870f2013-03-26 18:11:36 -070016988 for (j = 0; j < temp; j++)
16989 {
16990 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
16991 {
16992 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053016993 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070016994 break;
16995 }
16996 }
16997 if ((j < temp) && (currentRate > maxRate))
16998 {
16999 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070017000 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017001 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053017002 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070017003 }
17004 }
17005
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017006 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
17007 {
17008 maxRate = myRate;
17009 maxSpeedMCS = 1;
17010 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
17011 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017012 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053017013 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070017014 {
17015 maxRate = myRate;
17016 if (rate_flags & eHAL_TX_RATE_LEGACY)
17017 {
17018 maxSpeedMCS = 0;
17019 }
17020 else
17021 {
17022 maxSpeedMCS = 1;
17023 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
17024 }
17025 }
17026
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017027 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070017028 {
17029 sinfo->txrate.legacy = maxRate;
17030#ifdef LINKSPEED_DEBUG_ENABLED
17031 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
17032#endif //LINKSPEED_DEBUG_ENABLED
17033 }
17034 else
17035 {
17036 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070017037#ifdef WLAN_FEATURE_11AC
17038 sinfo->txrate.nss = 1;
17039 if (rate_flags & eHAL_TX_RATE_VHT80)
17040 {
17041 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017042 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070017043 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017044 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070017045 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017046 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
17047 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
17048 }
17049 else if (rate_flags & eHAL_TX_RATE_VHT20)
17050 {
17051 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
17052 }
17053#endif /* WLAN_FEATURE_11AC */
17054 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
17055 {
17056 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
17057 if (rate_flags & eHAL_TX_RATE_HT40)
17058 {
17059 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
17060 }
Leo Chang6f8870f2013-03-26 18:11:36 -070017061 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017062 if (rate_flags & eHAL_TX_RATE_SGI)
17063 {
17064 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
17065 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017066
Jeff Johnson295189b2012-06-20 16:38:30 -070017067#ifdef LINKSPEED_DEBUG_ENABLED
17068 pr_info("Reporting MCS rate %d flags %x\n",
17069 sinfo->txrate.mcs,
17070 sinfo->txrate.flags );
17071#endif //LINKSPEED_DEBUG_ENABLED
17072 }
17073 }
17074 else
17075 {
17076 // report current rate instead of max rate
17077
17078 if (rate_flags & eHAL_TX_RATE_LEGACY)
17079 {
17080 //provide to the UI in units of 100kbps
17081 sinfo->txrate.legacy = myRate;
17082#ifdef LINKSPEED_DEBUG_ENABLED
17083 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
17084#endif //LINKSPEED_DEBUG_ENABLED
17085 }
17086 else
17087 {
17088 //must be MCS
17089 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070017090#ifdef WLAN_FEATURE_11AC
17091 sinfo->txrate.nss = 1;
17092 if (rate_flags & eHAL_TX_RATE_VHT80)
17093 {
17094 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
17095 }
17096 else
17097#endif /* WLAN_FEATURE_11AC */
17098 {
17099 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
17100 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017101 if (rate_flags & eHAL_TX_RATE_SGI)
17102 {
17103 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
17104 }
17105 if (rate_flags & eHAL_TX_RATE_HT40)
17106 {
17107 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
17108 }
Leo Chang6f8870f2013-03-26 18:11:36 -070017109#ifdef WLAN_FEATURE_11AC
17110 else if (rate_flags & eHAL_TX_RATE_VHT80)
17111 {
17112 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
17113 }
17114#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070017115#ifdef LINKSPEED_DEBUG_ENABLED
17116 pr_info("Reporting actual MCS rate %d flags %x\n",
17117 sinfo->txrate.mcs,
17118 sinfo->txrate.flags );
17119#endif //LINKSPEED_DEBUG_ENABLED
17120 }
17121 }
17122 sinfo->filled |= STATION_INFO_TX_BITRATE;
17123
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070017124 sinfo->tx_packets =
17125 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
17126 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
17127 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
17128 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
17129
17130 sinfo->tx_retries =
17131 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
17132 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
17133 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
17134 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
17135
17136 sinfo->tx_failed =
17137 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
17138 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
17139 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
17140 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
17141
17142 sinfo->filled |=
17143 STATION_INFO_TX_PACKETS |
17144 STATION_INFO_TX_RETRIES |
17145 STATION_INFO_TX_FAILED;
17146
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053017147 sinfo->rx_packets = pAdapter->hdd_stats.summary_stat.rx_frm_cnt;
17148 sinfo->filled |= STATION_INFO_RX_PACKETS;
17149
17150 if (rate_flags & eHAL_TX_RATE_LEGACY)
17151 hddLog(LOG1, FL("Reporting RSSI:%d legacy rate %d pkt cnt tx %d rx %d"),
17152 sinfo->signal, sinfo->txrate.legacy, sinfo->tx_packets,
17153 sinfo->rx_packets);
17154 else
17155 hddLog(LOG1,
17156 FL("Reporting RSSI:%d MCS rate %d flags 0x%x pkt cnt tx %d rx %d"),
17157 sinfo->signal, sinfo->txrate.mcs, sinfo->txrate.flags,
17158 sinfo->tx_packets, sinfo->rx_packets);
17159
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017160 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17161 TRACE_CODE_HDD_CFG80211_GET_STA,
17162 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070017163 EXIT();
17164 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070017165}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017166#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
17167static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
17168 const u8* mac, struct station_info *sinfo)
17169#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017170static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
17171 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017172#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017173{
17174 int ret;
17175
17176 vos_ssr_protect(__func__);
17177 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
17178 vos_ssr_unprotect(__func__);
17179
17180 return ret;
17181}
17182
17183static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070017184 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070017185{
17186 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017187 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070017188 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017189 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017190
Jeff Johnsone7245742012-09-05 17:12:55 -070017191 ENTER();
17192
Jeff Johnson295189b2012-06-20 16:38:30 -070017193 if (NULL == pAdapter)
17194 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017195 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017196 return -ENODEV;
17197 }
17198
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017199 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17200 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
17201 pAdapter->sessionId, timeout));
17202
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017203 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017204 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017205 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017206 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017207 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017208 }
17209
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017210 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
17211 (TRUE == pHddCtx->hdd_wlan_suspended) &&
17212 (pHddCtx->cfg_ini->fhostArpOffload) &&
17213 (eConnectionState_Associated ==
17214 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
17215 {
Amar Singhald53568e2013-09-26 11:03:45 -070017216
17217 hddLog(VOS_TRACE_LEVEL_INFO,
17218 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053017219 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017220 if (!VOS_IS_STATUS_SUCCESS(vos_status))
17221 {
17222 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017223 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017224 __func__, vos_status);
17225 }
17226 }
17227
Jeff Johnson295189b2012-06-20 16:38:30 -070017228 /**The get power cmd from the supplicant gets updated by the nl only
17229 *on successful execution of the function call
17230 *we are oppositely mapped w.r.t mode in the driver
17231 **/
17232 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
17233
17234 if (VOS_STATUS_E_FAILURE == vos_status)
17235 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053017236 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17237 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017238 return -EINVAL;
17239 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017240 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017241 return 0;
17242}
17243
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017244static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
17245 struct net_device *dev, bool mode, int timeout)
17246{
17247 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070017248
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017249 vos_ssr_protect(__func__);
17250 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
17251 vos_ssr_unprotect(__func__);
17252
17253 return ret;
17254}
Sushant Kaushik084f6592015-09-10 13:11:56 +053017255
Jeff Johnson295189b2012-06-20 16:38:30 -070017256#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017257static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
17258 struct net_device *netdev,
17259 u8 key_index)
17260{
17261 ENTER();
17262 return 0;
17263}
17264
Jeff Johnson295189b2012-06-20 16:38:30 -070017265static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017266 struct net_device *netdev,
17267 u8 key_index)
17268{
17269 int ret;
17270 vos_ssr_protect(__func__);
17271 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
17272 vos_ssr_unprotect(__func__);
17273 return ret;
17274}
17275#endif //LINUX_VERSION_CODE
17276
17277#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
17278static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
17279 struct net_device *dev,
17280 struct ieee80211_txq_params *params)
17281{
17282 ENTER();
17283 return 0;
17284}
17285#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
17286static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
17287 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070017288{
Jeff Johnsone7245742012-09-05 17:12:55 -070017289 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070017290 return 0;
17291}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017292#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070017293
17294#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
17295static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017296 struct net_device *dev,
17297 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070017298{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017299 int ret;
17300
17301 vos_ssr_protect(__func__);
17302 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
17303 vos_ssr_unprotect(__func__);
17304 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070017305}
17306#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
17307static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
17308 struct ieee80211_txq_params *params)
17309{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017310 int ret;
17311
17312 vos_ssr_protect(__func__);
17313 ret = __wlan_hdd_set_txq_params(wiphy, params);
17314 vos_ssr_unprotect(__func__);
17315 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070017316}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017317#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017318
Naresh Jayaram69e3f282014-10-14 12:29:12 +053017319static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017320 struct net_device *dev,
17321 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070017322{
17323 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017324 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017325 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017326 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017327 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017328 v_CONTEXT_t pVosContext = NULL;
17329 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017330
Jeff Johnsone7245742012-09-05 17:12:55 -070017331 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017332
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017333 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070017334 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017335 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017336 return -EINVAL;
17337 }
17338
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017339 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17340 TRACE_CODE_HDD_CFG80211_DEL_STA,
17341 pAdapter->sessionId, pAdapter->device_mode));
17342
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017343 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17344 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017345 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017346 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017347 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017348 }
17349
Jeff Johnson295189b2012-06-20 16:38:30 -070017350 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070017351 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070017352 )
17353 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017354 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
17355 pSapCtx = VOS_GET_SAP_CB(pVosContext);
17356 if(pSapCtx == NULL){
17357 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17358 FL("psapCtx is NULL"));
17359 return -ENOENT;
17360 }
Agrawal Ashish306b75f2017-01-11 19:16:25 +053017361 if (pHddCtx->cfg_ini->enable_sap_auth_offload)
17362 {
17363 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
17364 "Change reason code to eSIR_MAC_DISASSOC_LEAVING_BSS_REASON in sap auth offload");
17365 pDelStaParams->reason_code = eSIR_MAC_DISASSOC_LEAVING_BSS_REASON;
17366 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017367 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070017368 {
17369 v_U16_t i;
17370 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
17371 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017372 if ((pSapCtx->aStaInfo[i].isUsed) &&
17373 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070017374 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017375 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017376 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017377 ETHER_ADDR_LEN);
17378
Jeff Johnson295189b2012-06-20 16:38:30 -070017379 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080017380 "%s: Delete STA with MAC::"
17381 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017382 __func__,
17383 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
17384 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070017385 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017386 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070017387 }
17388 }
17389 }
17390 else
17391 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017392
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017393 vos_status = hdd_softap_GetStaId(pAdapter,
17394 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017395 if (!VOS_IS_STATUS_SUCCESS(vos_status))
17396 {
17397 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080017398 "%s: Skip this DEL STA as this is not used::"
17399 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017400 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017401 return -ENOENT;
17402 }
17403
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017404 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017405 {
17406 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080017407 "%s: Skip this DEL STA as deauth is in progress::"
17408 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017409 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017410 return -ENOENT;
17411 }
17412
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017413 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017414
Jeff Johnson295189b2012-06-20 16:38:30 -070017415 hddLog(VOS_TRACE_LEVEL_INFO,
17416 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080017417 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070017418 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017419 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017420
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017421 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017422 if (!VOS_IS_STATUS_SUCCESS(vos_status))
17423 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017424 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017425 hddLog(VOS_TRACE_LEVEL_INFO,
17426 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080017427 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017428 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017429 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017430 return -ENOENT;
17431 }
17432
Jeff Johnson295189b2012-06-20 16:38:30 -070017433 }
17434 }
17435
17436 EXIT();
17437
17438 return 0;
17439}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053017440
17441#ifdef CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053017442int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Naresh Jayaram69e3f282014-10-14 12:29:12 +053017443 struct net_device *dev,
17444 struct station_del_parameters *param)
17445#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017446#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
Kapil Gupta137ef892016-12-13 19:38:00 +053017447int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017448 struct net_device *dev, const u8 *mac)
17449#else
Kapil Gupta137ef892016-12-13 19:38:00 +053017450int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017451 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053017452#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017453#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017454{
17455 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017456 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070017457
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017458 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017459
Naresh Jayaram69e3f282014-10-14 12:29:12 +053017460#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017461 if (NULL == param) {
17462 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017463 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017464 return -EINVAL;
17465 }
17466
17467 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
17468 param->subtype, &delStaParams);
17469
Naresh Jayaram69e3f282014-10-14 12:29:12 +053017470#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053017471 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017472 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053017473#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017474 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
17475
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017476 vos_ssr_unprotect(__func__);
17477
17478 return ret;
17479}
17480
17481static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017482 struct net_device *dev,
17483#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17484 const u8 *mac,
17485#else
17486 u8 *mac,
17487#endif
17488 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017489{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017490 hdd_adapter_t *pAdapter;
17491 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017492 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017493#ifdef FEATURE_WLAN_TDLS
17494 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017495
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017496 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017497
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017498 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17499 if (NULL == pAdapter)
17500 {
17501 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17502 "%s: Adapter is NULL",__func__);
17503 return -EINVAL;
17504 }
17505 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17506 status = wlan_hdd_validate_context(pHddCtx);
17507 if (0 != status)
17508 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017509 return status;
17510 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017511
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017512 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17513 TRACE_CODE_HDD_CFG80211_ADD_STA,
17514 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017515 mask = params->sta_flags_mask;
17516
17517 set = params->sta_flags_set;
17518
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017519 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017520 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
17521 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017522
17523 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
17524 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080017525 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017526 }
17527 }
17528#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017529 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017530 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017531}
17532
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017533#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
17534static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
17535 struct net_device *dev, const u8 *mac,
17536 struct station_parameters *params)
17537#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017538static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
17539 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017540#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017541{
17542 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017543
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017544 vos_ssr_protect(__func__);
17545 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
17546 vos_ssr_unprotect(__func__);
17547
17548 return ret;
17549}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017550#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070017551
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017552static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070017553 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017554{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017555 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17556 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017557 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017558 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017559 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017560 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070017561
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017562 ENTER();
17563
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017564 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017565 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017566 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017567 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017568 return -EINVAL;
17569 }
17570
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017571 if (!pmksa) {
17572 hddLog(LOGE, FL("pmksa is NULL"));
17573 return -EINVAL;
17574 }
17575
17576 if (!pmksa->bssid || !pmksa->pmkid) {
17577 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
17578 pmksa->bssid, pmksa->pmkid);
17579 return -EINVAL;
17580 }
17581
17582 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
17583 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
17584
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017585 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17586 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017587 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017588 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017589 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017590 }
17591
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017592 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017593 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
17594
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017595 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
17596 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017597
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017598 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017599 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017600 &pmk_id, 1, FALSE);
17601
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017602 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17603 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
17604 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017605
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017606 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017607 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017608}
17609
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017610static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
17611 struct cfg80211_pmksa *pmksa)
17612{
17613 int ret;
17614
17615 vos_ssr_protect(__func__);
17616 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
17617 vos_ssr_unprotect(__func__);
17618
17619 return ret;
17620}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017621
Wilson Yang6507c4e2013-10-01 20:11:19 -070017622
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017623static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070017624 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017625{
Wilson Yang6507c4e2013-10-01 20:11:19 -070017626 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17627 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017628 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080017629 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017630
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017631 ENTER();
17632
Wilson Yang6507c4e2013-10-01 20:11:19 -070017633 /* Validate pAdapter */
17634 if (NULL == pAdapter)
17635 {
17636 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
17637 return -EINVAL;
17638 }
17639
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017640 if (!pmksa) {
17641 hddLog(LOGE, FL("pmksa is NULL"));
17642 return -EINVAL;
17643 }
17644
17645 if (!pmksa->bssid) {
17646 hddLog(LOGE, FL("pmksa->bssid is NULL"));
17647 return -EINVAL;
17648 }
17649
Kiet Lam98c46a12014-10-31 15:34:57 -070017650 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
17651 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
17652
Wilson Yang6507c4e2013-10-01 20:11:19 -070017653 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17654 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070017655 if (0 != status)
17656 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070017657 return status;
17658 }
17659
17660 /*Retrieve halHandle*/
17661 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
17662
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017663 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17664 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
17665 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017666 /* Delete the PMKID CSR cache */
17667 if (eHAL_STATUS_SUCCESS !=
17668 sme_RoamDelPMKIDfromCache(halHandle,
17669 pAdapter->sessionId, pmksa->bssid, FALSE)) {
17670 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
17671 MAC_ADDR_ARRAY(pmksa->bssid));
17672 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017673 }
17674
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017675 EXIT();
17676 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017677}
17678
Wilson Yang6507c4e2013-10-01 20:11:19 -070017679
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017680static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
17681 struct cfg80211_pmksa *pmksa)
17682{
17683 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017684
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017685 vos_ssr_protect(__func__);
17686 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
17687 vos_ssr_unprotect(__func__);
17688
17689 return ret;
17690
17691}
17692
17693static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017694{
Wilson Yang6507c4e2013-10-01 20:11:19 -070017695 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17696 tHalHandle halHandle;
17697 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080017698 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017699
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017700 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070017701
17702 /* Validate pAdapter */
17703 if (NULL == pAdapter)
17704 {
17705 hddLog(VOS_TRACE_LEVEL_ERROR,
17706 "%s: Invalid Adapter" ,__func__);
17707 return -EINVAL;
17708 }
17709
17710 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17711 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070017712 if (0 != status)
17713 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070017714 return status;
17715 }
17716
17717 /*Retrieve halHandle*/
17718 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
17719
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017720 /* Flush the PMKID cache in CSR */
17721 if (eHAL_STATUS_SUCCESS !=
17722 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
17723 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
17724 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017725 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017726 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080017727 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017728}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017729
17730static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
17731{
17732 int ret;
17733
17734 vos_ssr_protect(__func__);
17735 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
17736 vos_ssr_unprotect(__func__);
17737
17738 return ret;
17739}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017740#endif
17741
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017742#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017743static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
17744 struct net_device *dev,
17745 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017746{
17747 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17748 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017749 hdd_context_t *pHddCtx;
17750 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017751
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017752 ENTER();
17753
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017754 if (NULL == pAdapter)
17755 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017756 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017757 return -ENODEV;
17758 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017759 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17760 ret = wlan_hdd_validate_context(pHddCtx);
17761 if (0 != ret)
17762 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017763 return ret;
17764 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017765 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017766 if (NULL == pHddStaCtx)
17767 {
17768 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
17769 return -EINVAL;
17770 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017771
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017772 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17773 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
17774 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017775 // Added for debug on reception of Re-assoc Req.
17776 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
17777 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017778 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017779 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080017780 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017781 }
17782
17783#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080017784 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017785 ftie->ie_len);
17786#endif
17787
17788 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053017789 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
17790 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017791 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017792
17793 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017794 return 0;
17795}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017796
17797static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
17798 struct net_device *dev,
17799 struct cfg80211_update_ft_ies_params *ftie)
17800{
17801 int ret;
17802
17803 vos_ssr_protect(__func__);
17804 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
17805 vos_ssr_unprotect(__func__);
17806
17807 return ret;
17808}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017809#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017810
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017811#ifdef FEATURE_WLAN_SCAN_PNO
17812
17813void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
17814 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
17815{
17816 int ret;
17817 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
17818 hdd_context_t *pHddCtx;
17819
Nirav Shah80830bf2013-12-31 16:35:12 +053017820 ENTER();
17821
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017822 if (NULL == pAdapter)
17823 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053017824 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017825 "%s: HDD adapter is Null", __func__);
17826 return ;
17827 }
17828
17829 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17830 if (NULL == pHddCtx)
17831 {
17832 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17833 "%s: HDD context is Null!!!", __func__);
17834 return ;
17835 }
17836
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017837 spin_lock(&pHddCtx->schedScan_lock);
17838 if (TRUE == pHddCtx->isWiphySuspended)
17839 {
17840 pHddCtx->isSchedScanUpdatePending = TRUE;
17841 spin_unlock(&pHddCtx->schedScan_lock);
17842 hddLog(VOS_TRACE_LEVEL_INFO,
17843 "%s: Update cfg80211 scan database after it resume", __func__);
17844 return ;
17845 }
17846 spin_unlock(&pHddCtx->schedScan_lock);
17847
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017848 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
17849
17850 if (0 > ret)
17851 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagarfb49cdd2015-10-16 18:41:59 +053017852 else
17853 {
17854 /* Acquire wakelock to handle the case where APP's tries to suspend
17855 * immediatly after the driver gets connect request(i.e after pno)
17856 * from supplicant, this result in app's is suspending and not able
17857 * to process the connect request to AP */
17858 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
17859 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017860 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017861 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17862 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017863}
17864
17865/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017866 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053017867 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017868 */
17869static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
17870{
17871 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
17872 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017873 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017874 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17875 int status = 0;
Agrawal Ashishcff31692016-12-16 17:17:50 +053017876
17877 if (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
17878 {
17879 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17880 "%s: PNO is allowed only in STA interface", __func__);
17881 return eHAL_STATUS_FAILURE;
17882 }
17883
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017884 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
17885
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053017886 /* The current firmware design does not allow PNO during any
Agrawal Ashishcff31692016-12-16 17:17:50 +053017887 * active sessions. PNO is allowed only in case when sap session
17888 * is present and sapo auth offload feature enabled in firmare.
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053017889 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017890 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
17891 {
17892 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017893 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017894
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017895 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
17896 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
17897 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
17898 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
Agrawal Ashishcff31692016-12-16 17:17:50 +053017899 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode &&
17900 !pHddCtx->cfg_ini->enable_sap_auth_offload)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053017901 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017902 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017903 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017904 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017905 }
17906 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
17907 pAdapterNode = pNext;
17908 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017909 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017910}
17911
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017912void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
17913{
17914 hdd_adapter_t *pAdapter = callbackContext;
17915 hdd_context_t *pHddCtx;
17916
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017917 ENTER();
17918
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017919 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
17920 {
17921 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17922 FL("Invalid adapter or adapter has invalid magic"));
17923 return;
17924 }
17925
17926 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17927 if (0 != wlan_hdd_validate_context(pHddCtx))
17928 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017929 return;
17930 }
17931
c_hpothub53c45d2014-08-18 16:53:14 +053017932 if (VOS_STATUS_SUCCESS != status)
17933 {
17934 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017935 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053017936 pHddCtx->isPnoEnable = FALSE;
17937 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017938
17939 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
17940 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017941 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017942}
17943
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017944#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) || \
17945 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
17946/**
17947 * hdd_config_sched_scan_plan() - configures the sched scan plans
17948 * from the framework.
17949 * @pno_req: pointer to PNO scan request
17950 * @request: pointer to scan request from framework
17951 *
17952 * Return: None
17953 */
17954static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
17955 struct cfg80211_sched_scan_request *request,
17956 hdd_context_t *hdd_ctx)
17957{
17958 v_U32_t i = 0;
17959
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053017960 pno_req->scanTimers.ucScanTimersCount = request->n_scan_plans;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017961 for (i = 0; i < request->n_scan_plans; i++)
17962 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053017963 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
17964 request->scan_plans[i].iterations;
17965 pno_req->scanTimers.aTimerValues[i].uTimerValue =
17966 request->scan_plans[i].interval;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017967 }
17968}
17969#else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053017970static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017971 struct cfg80211_sched_scan_request *request,
17972 hdd_context_t *hdd_ctx)
17973{
17974 v_U32_t i, temp_int;
17975 /* Driver gets only one time interval which is hardcoded in
17976 * supplicant for 10000ms. Taking power consumption into account 6
17977 * timers will be used, Timervalue is increased exponentially
17978 * i.e 10,20,40, 80,160,320 secs. And number of scan cycle for each
17979 * timer is configurable through INI param gPNOScanTimerRepeatValue.
17980 * If it is set to 0 only one timer will be used and PNO scan cycle
17981 * will be repeated after each interval specified by supplicant
17982 * till PNO is disabled.
17983 */
17984 if (0 == hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue)
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053017985 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017986 HDD_PNO_SCAN_TIMERS_SET_ONE;
17987 else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053017988 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017989 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
17990
17991 temp_int = (request->interval)/1000;
17992 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17993 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
17994 temp_int, hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue);
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053017995 for ( i = 0; i < pno_req->scanTimers.ucScanTimersCount; i++)
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017996 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053017997 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017998 hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue;
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053017999 pno_req->scanTimers.aTimerValues[i].uTimerValue = temp_int;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018000 temp_int *= 2;
18001 }
18002 //Repeat last timer until pno disabled.
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018003 pno_req->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018004}
18005#endif
18006
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018007/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018008 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
18009 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018010 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018011static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018012 struct net_device *dev, struct cfg80211_sched_scan_request *request)
18013{
18014 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018015 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018016 hdd_context_t *pHddCtx;
18017 tHalHandle hHal;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018018 v_U32_t i, indx, num_ch, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053018019 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
18020 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018021 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
18022 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018023 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053018024 hdd_config_t *pConfig = NULL;
18025 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018026
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018027 ENTER();
18028
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018029 if (NULL == pAdapter)
18030 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018031 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018032 "%s: HDD adapter is Null", __func__);
18033 return -ENODEV;
18034 }
18035
18036 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018037 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018038
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018039 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018040 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018041 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018042 }
18043
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053018044 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018045 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
18046 if (NULL == hHal)
18047 {
18048 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18049 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018050 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018051 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018052 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18053 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
18054 pAdapter->sessionId, pAdapter->device_mode));
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053018055 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053018056 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053018057 {
18058 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18059 "%s: aborting the existing scan is unsuccessfull", __func__);
18060 return -EBUSY;
18061 }
18062
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018063 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018064 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053018065 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018066 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018067 return -EBUSY;
18068 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018069
c_hpothu37f21312014-04-09 21:49:54 +053018070 if (TRUE == pHddCtx->isPnoEnable)
18071 {
18072 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
18073 FL("already PNO is enabled"));
18074 return -EBUSY;
18075 }
c_hpothu225aa7c2014-10-22 17:45:13 +053018076
18077 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
18078 {
18079 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18080 "%s: abort ROC failed ", __func__);
18081 return -EBUSY;
18082 }
18083
c_hpothu37f21312014-04-09 21:49:54 +053018084 pHddCtx->isPnoEnable = TRUE;
18085
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018086 pnoRequest.enable = 1; /*Enable PNO */
18087 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018088
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018089 if (( !pnoRequest.ucNetworksCount ) ||
18090 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018091 {
18092 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053018093 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018094 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053018095 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018096 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018097 goto error;
18098 }
18099
18100 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
18101 {
18102 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053018103 "%s: Incorrect number of channels %d",
18104 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018105 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018106 goto error;
18107 }
18108
18109 /* Framework provides one set of channels(all)
18110 * common for all saved profile */
18111 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
18112 channels_allowed, &num_channels_allowed))
18113 {
18114 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18115 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018116 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018117 goto error;
18118 }
18119 /* Checking each channel against allowed channel list */
18120 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053018121 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018122 {
Nirav Shah80830bf2013-12-31 16:35:12 +053018123 char chList [(request->n_channels*5)+1];
18124 int len;
18125 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018126 {
Nirav Shah80830bf2013-12-31 16:35:12 +053018127 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018128 {
Nirav Shah80830bf2013-12-31 16:35:12 +053018129 if (request->channels[i]->hw_value == channels_allowed[indx])
18130 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053018131 if ((!pConfig->enableDFSPnoChnlScan) &&
18132 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
18133 {
18134 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18135 "%s : Dropping DFS channel : %d",
18136 __func__,channels_allowed[indx]);
18137 num_ignore_dfs_ch++;
18138 break;
18139 }
18140
Nirav Shah80830bf2013-12-31 16:35:12 +053018141 valid_ch[num_ch++] = request->channels[i]->hw_value;
18142 len += snprintf(chList+len, 5, "%d ",
18143 request->channels[i]->hw_value);
18144 break ;
18145 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018146 }
18147 }
Nirav Shah80830bf2013-12-31 16:35:12 +053018148 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018149
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053018150 /*If all channels are DFS and dropped, then ignore the PNO request*/
18151 if (num_ignore_dfs_ch == request->n_channels)
18152 {
18153 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18154 "%s : All requested channels are DFS channels", __func__);
18155 ret = -EINVAL;
18156 goto error;
18157 }
18158 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018159
18160 pnoRequest.aNetworks =
18161 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
18162 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018163 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018164 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
18165 FL("failed to allocate memory aNetworks %u"),
18166 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
18167 goto error;
18168 }
18169 vos_mem_zero(pnoRequest.aNetworks,
18170 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
18171
18172 /* Filling per profile params */
18173 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
18174 {
18175 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018176 request->match_sets[i].ssid.ssid_len;
18177
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018178 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
18179 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018180 {
18181 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053018182 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018183 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018184 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018185 goto error;
18186 }
18187
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018188 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018189 request->match_sets[i].ssid.ssid,
18190 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053018191 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18192 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018193 i, pnoRequest.aNetworks[i].ssId.ssId);
18194 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
18195 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
18196 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018197
18198 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018199 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
18200 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018201
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018202 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018203 }
18204
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018205 for (i = 0; i < request->n_ssids; i++)
18206 {
18207 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018208 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018209 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018210 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018211 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018212 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018213 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018214 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018215 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018216 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018217 break;
18218 }
18219 j++;
18220 }
18221 }
18222 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18223 "Number of hidden networks being Configured = %d",
18224 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053018225 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080018226 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018227
18228 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
18229 if (pnoRequest.p24GProbeTemplate == NULL)
18230 {
18231 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
18232 FL("failed to allocate memory p24GProbeTemplate %u"),
18233 SIR_PNO_MAX_PB_REQ_SIZE);
18234 goto error;
18235 }
18236
18237 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
18238 if (pnoRequest.p5GProbeTemplate == NULL)
18239 {
18240 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
18241 FL("failed to allocate memory p5GProbeTemplate %u"),
18242 SIR_PNO_MAX_PB_REQ_SIZE);
18243 goto error;
18244 }
18245
18246 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
18247 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
18248
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053018249 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
18250 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053018251 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018252 pnoRequest.us24GProbeTemplateLen = request->ie_len;
18253 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
18254 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053018255
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018256 pnoRequest.us5GProbeTemplateLen = request->ie_len;
18257 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
18258 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053018259 }
18260
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018261 hdd_config_sched_scan_plan(&pnoRequest, request, pHddCtx);
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053018262
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018263 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018264
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018265 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018266 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
18267 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018268 pAdapter->pno_req_status = 0;
18269
Nirav Shah80830bf2013-12-31 16:35:12 +053018270 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18271 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018272 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
18273 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053018274
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018275 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018276 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018277 hdd_cfg80211_sched_scan_done_callback, pAdapter);
18278 if (eHAL_STATUS_SUCCESS != status)
18279 {
18280 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053018281 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018282 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018283 goto error;
18284 }
18285
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018286 ret = wait_for_completion_timeout(
18287 &pAdapter->pno_comp_var,
18288 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
18289 if (0 >= ret)
18290 {
18291 // Did not receive the response for PNO enable in time.
18292 // Assuming the PNO enable was success.
18293 // Returning error from here, because we timeout, results
18294 // in side effect of Wifi (Wifi Setting) not to work.
18295 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18296 FL("Timed out waiting for PNO to be Enabled"));
18297 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018298 }
18299
18300 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053018301 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018302
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018303error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018304 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18305 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053018306 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018307 if (pnoRequest.aNetworks)
18308 vos_mem_free(pnoRequest.aNetworks);
18309 if (pnoRequest.p24GProbeTemplate)
18310 vos_mem_free(pnoRequest.p24GProbeTemplate);
18311 if (pnoRequest.p5GProbeTemplate)
18312 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018313
18314 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018315 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018316}
18317
18318/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018319 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
18320 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018321 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018322static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
18323 struct net_device *dev, struct cfg80211_sched_scan_request *request)
18324{
18325 int ret;
18326
18327 vos_ssr_protect(__func__);
18328 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
18329 vos_ssr_unprotect(__func__);
18330
18331 return ret;
18332}
18333
18334/*
18335 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
18336 * Function to disable PNO
18337 */
18338static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018339 struct net_device *dev)
18340{
18341 eHalStatus status = eHAL_STATUS_FAILURE;
18342 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18343 hdd_context_t *pHddCtx;
18344 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018345 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018346 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018347
18348 ENTER();
18349
18350 if (NULL == pAdapter)
18351 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018352 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018353 "%s: HDD adapter is Null", __func__);
18354 return -ENODEV;
18355 }
18356
18357 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018358
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018359 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018360 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018361 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018362 "%s: HDD context is Null", __func__);
18363 return -ENODEV;
18364 }
18365
18366 /* The return 0 is intentional when isLogpInProgress and
18367 * isLoadUnloadInProgress. We did observe a crash due to a return of
18368 * failure in sched_scan_stop , especially for a case where the unload
18369 * of the happens at the same time. The function __cfg80211_stop_sched_scan
18370 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
18371 * success. If it returns a failure , then its next invocation due to the
18372 * clean up of the second interface will have the dev pointer corresponding
18373 * to the first one leading to a crash.
18374 */
18375 if (pHddCtx->isLogpInProgress)
18376 {
18377 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18378 "%s: LOGP in Progress. Ignore!!!", __func__);
Mahesh A Saptasagar0c11d822015-10-08 19:54:08 +053018379 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018380 return ret;
18381 }
18382
Mihir Shete18156292014-03-11 15:38:30 +053018383 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018384 {
18385 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18386 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
18387 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018388 }
18389
18390 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
18391 if (NULL == hHal)
18392 {
18393 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18394 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018395 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018396 }
18397
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018398 pnoRequest.enable = 0; /* Disable PNO */
18399 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018400
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018401 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18402 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
18403 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053018404
18405 INIT_COMPLETION(pAdapter->pno_comp_var);
18406 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
18407 pnoRequest.callbackContext = pAdapter;
18408 pAdapter->pno_req_status = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018409 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018410 pAdapter->sessionId,
18411 NULL, pAdapter);
18412 if (eHAL_STATUS_SUCCESS != status)
18413 {
18414 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18415 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018416 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018417 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018418 }
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053018419 ret = wait_for_completion_timeout(
18420 &pAdapter->pno_comp_var,
18421 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
18422 if (0 >= ret)
18423 {
18424 // Did not receive the response for PNO disable in time.
18425 // Assuming the PNO disable was success.
18426 // Returning error from here, because we timeout, results
18427 // in side effect of Wifi (Wifi Setting) not to work.
Anurag Chouhan96b41cb2016-09-28 18:54:47 +053018428 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053018429 FL("Timed out waiting for PNO to be disabled"));
18430 ret = 0;
18431 }
18432
18433 ret = pAdapter->pno_req_status;
18434 pHddCtx->isPnoEnable = (ret == 0) ? FALSE : TRUE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018435
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018436error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018437 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018438 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018439
18440 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018441 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018442}
18443
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018444/*
18445 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
18446 * NL interface to disable PNO
18447 */
18448static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
18449 struct net_device *dev)
18450{
18451 int ret;
18452
18453 vos_ssr_protect(__func__);
18454 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
18455 vos_ssr_unprotect(__func__);
18456
18457 return ret;
18458}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018459#endif /*FEATURE_WLAN_SCAN_PNO*/
18460
18461
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018462#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018463#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018464static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18465 struct net_device *dev,
18466 u8 *peer, u8 action_code,
18467 u8 dialog_token,
18468 u16 status_code, u32 peer_capability,
18469 const u8 *buf, size_t len)
18470#else /* TDLS_MGMT_VERSION2 */
18471#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
18472static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18473 struct net_device *dev,
18474 const u8 *peer, u8 action_code,
18475 u8 dialog_token, u16 status_code,
18476 u32 peer_capability, bool initiator,
18477 const u8 *buf, size_t len)
18478#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
18479static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18480 struct net_device *dev,
18481 const u8 *peer, u8 action_code,
18482 u8 dialog_token, u16 status_code,
18483 u32 peer_capability, const u8 *buf,
18484 size_t len)
18485#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
18486static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18487 struct net_device *dev,
18488 u8 *peer, u8 action_code,
18489 u8 dialog_token,
18490 u16 status_code, u32 peer_capability,
18491 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018492#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018493static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18494 struct net_device *dev,
18495 u8 *peer, u8 action_code,
18496 u8 dialog_token,
18497 u16 status_code, const u8 *buf,
18498 size_t len)
18499#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018500#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018501{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018502 hdd_adapter_t *pAdapter;
18503 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018504 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070018505 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080018506 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070018507 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018508 int ret;
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053018509 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018510#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018511 u32 peer_capability = 0;
18512#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053018513 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018514 hdd_station_ctx_t *pHddStaCtx = NULL;
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053018515 tdlsCtx_t *pHddTdlsCtx;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018516
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018517 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18518 if (NULL == pAdapter)
18519 {
18520 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18521 "%s: Adapter is NULL",__func__);
18522 return -EINVAL;
18523 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018524 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18525 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
18526 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018527
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018528 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018529 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018530 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018531 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018532 "Invalid arguments");
18533 return -EINVAL;
18534 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018535
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080018536 if (pHddCtx->isLogpInProgress)
18537 {
18538 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18539 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053018540 wlan_hdd_tdls_set_link_status(pAdapter,
18541 peer,
18542 eTDLS_LINK_IDLE,
18543 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080018544 return -EBUSY;
18545 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018546
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018547 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
18548 {
18549 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18550 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
18551 return -EAGAIN;
18552 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018553
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053018554 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
18555 if (!pHddTdlsCtx) {
18556 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18557 "%s: pHddTdlsCtx not valid.", __func__);
18558 }
18559
Hoonki Lee27511902013-03-14 18:19:06 -070018560 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018561 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018562 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070018563 "%s: TDLS mode is disabled OR not enabled in FW."
18564 MAC_ADDRESS_STR " action %d declined.",
18565 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018566 return -ENOTSUPP;
18567 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018568
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018569 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18570
18571 if( NULL == pHddStaCtx )
18572 {
18573 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18574 "%s: HDD station context NULL ",__func__);
18575 return -EINVAL;
18576 }
18577
18578 /* STA should be connected and authenticated
18579 * before sending any TDLS frames
18580 */
18581 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
18582 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
18583 {
18584 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18585 "STA is not connected or unauthenticated. "
18586 "connState %u, uIsAuthenticated %u",
18587 pHddStaCtx->conn_info.connState,
18588 pHddStaCtx->conn_info.uIsAuthenticated);
18589 return -EAGAIN;
18590 }
18591
Hoonki Lee27511902013-03-14 18:19:06 -070018592 /* other than teardown frame, other mgmt frames are not sent if disabled */
18593 if (SIR_MAC_TDLS_TEARDOWN != action_code)
18594 {
18595 /* if tdls_mode is disabled to respond to peer's request */
18596 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
18597 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018598 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070018599 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070018600 " TDLS mode is disabled. action %d declined.",
18601 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070018602
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018603 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070018604 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053018605
18606 if (vos_max_concurrent_connections_reached())
18607 {
18608 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
18609 return -EINVAL;
18610 }
Hoonki Lee27511902013-03-14 18:19:06 -070018611 }
18612
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018613 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
18614 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053018615 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018616 {
18617 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018618 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070018619 " TDLS setup is ongoing. action %d declined.",
18620 __func__, MAC_ADDR_ARRAY(peer), action_code);
18621 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018622 }
18623 }
18624
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018625 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
18626 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080018627 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053018628 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
18629 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080018630 {
18631 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
18632 we return error code at 'add_station()'. Hence we have this
18633 check again in addtion to add_station().
18634 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018635 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080018636 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018637 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18638 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053018639 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
18640 __func__, MAC_ADDR_ARRAY(peer), action_code,
18641 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053018642 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080018643 }
18644 else
18645 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018646 /* maximum reached. tweak to send error code to peer and return
18647 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080018648 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018649 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18650 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053018651 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
18652 __func__, MAC_ADDR_ARRAY(peer), status_code,
18653 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070018654 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018655 /* fall through to send setup resp with failure status
18656 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080018657 }
18658 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018659 else
18660 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018661 mutex_lock(&pHddCtx->tdls_lock);
18662 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018663 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018664 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018665 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018666 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070018667 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
18668 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018669 return -EPERM;
18670 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018671 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018672 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018673 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018674
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018675 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053018676 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018677 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
18678 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018679
Hoonki Leea34dd892013-02-05 22:56:02 -080018680 /*Except teardown responder will not be used so just make 0*/
18681 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018682 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080018683 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070018684
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018685 mutex_lock(&pHddCtx->tdls_lock);
18686 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070018687
18688 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
18689 responder = pTdlsPeer->is_responder;
18690 else
Hoonki Leea34dd892013-02-05 22:56:02 -080018691 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070018692 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053018693 "%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 -070018694 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
18695 dialog_token, status_code, len);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018696 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070018697 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080018698 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018699 mutex_unlock(&pHddCtx->tdls_lock);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018700 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018701
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053018702 /* Discard TDLS setup if peer is removed by user app */
18703 if ((pHddCtx->cfg_ini->fTDLSExternalControl) &&
18704 ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
18705 (SIR_MAC_TDLS_SETUP_CNF == action_code) ||
18706 (SIR_MAC_TDLS_DIS_REQ == action_code))) {
18707
18708 mutex_lock(&pHddCtx->tdls_lock);
18709 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18710 if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) {
18711 mutex_unlock(&pHddCtx->tdls_lock);
18712 hddLog(LOGE, FL("TDLS External Control enabled, but peer "
18713 MAC_ADDRESS_STR " is not forced, so reject the action code %d"),
18714 MAC_ADDR_ARRAY(peer), action_code);
18715 return -EINVAL;
18716 }
18717 mutex_unlock(&pHddCtx->tdls_lock);
18718 }
18719
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053018720 /* For explicit trigger of DIS_REQ come out of BMPS for
18721 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070018722 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Deepthi Gowrif78f1f72016-03-21 13:13:28 +053018723 (SIR_MAC_TDLS_SETUP_CNF== action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053018724 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
18725 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070018726 {
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053018727 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter))) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018728 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053018729 "%s: Sending frame action_code %u.Disable BMPS", __func__,
18730 action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018731 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
18732 if (status != VOS_STATUS_SUCCESS) {
18733 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053018734 } else {
18735 pHddTdlsCtx->is_tdls_disabled_bmps = true;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018736 }
Hoonki Lee14621352013-04-16 17:51:19 -070018737 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018738 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018739 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018740 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
18741 }
18742 }
Hoonki Lee14621352013-04-16 17:51:19 -070018743 }
18744
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018745 /* make sure doesn't call send_mgmt() while it is pending */
18746 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
18747 {
18748 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080018749 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018750 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018751 ret = -EBUSY;
18752 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018753 }
18754
18755 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018756 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
18757
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018758 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
18759 pAdapter->sessionId, peer, action_code, dialog_token,
18760 status_code, peer_capability, (tANI_U8 *)buf, len,
18761 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018762
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018763 if (VOS_STATUS_SUCCESS != status)
18764 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018765 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18766 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018767 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018768 ret = -EINVAL;
18769 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018770 }
18771
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018772 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18773 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
18774 WAIT_TIME_TDLS_MGMT);
18775
Hoonki Leed37cbb32013-04-20 00:31:14 -070018776 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
18777 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
18778
18779 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018780 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070018781 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070018782 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070018783 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018784 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080018785
18786 if (pHddCtx->isLogpInProgress)
18787 {
18788 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18789 "%s: LOGP in Progress. Ignore!!!", __func__);
18790 return -EAGAIN;
18791 }
Abhishek Singh837adf22015-10-01 17:37:37 +053018792 if (rc <= 0)
18793 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
18794 WLAN_LOG_INDICATOR_HOST_DRIVER,
18795 WLAN_LOG_REASON_HDD_TIME_OUT,
18796 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080018797
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018798 ret = -EINVAL;
18799 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018800 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018801 else
18802 {
18803 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18804 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
18805 __func__, rc, pAdapter->mgmtTxCompletionStatus);
18806 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018807
Gopichand Nakkala05922802013-03-14 12:23:19 -070018808 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070018809 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018810 ret = max_sta_failed;
18811 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070018812 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018813
Hoonki Leea34dd892013-02-05 22:56:02 -080018814 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
18815 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018816 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018817 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
18818 }
Hoonki Leea34dd892013-02-05 22:56:02 -080018819 }
18820 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
18821 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018822 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018823 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
18824 }
Hoonki Leea34dd892013-02-05 22:56:02 -080018825 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018826
18827 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018828
18829tx_failed:
18830 /* add_station will be called before sending TDLS_SETUP_REQ and
18831 * TDLS_SETUP_RSP and as part of add_station driver will enable
18832 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
18833 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
18834 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
18835 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
18836 */
18837
18838 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
18839 (SIR_MAC_TDLS_SETUP_RSP == action_code))
18840 wlan_hdd_tdls_check_bmps(pAdapter);
18841 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018842}
18843
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018844#if TDLS_MGMT_VERSION2
18845static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
18846 u8 *peer, u8 action_code, u8 dialog_token,
18847 u16 status_code, u32 peer_capability,
18848 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018849#else /* TDLS_MGMT_VERSION2 */
18850#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
18851static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18852 struct net_device *dev,
18853 const u8 *peer, u8 action_code,
18854 u8 dialog_token, u16 status_code,
18855 u32 peer_capability, bool initiator,
18856 const u8 *buf, size_t len)
18857#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18858static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18859 struct net_device *dev,
18860 const u8 *peer, u8 action_code,
18861 u8 dialog_token, u16 status_code,
18862 u32 peer_capability, const u8 *buf,
18863 size_t len)
18864#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
18865static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18866 struct net_device *dev,
18867 u8 *peer, u8 action_code,
18868 u8 dialog_token,
18869 u16 status_code, u32 peer_capability,
18870 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018871#else
18872static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
18873 u8 *peer, u8 action_code, u8 dialog_token,
18874 u16 status_code, const u8 *buf, size_t len)
18875#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018876#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018877{
18878 int ret;
18879
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018880 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018881#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018882 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
18883 dialog_token, status_code,
18884 peer_capability, buf, len);
18885#else /* TDLS_MGMT_VERSION2 */
18886#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
18887 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
18888 dialog_token, status_code,
18889 peer_capability, initiator,
18890 buf, len);
18891#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
18892 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
18893 dialog_token, status_code,
18894 peer_capability, buf, len);
18895#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
18896 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
18897 dialog_token, status_code,
18898 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018899#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018900 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
18901 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018902#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018903#endif
18904 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018905
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018906 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018907}
Atul Mittal115287b2014-07-08 13:26:33 +053018908
18909int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018910#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18911 const u8 *peer,
18912#else
Atul Mittal115287b2014-07-08 13:26:33 +053018913 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018914#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018915 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053018916 cfg80211_exttdls_callback callback)
18917{
18918
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018919 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053018920 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053018921 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053018922 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18923 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
18924 __func__, MAC_ADDR_ARRAY(peer));
18925
18926 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
18927 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
18928
18929 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018930 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
18931 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
18932 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053018933 return -ENOTSUPP;
18934 }
18935
18936 /* To cater the requirement of establishing the TDLS link
18937 * irrespective of the data traffic , get an entry of TDLS peer.
18938 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053018939 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053018940 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
18941 if (pTdlsPeer == NULL) {
18942 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18943 "%s: peer " MAC_ADDRESS_STR " not existing",
18944 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053018945 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053018946 return -EINVAL;
18947 }
18948
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053018949 /* check FW TDLS Off Channel capability */
18950 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053018951 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053018952 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018953 {
18954 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
18955 pTdlsPeer->peerParams.global_operating_class =
18956 tdls_peer_params->global_operating_class;
18957 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
18958 pTdlsPeer->peerParams.min_bandwidth_kbps =
18959 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053018960 /* check configured channel is valid, non dfs and
18961 * not current operating channel */
18962 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
18963 tdls_peer_params->channel)) &&
18964 (pHddStaCtx) &&
18965 (tdls_peer_params->channel !=
18966 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018967 {
18968 pTdlsPeer->isOffChannelConfigured = TRUE;
18969 }
18970 else
18971 {
18972 pTdlsPeer->isOffChannelConfigured = FALSE;
18973 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18974 "%s: Configured Tdls Off Channel is not valid", __func__);
18975
18976 }
18977 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053018978 "%s: tdls_off_channel %d isOffChannelConfigured %d "
18979 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018980 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053018981 pTdlsPeer->isOffChannelConfigured,
18982 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018983 }
18984 else
18985 {
18986 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053018987 "%s: TDLS off channel FW capability %d, "
18988 "host capab %d or Invalid TDLS Peer Params", __func__,
18989 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
18990 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018991 }
18992
Atul Mittal115287b2014-07-08 13:26:33 +053018993 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
18994
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018995 mutex_unlock(&pHddCtx->tdls_lock);
18996
Atul Mittal115287b2014-07-08 13:26:33 +053018997 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18998 " %s TDLS Add Force Peer Failed",
18999 __func__);
19000 return -EINVAL;
19001 }
19002 /*EXT TDLS*/
19003
19004 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019005 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019006 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19007 " %s TDLS set callback Failed",
19008 __func__);
19009 return -EINVAL;
19010 }
19011
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019012 mutex_unlock(&pHddCtx->tdls_lock);
19013
Atul Mittal115287b2014-07-08 13:26:33 +053019014 return(0);
19015
19016}
19017
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019018int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
19019#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19020 const u8 *peer
19021#else
19022 u8 *peer
19023#endif
19024)
Atul Mittal115287b2014-07-08 13:26:33 +053019025{
19026
19027 hddTdlsPeer_t *pTdlsPeer;
19028 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053019029
Atul Mittal115287b2014-07-08 13:26:33 +053019030 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19031 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
19032 __func__, MAC_ADDR_ARRAY(peer));
19033
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053019034 if (0 != wlan_hdd_validate_context(pHddCtx)) {
19035 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
19036 return -EINVAL;
19037 }
19038
Atul Mittal115287b2014-07-08 13:26:33 +053019039 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
19040 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
19041
19042 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019043 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
19044 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
19045 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053019046 return -ENOTSUPP;
19047 }
19048
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019049 mutex_lock(&pHddCtx->tdls_lock);
19050 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Atul Mittal115287b2014-07-08 13:26:33 +053019051
19052 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019053 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019054 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019055 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053019056 __func__, MAC_ADDR_ARRAY(peer));
19057 return -EINVAL;
19058 }
19059 else {
19060 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
19061 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053019062 hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_EXT_CTRL,
19063 pTdlsPeer->peerMac);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019064 /* if channel switch is configured, reset
19065 the channel for this peer */
19066 if (TRUE == pTdlsPeer->isOffChannelConfigured)
19067 {
19068 pTdlsPeer->peerParams.channel = 0;
19069 pTdlsPeer->isOffChannelConfigured = FALSE;
19070 }
Atul Mittal115287b2014-07-08 13:26:33 +053019071 }
19072
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019073 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019074 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019075 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053019076 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019077 }
Atul Mittal115287b2014-07-08 13:26:33 +053019078
19079 /*EXT TDLS*/
19080
19081 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019082 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019083 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19084 " %s TDLS set callback Failed",
19085 __func__);
19086 return -EINVAL;
19087 }
Atul Mittal115287b2014-07-08 13:26:33 +053019088
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019089 mutex_unlock(&pHddCtx->tdls_lock);
19090
19091 return(0);
Atul Mittal115287b2014-07-08 13:26:33 +053019092}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019093static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019094#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19095 const u8 *peer,
19096#else
19097 u8 *peer,
19098#endif
19099 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019100{
19101 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19102 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019103 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019104 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019105
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019106 ENTER();
19107
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053019108 if (!pAdapter) {
19109 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
19110 return -EINVAL;
19111 }
19112
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019113 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19114 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
19115 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019116 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019117 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019118 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070019119 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019120 return -EINVAL;
19121 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080019122
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019123 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019124 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080019125 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019126 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080019127 }
19128
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019129
19130 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080019131 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019132 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080019133 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019134 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
19135 "Cannot process TDLS commands",
19136 pHddCtx->cfg_ini->fEnableTDLSSupport,
19137 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019138 return -ENOTSUPP;
19139 }
19140
19141 switch (oper) {
19142 case NL80211_TDLS_ENABLE_LINK:
19143 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019144 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019145 long ret;
Hanumantha Reddy Pothulada389492016-02-11 17:29:27 +053019146 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams = { {0}, 0,
19147 0, 0, 0, 0, 0, 0, {0}, 0, {0} };
Agarwal Ashish16020c42014-12-29 22:01:11 +053019148 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019149 tANI_U16 numCurrTdlsPeers = 0;
19150 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053019151 tANI_U8 suppChannelLen = 0;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019152 tSirMacAddr peerMac;
19153 int channel;
19154 tTDLSLinkStatus peer_status = eTDLS_LINK_IDLE;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019155
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019156 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19157 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
19158 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019159
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019160 mutex_lock(&pHddCtx->tdls_lock);
19161 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053019162 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053019163 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019164 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053019165 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
19166 " (oper %d) not exsting. ignored",
19167 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
19168 return -EINVAL;
19169 }
19170
19171 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19172 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
19173 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
19174 "NL80211_TDLS_ENABLE_LINK");
19175
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070019176 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
19177 {
19178 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
19179 MAC_ADDRESS_STR " failed",
19180 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019181 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070019182 return -EINVAL;
19183 }
19184
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053019185 /* before starting tdls connection, set tdls
19186 * off channel established status to default value */
19187 pTdlsPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019188
19189 mutex_unlock(&pHddCtx->tdls_lock);
19190
Deepthi Gowri2d85bbf2016-07-25 15:43:31 +053019191 wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019192 /* TDLS Off Channel, Disable tdls channel switch,
19193 when there are more than one tdls link */
19194 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053019195 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019196 {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019197 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019198 /* get connected peer and send disable tdls off chan */
19199 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019200 if ((connPeer) &&
19201 (connPeer->isOffChannelSupported == TRUE) &&
19202 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019203 {
19204 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19205 "%s: More then one peer connected, Disable "
19206 "TDLS channel switch", __func__);
19207
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053019208 connPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019209 vos_mem_copy(peerMac, connPeer->peerMac, sizeof (tSirMacAddr));
19210 channel = connPeer->peerParams.channel;
19211
19212 mutex_unlock(&pHddCtx->tdls_lock);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019213
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019214 ret = sme_SendTdlsChanSwitchReq(
19215 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019216 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019217 peerMac,
19218 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019219 TDLS_OFF_CHANNEL_BW_OFFSET,
19220 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019221 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019222 hddLog(VOS_TRACE_LEVEL_ERROR,
19223 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019224 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019225 }
19226 else
19227 {
19228 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19229 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019230 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019231 "isOffChannelConfigured %d",
19232 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019233 (connPeer ? (connPeer->isOffChannelSupported)
19234 : -1),
19235 (connPeer ? (connPeer->isOffChannelConfigured)
19236 : -1));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019237 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019238 }
19239 }
19240
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019241 mutex_lock(&pHddCtx->tdls_lock);
19242 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
19243 if ( NULL == pTdlsPeer ) {
19244 mutex_unlock(&pHddCtx->tdls_lock);
19245 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19246 "%s: " MAC_ADDRESS_STR
19247 " (oper %d) peer got freed in other context. ignored",
19248 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
19249 return -EINVAL;
19250 }
19251 peer_status = pTdlsPeer->link_status;
19252 mutex_unlock(&pHddCtx->tdls_lock);
19253
19254 if (eTDLS_LINK_CONNECTED != peer_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019255 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019256 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053019257
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019258 if (0 != wlan_hdd_tdls_get_link_establish_params(
19259 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019260 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019261 return -EINVAL;
19262 }
19263 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053019264
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019265 ret = sme_SendTdlsLinkEstablishParams(
19266 WLAN_HDD_GET_HAL_CTX(pAdapter),
19267 pAdapter->sessionId, peer,
19268 &tdlsLinkEstablishParams);
19269 if (ret != VOS_STATUS_SUCCESS) {
19270 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
19271 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019272 /* Send TDLS peer UAPSD capabilities to the firmware and
19273 * register with the TL on after the response for this operation
19274 * is received .
19275 */
19276 ret = wait_for_completion_interruptible_timeout(
19277 &pAdapter->tdls_link_establish_req_comp,
19278 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
Masti, Narayanraddie1892a52015-12-15 15:01:01 +053019279
19280 mutex_lock(&pHddCtx->tdls_lock);
19281 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
19282 if ( NULL == pTdlsPeer ) {
19283 mutex_unlock(&pHddCtx->tdls_lock);
19284 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19285 "%s %d: " MAC_ADDRESS_STR
19286 " (oper %d) peer got freed in other context. ignored",
19287 __func__, __LINE__, MAC_ADDR_ARRAY(peer),
19288 (int)oper);
19289 return -EINVAL;
19290 }
19291 peer_status = pTdlsPeer->link_status;
19292 mutex_unlock(&pHddCtx->tdls_lock);
19293
19294 if (ret <= 0 || (peer_status == eTDLS_LINK_TEARING))
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019295 {
19296 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019297 FL("Link Establish Request Failed Status %ld"),
19298 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019299 return -EINVAL;
19300 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053019301 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019302
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019303 mutex_lock(&pHddCtx->tdls_lock);
19304 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
19305 if ( NULL == pTdlsPeer ) {
19306 mutex_unlock(&pHddCtx->tdls_lock);
19307 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19308 "%s: " MAC_ADDRESS_STR
19309 " (oper %d) peer got freed in other context. ignored",
19310 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
19311 return -EINVAL;
19312 }
19313
Atul Mittal115287b2014-07-08 13:26:33 +053019314 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
19315 eTDLS_LINK_CONNECTED,
19316 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053019317 staDesc.ucSTAId = pTdlsPeer->staId;
19318 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053019319
19320 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19321 "%s: tdlsLinkEstablishParams of peer "
19322 MAC_ADDRESS_STR "uapsdQueues: %d"
19323 "qos: %d maxSp: %d isBufSta: %d isOffChannelSupported: %d"
19324 "isResponder: %d peerstaId: %d",
19325 __func__,
19326 MAC_ADDR_ARRAY(tdlsLinkEstablishParams.peerMac),
19327 tdlsLinkEstablishParams.uapsdQueues,
19328 tdlsLinkEstablishParams.qos,
19329 tdlsLinkEstablishParams.maxSp,
19330 tdlsLinkEstablishParams.isBufSta,
19331 tdlsLinkEstablishParams.isOffChannelSupported,
19332 tdlsLinkEstablishParams.isResponder,
19333 pTdlsPeer->staId);
19334
19335 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19336 "%s: StaDesc ucSTAId: %d ucQosEnabled: %d",
19337 __func__,
19338 staDesc.ucSTAId,
19339 staDesc.ucQosEnabled);
19340
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019341 ret = WLANTL_UpdateTdlsSTAClient(
19342 pHddCtx->pvosContext,
19343 &staDesc);
19344 if (ret != VOS_STATUS_SUCCESS) {
19345 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
19346 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053019347
Gopichand Nakkala471708b2013-06-04 20:03:01 +053019348 /* Mark TDLS client Authenticated .*/
19349 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
19350 pTdlsPeer->staId,
19351 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070019352 if (VOS_STATUS_SUCCESS == status)
19353 {
Hoonki Lee14621352013-04-16 17:51:19 -070019354 if (pTdlsPeer->is_responder == 0)
19355 {
19356 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053019357 tdlsConnInfo_t *tdlsInfo;
19358
19359 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
19360
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053019361 if (!vos_timer_is_initialized(
19362 &pTdlsPeer->initiatorWaitTimeoutTimer))
19363 {
19364 /* Initialize initiator wait callback */
19365 vos_timer_init(
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053019366 &pTdlsPeer->initiatorWaitTimeoutTimer,
19367 VOS_TIMER_TYPE_SW,
19368 wlan_hdd_tdls_initiator_wait_cb,
19369 tdlsInfo);
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053019370 }
Hoonki Lee14621352013-04-16 17:51:19 -070019371 wlan_hdd_tdls_timer_restart(pAdapter,
19372 &pTdlsPeer->initiatorWaitTimeoutTimer,
19373 WAIT_TIME_TDLS_INITIATOR);
19374 /* suspend initiator TX until it receives direct packet from the
19375 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019376 ret = WLANTL_SuspendDataTx(
19377 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
19378 &staId, NULL);
19379 if (ret != VOS_STATUS_SUCCESS) {
19380 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
19381 }
Hoonki Lee14621352013-04-16 17:51:19 -070019382 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019383
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053019384 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019385 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053019386 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019387 suppChannelLen =
19388 tdlsLinkEstablishParams.supportedChannelsLen;
19389
19390 if ((suppChannelLen > 0) &&
19391 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
19392 {
19393 tANI_U8 suppPeerChannel = 0;
19394 int i = 0;
19395 for (i = 0U; i < suppChannelLen; i++)
19396 {
19397 suppPeerChannel =
19398 tdlsLinkEstablishParams.supportedChannels[i];
19399
19400 pTdlsPeer->isOffChannelSupported = FALSE;
19401 if (suppPeerChannel ==
19402 pTdlsPeer->peerParams.channel)
19403 {
19404 pTdlsPeer->isOffChannelSupported = TRUE;
19405 break;
19406 }
19407 }
19408 }
19409 else
19410 {
19411 pTdlsPeer->isOffChannelSupported = FALSE;
19412 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053019413 }
19414 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19415 "%s: TDLS channel switch request for channel "
19416 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019417 "%d isOffChannelSupported %d", __func__,
19418 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053019419 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019420 suppChannelLen,
19421 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053019422
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019423 /* TDLS Off Channel, Enable tdls channel switch,
19424 when their is only one tdls link and it supports */
19425 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
19426 if ((numCurrTdlsPeers == 1) &&
19427 (TRUE == pTdlsPeer->isOffChannelSupported) &&
19428 (TRUE == pTdlsPeer->isOffChannelConfigured))
19429 {
19430 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19431 "%s: Send TDLS channel switch request for channel %d",
19432 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053019433
19434 pTdlsPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019435 vos_mem_copy(peerMac, pTdlsPeer->peerMac, sizeof (tSirMacAddr));
19436 channel = pTdlsPeer->peerParams.channel;
19437
19438 mutex_unlock(&pHddCtx->tdls_lock);
19439
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019440 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
19441 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019442 peerMac,
19443 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019444 TDLS_OFF_CHANNEL_BW_OFFSET,
19445 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019446 if (ret != VOS_STATUS_SUCCESS) {
19447 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
19448 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019449 }
19450 else
19451 {
19452 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19453 "%s: TDLS channel switch request not sent"
19454 " numCurrTdlsPeers %d "
19455 "isOffChannelSupported %d "
19456 "isOffChannelConfigured %d",
19457 __func__, numCurrTdlsPeers,
19458 pTdlsPeer->isOffChannelSupported,
19459 pTdlsPeer->isOffChannelConfigured);
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019460 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019461 }
19462
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070019463 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019464 else
19465 mutex_unlock(&pHddCtx->tdls_lock);
19466
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019467 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053019468
19469 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053019470 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
19471 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053019472 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053019473 int ac;
19474 uint8 ucAc[4] = { WLANTL_AC_VO,
19475 WLANTL_AC_VI,
19476 WLANTL_AC_BK,
19477 WLANTL_AC_BE };
19478 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
19479 for(ac=0; ac < 4; ac++)
19480 {
19481 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
19482 pTdlsPeer->staId, ucAc[ac],
19483 tlTid[ac], tlTid[ac], 0, 0,
19484 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019485 if (status != VOS_STATUS_SUCCESS) {
19486 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
19487 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053019488 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053019489 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019490 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019491
Bhargav Shah66896792015-10-01 18:17:37 +053019492 /* stop TCP delack timer if TDLS is enable */
19493 set_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
19494 hdd_manage_delack_timer(pHddCtx);
Abhishek Singh67fa6bc2016-01-05 15:57:19 +053019495 hdd_wlan_tdls_enable_link_event(peer,
19496 pTdlsPeer->isOffChannelSupported,
19497 pTdlsPeer->isOffChannelConfigured,
19498 pTdlsPeer->isOffChannelEstablished);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019499 }
19500 break;
19501 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080019502 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019503 tANI_U16 numCurrTdlsPeers = 0;
19504 hddTdlsPeer_t *connPeer = NULL;
19505
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019506 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19507 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
19508 __func__, MAC_ADDR_ARRAY(peer));
19509
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019510 mutex_lock(&pHddCtx->tdls_lock);
19511 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Sunil Dutt41de4e22013-11-14 18:09:02 +053019512
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019513
Sunil Dutt41de4e22013-11-14 18:09:02 +053019514 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019515 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053019516 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
19517 " (oper %d) not exsting. ignored",
19518 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
19519 return -EINVAL;
19520 }
19521
19522 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19523 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
19524 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
19525 "NL80211_TDLS_DISABLE_LINK");
19526
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019527 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080019528 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019529 long status;
19530
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053019531 /* set tdls off channel status to false for this peer */
19532 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053019533 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
19534 eTDLS_LINK_TEARING,
19535 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
19536 eTDLS_LINK_UNSPECIFIED:
19537 eTDLS_LINK_DROPPED_BY_REMOTE);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019538 mutex_unlock(&pHddCtx->tdls_lock);
19539
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019540 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
19541
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019542 status = sme_DeleteTdlsPeerSta(
19543 WLAN_HDD_GET_HAL_CTX(pAdapter),
19544 pAdapter->sessionId, peer );
19545 if (status != VOS_STATUS_SUCCESS) {
19546 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
19547 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019548
19549 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
19550 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019551
19552 mutex_lock(&pHddCtx->tdls_lock);
19553 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
19554 if ( NULL == pTdlsPeer ) {
19555 mutex_unlock(&pHddCtx->tdls_lock);
19556 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
19557 " peer was freed in other context",
19558 __func__, MAC_ADDR_ARRAY(peer));
19559 return -EINVAL;
19560 }
19561
Atul Mittal271a7652014-09-12 13:18:22 +053019562 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053019563 eTDLS_LINK_IDLE,
19564 eTDLS_LINK_UNSPECIFIED);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019565 mutex_unlock(&pHddCtx->tdls_lock);
19566
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019567 if (status <= 0)
19568 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019569 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19570 "%s: Del station failed status %ld",
19571 __func__, status);
19572 return -EPERM;
19573 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019574
19575 /* TDLS Off Channel, Enable tdls channel switch,
19576 when their is only one tdls link and it supports */
19577 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
19578 if (numCurrTdlsPeers == 1)
19579 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019580 tSirMacAddr peerMac;
19581 int channel;
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053019582
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019583 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019584 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053019585
19586 if (connPeer == NULL) {
19587 mutex_unlock(&pHddCtx->tdls_lock);
19588 hddLog(VOS_TRACE_LEVEL_ERROR,
19589 "%s connPeer is NULL", __func__);
19590 return -EINVAL;
19591 }
19592
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019593 vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr));
19594 channel = connPeer->peerParams.channel;
19595
19596 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19597 "%s: TDLS channel switch "
19598 "isOffChannelSupported %d "
19599 "isOffChannelConfigured %d "
19600 "isOffChannelEstablished %d",
19601 __func__,
19602 (connPeer ? connPeer->isOffChannelSupported : -1),
19603 (connPeer ? connPeer->isOffChannelConfigured : -1),
19604 (connPeer ? connPeer->isOffChannelEstablished : -1));
19605
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019606 if ((connPeer) &&
19607 (connPeer->isOffChannelSupported == TRUE) &&
19608 (connPeer->isOffChannelConfigured == TRUE))
19609 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053019610 connPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019611 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019612 status = sme_SendTdlsChanSwitchReq(
19613 WLAN_HDD_GET_HAL_CTX(pAdapter),
19614 pAdapter->sessionId,
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019615 peerMac,
19616 channel,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019617 TDLS_OFF_CHANNEL_BW_OFFSET,
19618 TDLS_CHANNEL_SWITCH_ENABLE);
19619 if (status != VOS_STATUS_SUCCESS) {
19620 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
19621 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019622 }
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019623 else
19624 mutex_unlock(&pHddCtx->tdls_lock);
19625 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019626 else
19627 {
19628 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19629 "%s: TDLS channel switch request not sent "
19630 "numCurrTdlsPeers %d ",
19631 __func__, numCurrTdlsPeers);
19632 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080019633 }
19634 else
19635 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019636 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019637 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19638 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080019639 }
Bhargav Shah66896792015-10-01 18:17:37 +053019640 if (numCurrTdlsPeers == 0) {
19641 /* start TCP delack timer if TDLS is disable */
19642 clear_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
19643 hdd_manage_delack_timer(pHddCtx);
19644 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080019645 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019646 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019647 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053019648 {
Atul Mittal115287b2014-07-08 13:26:33 +053019649 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053019650
Atul Mittal115287b2014-07-08 13:26:33 +053019651 if (0 != status)
19652 {
19653 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019654 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053019655 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053019656 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053019657 break;
19658 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019659 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053019660 {
Atul Mittal115287b2014-07-08 13:26:33 +053019661 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
19662 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019663 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053019664 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053019665
Atul Mittal115287b2014-07-08 13:26:33 +053019666 if (0 != status)
19667 {
19668 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019669 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053019670 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053019671 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053019672 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053019673 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019674 case NL80211_TDLS_DISCOVERY_REQ:
19675 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019676 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019677 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019678 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019679 return -ENOTSUPP;
19680 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019681 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19682 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019683 return -ENOTSUPP;
19684 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019685
19686 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019687 return 0;
19688}
Chilam NG571c65a2013-01-19 12:27:36 +053019689
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019690static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019691#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19692 const u8 *peer,
19693#else
19694 u8 *peer,
19695#endif
19696 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019697{
19698 int ret;
19699
19700 vos_ssr_protect(__func__);
19701 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
19702 vos_ssr_unprotect(__func__);
19703
19704 return ret;
19705}
19706
Chilam NG571c65a2013-01-19 12:27:36 +053019707int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
19708 struct net_device *dev, u8 *peer)
19709{
Arif Hussaina7c8e412013-11-20 11:06:42 -080019710 hddLog(VOS_TRACE_LEVEL_INFO,
19711 "tdls send discover req: "MAC_ADDRESS_STR,
19712 MAC_ADDR_ARRAY(peer));
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019713#if TDLS_MGMT_VERSION2
19714 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19715 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
19716#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019717#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
19718 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19719 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
19720#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
19721 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19722 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
19723#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
19724 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19725 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
19726#else
Chilam NG571c65a2013-01-19 12:27:36 +053019727 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19728 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019729#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019730#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053019731}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019732#endif
19733
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019734#ifdef WLAN_FEATURE_GTK_OFFLOAD
19735/*
19736 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
19737 * Callback rountine called upon receiving response for
19738 * get offload info
19739 */
19740void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
19741 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
19742{
19743
19744 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019745 tANI_U8 tempReplayCounter[8];
19746 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019747
19748 ENTER();
19749
19750 if (NULL == pAdapter)
19751 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053019752 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019753 "%s: HDD adapter is Null", __func__);
19754 return ;
19755 }
19756
19757 if (NULL == pGtkOffloadGetInfoRsp)
19758 {
19759 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19760 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
19761 return ;
19762 }
19763
19764 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
19765 {
19766 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19767 "%s: wlan Failed to get replay counter value",
19768 __func__);
19769 return ;
19770 }
19771
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019772 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
19773 /* Update replay counter */
19774 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
19775 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
19776
19777 {
19778 /* changing from little to big endian since supplicant
19779 * works on big endian format
19780 */
19781 int i;
19782 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
19783
19784 for (i = 0; i < 8; i++)
19785 {
19786 tempReplayCounter[7-i] = (tANI_U8)p[i];
19787 }
19788 }
19789
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019790 /* Update replay counter to NL */
19791 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019792 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019793}
19794
19795/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019796 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019797 * This function is used to offload GTK rekeying job to the firmware.
19798 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019799int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019800 struct cfg80211_gtk_rekey_data *data)
19801{
19802 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19803 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
19804 hdd_station_ctx_t *pHddStaCtx;
19805 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019806 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019807 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019808 eHalStatus status = eHAL_STATUS_FAILURE;
19809
19810 ENTER();
19811
19812 if (NULL == pAdapter)
19813 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019814 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019815 "%s: HDD adapter is Null", __func__);
19816 return -ENODEV;
19817 }
19818
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019819 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19820 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
19821 pAdapter->sessionId, pAdapter->device_mode));
19822
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019823 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019824 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019825 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019826 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019827 }
19828
19829 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
19830 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
19831 if (NULL == hHal)
19832 {
19833 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19834 "%s: HAL context is Null!!!", __func__);
19835 return -EAGAIN;
19836 }
19837
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019838 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
19839 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
19840 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
19841 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019842 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019843 {
19844 /* changing from big to little endian since driver
19845 * works on little endian format
19846 */
19847 tANI_U8 *p =
19848 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
19849 int i;
19850
19851 for (i = 0; i < 8; i++)
19852 {
19853 p[7-i] = data->replay_ctr[i];
19854 }
19855 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019856
19857 if (TRUE == pHddCtx->hdd_wlan_suspended)
19858 {
19859 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019860 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
19861 sizeof (tSirGtkOffloadParams));
19862 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019863 pAdapter->sessionId);
19864
19865 if (eHAL_STATUS_SUCCESS != status)
19866 {
19867 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19868 "%s: sme_SetGTKOffload failed, returned %d",
19869 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053019870
19871 /* Need to clear any trace of key value in the memory.
19872 * Thus zero out the memory even though it is local
19873 * variable.
19874 */
19875 vos_mem_zero(&hddGtkOffloadReqParams,
19876 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019877 return status;
19878 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019879 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19880 "%s: sme_SetGTKOffload successfull", __func__);
19881 }
19882 else
19883 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019884 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19885 "%s: wlan not suspended GTKOffload request is stored",
19886 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019887 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019888
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053019889 /* Need to clear any trace of key value in the memory.
19890 * Thus zero out the memory even though it is local
19891 * variable.
19892 */
19893 vos_mem_zero(&hddGtkOffloadReqParams,
19894 sizeof(hddGtkOffloadReqParams));
19895
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019896 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019897 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019898}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019899
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019900int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
19901 struct cfg80211_gtk_rekey_data *data)
19902{
19903 int ret;
19904
19905 vos_ssr_protect(__func__);
19906 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
19907 vos_ssr_unprotect(__func__);
19908
19909 return ret;
19910}
19911#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019912/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019913 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019914 * This function is used to set access control policy
19915 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019916static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
19917 struct net_device *dev,
19918 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019919{
19920 int i;
19921 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19922 hdd_hostapd_state_t *pHostapdState;
19923 tsap_Config_t *pConfig;
19924 v_CONTEXT_t pVosContext = NULL;
19925 hdd_context_t *pHddCtx;
19926 int status;
19927
19928 ENTER();
19929
19930 if (NULL == pAdapter)
19931 {
19932 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19933 "%s: HDD adapter is Null", __func__);
19934 return -ENODEV;
19935 }
19936
19937 if (NULL == params)
19938 {
19939 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19940 "%s: params is Null", __func__);
19941 return -EINVAL;
19942 }
19943
19944 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19945 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019946 if (0 != status)
19947 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019948 return status;
19949 }
19950
19951 pVosContext = pHddCtx->pvosContext;
19952 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
19953
19954 if (NULL == pHostapdState)
19955 {
19956 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19957 "%s: pHostapdState is Null", __func__);
19958 return -EINVAL;
19959 }
19960
19961 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
19962 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019963 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19964 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
19965 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019966
19967 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
19968 {
19969 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
19970
19971 /* default value */
19972 pConfig->num_accept_mac = 0;
19973 pConfig->num_deny_mac = 0;
19974
19975 /**
19976 * access control policy
19977 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
19978 * listed in hostapd.deny file.
19979 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
19980 * listed in hostapd.accept file.
19981 */
19982 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
19983 {
19984 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
19985 }
19986 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
19987 {
19988 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
19989 }
19990 else
19991 {
19992 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19993 "%s:Acl Policy : %d is not supported",
19994 __func__, params->acl_policy);
19995 return -ENOTSUPP;
19996 }
19997
19998 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
19999 {
20000 pConfig->num_accept_mac = params->n_acl_entries;
20001 for (i = 0; i < params->n_acl_entries; i++)
20002 {
20003 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20004 "** Add ACL MAC entry %i in WhiletList :"
20005 MAC_ADDRESS_STR, i,
20006 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
20007
20008 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
20009 sizeof(qcmacaddr));
20010 }
20011 }
20012 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
20013 {
20014 pConfig->num_deny_mac = params->n_acl_entries;
20015 for (i = 0; i < params->n_acl_entries; i++)
20016 {
20017 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20018 "** Add ACL MAC entry %i in BlackList :"
20019 MAC_ADDRESS_STR, i,
20020 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
20021
20022 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
20023 sizeof(qcmacaddr));
20024 }
20025 }
20026
20027 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
20028 {
20029 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20030 "%s: SAP Set Mac Acl fail", __func__);
20031 return -EINVAL;
20032 }
20033 }
20034 else
20035 {
20036 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053020037 "%s: Invalid device_mode = %s (%d)",
20038 __func__, hdd_device_modetoString(pAdapter->device_mode),
20039 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020040 return -EINVAL;
20041 }
20042
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020043 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020044 return 0;
20045}
20046
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020047static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
20048 struct net_device *dev,
20049 const struct cfg80211_acl_data *params)
20050{
20051 int ret;
20052 vos_ssr_protect(__func__);
20053 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
20054 vos_ssr_unprotect(__func__);
20055
20056 return ret;
20057}
20058
Leo Chang9056f462013-08-01 19:21:11 -070020059#ifdef WLAN_NL80211_TESTMODE
20060#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070020061void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070020062(
20063 void *pAdapter,
20064 void *indCont
20065)
20066{
Leo Changd9df8aa2013-09-26 13:32:26 -070020067 tSirLPHBInd *lphbInd;
20068 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053020069 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070020070
20071 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070020072 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070020073
c_hpothu73f35e62014-04-18 13:40:08 +053020074 if (pAdapter == NULL)
20075 {
20076 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20077 "%s: pAdapter is NULL\n",__func__);
20078 return;
20079 }
20080
Leo Chang9056f462013-08-01 19:21:11 -070020081 if (NULL == indCont)
20082 {
20083 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070020084 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070020085 return;
20086 }
20087
c_hpothu73f35e62014-04-18 13:40:08 +053020088 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070020089 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070020090 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053020091 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070020092 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070020093 GFP_ATOMIC);
20094 if (!skb)
20095 {
20096 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20097 "LPHB timeout, NL buffer alloc fail");
20098 return;
20099 }
20100
Leo Changac3ba772013-10-07 09:47:04 -070020101 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070020102 {
20103 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20104 "WLAN_HDD_TM_ATTR_CMD put fail");
20105 goto nla_put_failure;
20106 }
Leo Changac3ba772013-10-07 09:47:04 -070020107 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070020108 {
20109 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20110 "WLAN_HDD_TM_ATTR_TYPE put fail");
20111 goto nla_put_failure;
20112 }
Leo Changac3ba772013-10-07 09:47:04 -070020113 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070020114 sizeof(tSirLPHBInd), lphbInd))
20115 {
20116 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20117 "WLAN_HDD_TM_ATTR_DATA put fail");
20118 goto nla_put_failure;
20119 }
Leo Chang9056f462013-08-01 19:21:11 -070020120 cfg80211_testmode_event(skb, GFP_ATOMIC);
20121 return;
20122
20123nla_put_failure:
20124 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20125 "NLA Put fail");
20126 kfree_skb(skb);
20127
20128 return;
20129}
20130#endif /* FEATURE_WLAN_LPHB */
20131
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020132static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070020133{
20134 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
20135 int err = 0;
20136#ifdef FEATURE_WLAN_LPHB
20137 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070020138 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020139
20140 ENTER();
20141
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053020142 err = wlan_hdd_validate_context(pHddCtx);
20143 if (0 != err)
20144 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053020145 return err;
20146 }
Leo Chang9056f462013-08-01 19:21:11 -070020147#endif /* FEATURE_WLAN_LPHB */
20148
20149 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
20150 if (err)
20151 {
20152 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20153 "%s Testmode INV ATTR", __func__);
20154 return err;
20155 }
20156
20157 if (!tb[WLAN_HDD_TM_ATTR_CMD])
20158 {
20159 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20160 "%s Testmode INV CMD", __func__);
20161 return -EINVAL;
20162 }
20163
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053020164 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20165 TRACE_CODE_HDD_CFG80211_TESTMODE,
20166 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070020167 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
20168 {
20169#ifdef FEATURE_WLAN_LPHB
20170 /* Low Power Heartbeat configuration request */
20171 case WLAN_HDD_TM_CMD_WLAN_HB:
20172 {
20173 int buf_len;
20174 void *buf;
20175 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080020176 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070020177
20178 if (!tb[WLAN_HDD_TM_ATTR_DATA])
20179 {
20180 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20181 "%s Testmode INV DATA", __func__);
20182 return -EINVAL;
20183 }
20184
20185 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
20186 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080020187
Manjeet Singh3c577442017-02-10 19:03:38 +053020188 if (buf_len > sizeof(*hb_params)) {
20189 hddLog(LOGE, FL("buf_len=%d exceeded hb_params size limit"),
20190 buf_len);
20191 return -ERANGE;
20192 }
20193
Amar Singhal05852702014-02-04 14:40:00 -080020194 hb_params_temp =(tSirLPHBReq *)buf;
20195 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
20196 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
20197 return -EINVAL;
20198
Leo Chang9056f462013-08-01 19:21:11 -070020199 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
20200 if (NULL == hb_params)
20201 {
20202 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20203 "%s Request Buffer Alloc Fail", __func__);
20204 return -EINVAL;
20205 }
20206
20207 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070020208 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
20209 hb_params,
20210 wlan_hdd_cfg80211_lphb_ind_handler);
20211 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070020212 {
Leo Changd9df8aa2013-09-26 13:32:26 -070020213 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20214 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070020215 vos_mem_free(hb_params);
20216 }
Leo Chang9056f462013-08-01 19:21:11 -070020217 return 0;
20218 }
20219#endif /* FEATURE_WLAN_LPHB */
20220 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020221 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20222 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070020223 return -EOPNOTSUPP;
20224 }
20225
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020226 EXIT();
20227 return err;
Leo Chang9056f462013-08-01 19:21:11 -070020228}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020229
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053020230static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
20231#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
20232 struct wireless_dev *wdev,
20233#endif
20234 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020235{
20236 int ret;
20237
20238 vos_ssr_protect(__func__);
20239 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
20240 vos_ssr_unprotect(__func__);
20241
20242 return ret;
20243}
Leo Chang9056f462013-08-01 19:21:11 -070020244#endif /* CONFIG_NL80211_TESTMODE */
20245
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053020246extern void hdd_set_wlan_suspend_mode(bool suspend);
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020247static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020248 struct net_device *dev,
20249 int idx, struct survey_info *survey)
20250{
20251 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20252 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053020253 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020254 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053020255 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020256 v_S7_t snr,rssi;
20257 int status, i, j, filled = 0;
20258
20259 ENTER();
20260
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020261 if (NULL == pAdapter)
20262 {
20263 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20264 "%s: HDD adapter is Null", __func__);
20265 return -ENODEV;
20266 }
20267
20268 if (NULL == wiphy)
20269 {
20270 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20271 "%s: wiphy is Null", __func__);
20272 return -ENODEV;
20273 }
20274
20275 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
20276 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020277 if (0 != status)
20278 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020279 return status;
20280 }
20281
Mihir Sheted9072e02013-08-21 17:02:29 +053020282 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
20283
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020284 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053020285 0 != pAdapter->survey_idx ||
20286 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020287 {
20288 /* The survey dump ops when implemented completely is expected to
20289 * return a survey of all channels and the ops is called by the
20290 * kernel with incremental values of the argument 'idx' till it
20291 * returns -ENONET. But we can only support the survey for the
20292 * operating channel for now. survey_idx is used to track
20293 * that the ops is called only once and then return -ENONET for
20294 * the next iteration
20295 */
20296 pAdapter->survey_idx = 0;
20297 return -ENONET;
20298 }
20299
Mukul Sharma9d5233b2015-06-11 20:28:20 +053020300 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
20301 {
20302 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20303 "%s: Roaming in progress, hence return ", __func__);
20304 return -ENONET;
20305 }
20306
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020307 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
20308
20309 wlan_hdd_get_snr(pAdapter, &snr);
20310 wlan_hdd_get_rssi(pAdapter, &rssi);
20311
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053020312 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20313 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
20314 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020315 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
20316 hdd_wlan_get_freq(channel, &freq);
20317
20318
20319 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
20320 {
20321 if (NULL == wiphy->bands[i])
20322 {
20323 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
20324 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
20325 continue;
20326 }
20327
20328 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
20329 {
20330 struct ieee80211_supported_band *band = wiphy->bands[i];
20331
20332 if (band->channels[j].center_freq == (v_U16_t)freq)
20333 {
20334 survey->channel = &band->channels[j];
20335 /* The Rx BDs contain SNR values in dB for the received frames
20336 * while the supplicant expects noise. So we calculate and
20337 * return the value of noise (dBm)
20338 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
20339 */
20340 survey->noise = rssi - snr;
20341 survey->filled = SURVEY_INFO_NOISE_DBM;
20342 filled = 1;
20343 }
20344 }
20345 }
20346
20347 if (filled)
20348 pAdapter->survey_idx = 1;
20349 else
20350 {
20351 pAdapter->survey_idx = 0;
20352 return -ENONET;
20353 }
20354
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020355 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020356 return 0;
20357}
20358
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020359static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
20360 struct net_device *dev,
20361 int idx, struct survey_info *survey)
20362{
20363 int ret;
20364
20365 vos_ssr_protect(__func__);
20366 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
20367 vos_ssr_unprotect(__func__);
20368
20369 return ret;
20370}
20371
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020372/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053020373 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020374 * this is called when cfg80211 driver resume
20375 * driver updates latest sched_scan scan result(if any) to cfg80211 database
20376 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053020377int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020378{
20379 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
20380 hdd_adapter_t *pAdapter;
20381 hdd_adapter_list_node_t *pAdapterNode, *pNext;
20382 VOS_STATUS status = VOS_STATUS_SUCCESS;
20383
20384 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020385
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053020386 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020387 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020388 return 0;
20389 }
20390
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053020391 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
20392 NO_SESSION, pHddCtx->isWiphySuspended));
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053020393
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053020394 if (pHddCtx->is_ap_mode_wow_supported)
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053020395 {
20396 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20397 "%s: Resume SoftAP", __func__);
20398 hdd_set_wlan_suspend_mode(false);
20399 }
20400
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020401 spin_lock(&pHddCtx->schedScan_lock);
20402 pHddCtx->isWiphySuspended = FALSE;
20403 if (TRUE != pHddCtx->isSchedScanUpdatePending)
20404 {
20405 spin_unlock(&pHddCtx->schedScan_lock);
20406 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20407 "%s: Return resume is not due to PNO indication", __func__);
20408 return 0;
20409 }
20410 // Reset flag to avoid updatating cfg80211 data old results again
20411 pHddCtx->isSchedScanUpdatePending = FALSE;
20412 spin_unlock(&pHddCtx->schedScan_lock);
20413
20414 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
20415
20416 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
20417 {
20418 pAdapter = pAdapterNode->pAdapter;
20419 if ( (NULL != pAdapter) &&
20420 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
20421 {
20422 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053020423 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020424 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
20425 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053020426 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020427 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053020428 {
20429 /* Acquire wakelock to handle the case where APP's tries to
20430 * suspend immediately after updating the scan results. Whis
20431 * results in app's is in suspended state and not able to
20432 * process the connect request to AP
20433 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053020434 hdd_prevent_suspend_timeout(2000,
20435 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020436 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053020437 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020438
20439 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20440 "%s : cfg80211 scan result database updated", __func__);
20441
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020442 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020443 return 0;
20444
20445 }
20446 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
20447 pAdapterNode = pNext;
20448 }
20449
20450 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20451 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020452 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020453 return 0;
20454}
20455
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053020456int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
20457{
20458 int ret;
20459
20460 vos_ssr_protect(__func__);
20461 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
20462 vos_ssr_unprotect(__func__);
20463
20464 return ret;
20465}
20466
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020467/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053020468 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020469 * this is called when cfg80211 driver suspends
20470 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053020471int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020472 struct cfg80211_wowlan *wow)
20473{
20474 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053020475 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020476
20477 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020478
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053020479 ret = wlan_hdd_validate_context(pHddCtx);
20480 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020481 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053020482 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020483 }
20484
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053020485 if (pHddCtx->is_ap_mode_wow_supported) {
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053020486 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20487 "%s: Suspend SoftAP", __func__);
20488 hdd_set_wlan_suspend_mode(true);
20489 }
20490
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053020491
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053020492 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20493 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
20494 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020495 pHddCtx->isWiphySuspended = TRUE;
20496
20497 EXIT();
20498
20499 return 0;
20500}
20501
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053020502int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
20503 struct cfg80211_wowlan *wow)
20504{
20505 int ret;
20506
20507 vos_ssr_protect(__func__);
20508 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
20509 vos_ssr_unprotect(__func__);
20510
20511 return ret;
20512}
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053020513
20514#ifdef FEATURE_OEM_DATA_SUPPORT
20515static void wlan_hdd_cfg80211_oem_data_rsp_ind_new(void *ctx,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053020516 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053020517{
20518 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
20519
20520 ENTER();
20521
20522 if (wlan_hdd_validate_context(pHddCtx)) {
20523 return;
20524 }
20525 if (!pMsg)
20526 {
20527 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
20528 return;
20529 }
20530
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053020531 send_oem_data_rsp_msg(evLen, pMsg);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053020532
20533 EXIT();
20534 return;
20535
20536}
20537
20538void wlan_hdd_cfg80211_oemdata_callback(void *ctx, const tANI_U16 evType,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053020539 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053020540{
20541 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
20542
20543 ENTER();
20544
20545 if (wlan_hdd_validate_context(pHddCtx)) {
20546 return;
20547 }
20548
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053020549 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d) evLen %d"), evType, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053020550
20551 switch(evType) {
20552 case SIR_HAL_START_OEM_DATA_RSP_IND_NEW:
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053020553 wlan_hdd_cfg80211_oem_data_rsp_ind_new(ctx, pMsg, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053020554 break;
20555 default:
20556 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
20557 break;
20558 }
20559 EXIT();
20560}
20561#endif
20562
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053020563#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
20564 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053020565/**
20566 * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api
20567 * @wiphy: Pointer to wiphy
20568 * @wdev: Pointer to wireless device structure
20569 *
20570 * This function is used to abort an ongoing scan
20571 *
20572 * Return: None
20573 */
20574static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
20575 struct wireless_dev *wdev)
20576{
20577 struct net_device *dev = wdev->netdev;
20578 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
20579 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
20580 int ret;
20581
20582 ENTER();
20583
20584 if (NULL == adapter) {
20585 hddLog(VOS_TRACE_LEVEL_FATAL, FL("HDD adapter is NULL"));
20586 return;
20587 }
20588
20589 ret = wlan_hdd_validate_context(hdd_ctx);
20590 if (0 != ret)
20591 return;
20592
20593 wlan_hdd_scan_abort(adapter);
20594
20595 return;
20596}
20597
20598/**
20599 * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api
20600 * @wiphy: Pointer to wiphy
20601 * @wdev: Pointer to wireless device structure
20602 *
20603 * Return: None
20604 */
20605void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
20606 struct wireless_dev *wdev)
20607{
20608 vos_ssr_protect(__func__);
20609 __wlan_hdd_cfg80211_abort_scan(wiphy, wdev);
20610 vos_ssr_unprotect(__func__);
20611
20612 return;
20613}
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053020614#endif
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053020615
Jeff Johnson295189b2012-06-20 16:38:30 -070020616/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053020617static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070020618{
20619 .add_virtual_intf = wlan_hdd_add_virtual_intf,
20620 .del_virtual_intf = wlan_hdd_del_virtual_intf,
20621 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
20622 .change_station = wlan_hdd_change_station,
20623#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
20624 .add_beacon = wlan_hdd_cfg80211_add_beacon,
20625 .del_beacon = wlan_hdd_cfg80211_del_beacon,
20626 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070020627#else
20628 .start_ap = wlan_hdd_cfg80211_start_ap,
20629 .change_beacon = wlan_hdd_cfg80211_change_beacon,
20630 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070020631#endif
20632 .change_bss = wlan_hdd_cfg80211_change_bss,
20633 .add_key = wlan_hdd_cfg80211_add_key,
20634 .get_key = wlan_hdd_cfg80211_get_key,
20635 .del_key = wlan_hdd_cfg80211_del_key,
20636 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080020637#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070020638 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080020639#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070020640 .scan = wlan_hdd_cfg80211_scan,
20641 .connect = wlan_hdd_cfg80211_connect,
20642 .disconnect = wlan_hdd_cfg80211_disconnect,
20643 .join_ibss = wlan_hdd_cfg80211_join_ibss,
20644 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
20645 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
20646 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
20647 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070020648 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
20649 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053020650 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070020651#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
20652 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
20653 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
20654 .set_txq_params = wlan_hdd_set_txq_params,
20655#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070020656 .get_station = wlan_hdd_cfg80211_get_station,
20657 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
20658 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070020659 .add_station = wlan_hdd_cfg80211_add_station,
20660#ifdef FEATURE_WLAN_LFR
20661 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
20662 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
20663 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
20664#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070020665#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
20666 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
20667#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020668#ifdef FEATURE_WLAN_TDLS
20669 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
20670 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
20671#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020672#ifdef WLAN_FEATURE_GTK_OFFLOAD
20673 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
20674#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020675#ifdef FEATURE_WLAN_SCAN_PNO
20676 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
20677 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
20678#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020679 .resume = wlan_hdd_cfg80211_resume_wlan,
20680 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020681 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070020682#ifdef WLAN_NL80211_TESTMODE
20683 .testmode_cmd = wlan_hdd_cfg80211_testmode,
20684#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020685 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053020686#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
20687 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053020688 .abort_scan = wlan_hdd_cfg80211_abort_scan,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053020689#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070020690};
20691