blob: 53bbdfa3995f5a072b9bc73f33dec4c9d4336fbd [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Abhishek Singhb3e376c2017-01-04 15:27:13 +05302 * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lama7f454d2014-07-24 12:04:06 -070023 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +053026 *
Kiet Lamaa8e15a2014-02-11 23:30:06 -080027 */
Kiet Lam842dad02014-02-18 18:44:02 -080028
29
Kiet Lama7f454d2014-07-24 12:04:06 -070030
31
Jeff Johnson295189b2012-06-20 16:38:30 -070032/**========================================================================
33
34 \file wlan_hdd_cfg80211.c
35
36 \brief WLAN Host Device Driver implementation
37
Jeff Johnson295189b2012-06-20 16:38:30 -070038 ========================================================================*/
39
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070040/**=========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -070041
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070042 EDIT HISTORY FOR FILE
Jeff Johnson295189b2012-06-20 16:38:30 -070043
44
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070045 This section contains comments describing changes made to the module.
46 Notice that changes are listed in reverse chronological order.
Jeff Johnson295189b2012-06-20 16:38:30 -070047
48
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070049 $Header:$ $DateTime: $ $Author: $
Jeff Johnson295189b2012-06-20 16:38:30 -070050
51
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070052 when who what, where, why
Jeff Johnson295189b2012-06-20 16:38:30 -070053 -------- --- --------------------------------------------------------
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070054 21/12/09 Ashwani Created module.
Jeff Johnson295189b2012-06-20 16:38:30 -070055
56 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070057 Ganesh K
Jeff Johnson295189b2012-06-20 16:38:30 -070058 ==========================================================================*/
59
Jeff Johnson295189b2012-06-20 16:38:30 -070060
61#include <linux/version.h>
62#include <linux/module.h>
63#include <linux/kernel.h>
64#include <linux/init.h>
65#include <linux/wireless.h>
66#include <wlan_hdd_includes.h>
67#include <net/arp.h>
68#include <net/cfg80211.h>
69#include <linux/wireless.h>
70#include <wlan_hdd_wowl.h>
71#include <aniGlobal.h>
72#include "ccmApi.h"
73#include "sirParams.h"
74#include "dot11f.h"
75#include "wlan_hdd_assoc.h"
76#include "wlan_hdd_wext.h"
77#include "sme_Api.h"
78#include "wlan_hdd_p2p.h"
79#include "wlan_hdd_cfg80211.h"
80#include "wlan_hdd_hostapd.h"
81#include "sapInternal.h"
82#include "wlan_hdd_softap_tx_rx.h"
83#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053084#include "wlan_hdd_assoc.h"
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053085#include "wlan_hdd_power.h"
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053086#include "wlan_hdd_trace.h"
87#include "vos_types.h"
88#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070089#ifdef WLAN_BTAMP_FEATURE
90#include "bap_hdd_misc.h"
91#endif
92#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080093#include "wlan_hdd_tdls.h"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053094#include "wlan_hdd_wmm.h"
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053095#include "wlan_qct_wda.h"
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053096#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070097#include "wlan_hdd_dev_pwr.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +053098#include "qwlan_version.h"
c_manjeecfd1efb2015-09-25 19:32:34 +053099#include "wlan_logging_sock_svc.h"
Agrawal Ashishcfe83282016-09-29 13:03:45 +0530100#include "wlan_hdd_misc.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +0530101
Jeff Johnson295189b2012-06-20 16:38:30 -0700102
103#define g_mode_rates_size (12)
104#define a_mode_rates_size (8)
105#define FREQ_BASE_80211G (2407)
106#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700107#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530108#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700109#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800110 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700111
112#define HDD2GHZCHAN(freq, chan, flag) { \
113 .band = IEEE80211_BAND_2GHZ, \
114 .center_freq = (freq), \
115 .hw_value = (chan),\
116 .flags = (flag), \
117 .max_antenna_gain = 0 ,\
118 .max_power = 30, \
119}
120
121#define HDD5GHZCHAN(freq, chan, flag) { \
122 .band = IEEE80211_BAND_5GHZ, \
123 .center_freq = (freq), \
124 .hw_value = (chan),\
125 .flags = (flag), \
126 .max_antenna_gain = 0 ,\
127 .max_power = 30, \
128}
129
130#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
131{\
132 .bitrate = rate, \
133 .hw_value = rate_id, \
134 .flags = flag, \
135}
136
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530137#ifdef WLAN_FEATURE_VOWIFI_11R
138#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
139#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
140#endif
141
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530142#define HDD_CHANNEL_14 14
Dasari Srinivase18b2cf2014-10-28 17:09:42 +0530143#define WLAN_HDD_MAX_FEATURE_SET 8
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530144
Sunil Duttc69bccb2014-05-26 21:30:20 +0530145#ifdef WLAN_FEATURE_LINK_LAYER_STATS
146/*
147 * Used to allocate the size of 4096 for the link layer stats.
148 * The size of 4096 is considered assuming that all data per
149 * respective event fit with in the limit.Please take a call
150 * on the limit based on the data requirements on link layer
151 * statistics.
152 */
153#define LL_STATS_EVENT_BUF_SIZE 4096
154#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +0530155#ifdef WLAN_FEATURE_EXTSCAN
156/*
157 * Used to allocate the size of 4096 for the EXTScan NL data.
158 * The size of 4096 is considered assuming that all data per
159 * respective event fit with in the limit.Please take a call
160 * on the limit based on the data requirements.
161 */
162
163#define EXTSCAN_EVENT_BUF_SIZE 4096
164#define EXTSCAN_MAX_CACHED_RESULTS_PER_IND 32
165#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +0530166
Atul Mittal115287b2014-07-08 13:26:33 +0530167/*EXT TDLS*/
168/*
169 * Used to allocate the size of 4096 for the TDLS.
170 * The size of 4096 is considered assuming that all data per
171 * respective event fit with in the limit.Please take a call
172 * on the limit based on the data requirements on link layer
173 * statistics.
174 */
175#define EXTTDLS_EVENT_BUF_SIZE 4096
176
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +0530177/*
178 * Values for Mac spoofing feature
179 *
180 */
181#define MAC_ADDR_SPOOFING_FW_HOST_DISABLE 0
182#define MAC_ADDR_SPOOFING_FW_HOST_ENABLE 1
183#define MAC_ADDR_SPOOFING_FW_ENABLE_HOST_DISABLE 2
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +0530184#define MAC_ADDR_SPOOFING_DEFER_INTERVAL 10 //in ms
185
Anurag Chouhan343af7e2016-12-16 13:11:19 +0530186/*
187 * max_sched_scan_plans defined to 10
188 */
189#define MAX_SCHED_SCAN_PLANS 10
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +0530190
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530191static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700192{
193 WLAN_CIPHER_SUITE_WEP40,
194 WLAN_CIPHER_SUITE_WEP104,
195 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800196#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700197#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
198 WLAN_CIPHER_SUITE_KRK,
199 WLAN_CIPHER_SUITE_CCMP,
200#else
201 WLAN_CIPHER_SUITE_CCMP,
202#endif
203#ifdef FEATURE_WLAN_WAPI
204 WLAN_CIPHER_SUITE_SMS4,
205#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700206#ifdef WLAN_FEATURE_11W
207 WLAN_CIPHER_SUITE_AES_CMAC,
208#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700209};
210
211static inline int is_broadcast_ether_addr(const u8 *addr)
212{
213 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
214 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
215}
216
Agrawal Ashish97dec502015-11-26 20:20:58 +0530217const static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530218{
Jeff Johnson295189b2012-06-20 16:38:30 -0700219 HDD2GHZCHAN(2412, 1, 0) ,
220 HDD2GHZCHAN(2417, 2, 0) ,
221 HDD2GHZCHAN(2422, 3, 0) ,
222 HDD2GHZCHAN(2427, 4, 0) ,
223 HDD2GHZCHAN(2432, 5, 0) ,
224 HDD2GHZCHAN(2437, 6, 0) ,
225 HDD2GHZCHAN(2442, 7, 0) ,
226 HDD2GHZCHAN(2447, 8, 0) ,
227 HDD2GHZCHAN(2452, 9, 0) ,
228 HDD2GHZCHAN(2457, 10, 0) ,
229 HDD2GHZCHAN(2462, 11, 0) ,
230 HDD2GHZCHAN(2467, 12, 0) ,
231 HDD2GHZCHAN(2472, 13, 0) ,
232 HDD2GHZCHAN(2484, 14, 0) ,
233};
234
Agrawal Ashish97dec502015-11-26 20:20:58 +0530235const static struct ieee80211_channel hdd_channels_5_GHZ[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700236{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700237 HDD5GHZCHAN(4920, 240, 0) ,
238 HDD5GHZCHAN(4940, 244, 0) ,
239 HDD5GHZCHAN(4960, 248, 0) ,
240 HDD5GHZCHAN(4980, 252, 0) ,
241 HDD5GHZCHAN(5040, 208, 0) ,
242 HDD5GHZCHAN(5060, 212, 0) ,
243 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700244 HDD5GHZCHAN(5180, 36, 0) ,
245 HDD5GHZCHAN(5200, 40, 0) ,
246 HDD5GHZCHAN(5220, 44, 0) ,
247 HDD5GHZCHAN(5240, 48, 0) ,
248 HDD5GHZCHAN(5260, 52, 0) ,
249 HDD5GHZCHAN(5280, 56, 0) ,
250 HDD5GHZCHAN(5300, 60, 0) ,
251 HDD5GHZCHAN(5320, 64, 0) ,
252 HDD5GHZCHAN(5500,100, 0) ,
253 HDD5GHZCHAN(5520,104, 0) ,
254 HDD5GHZCHAN(5540,108, 0) ,
255 HDD5GHZCHAN(5560,112, 0) ,
256 HDD5GHZCHAN(5580,116, 0) ,
257 HDD5GHZCHAN(5600,120, 0) ,
258 HDD5GHZCHAN(5620,124, 0) ,
259 HDD5GHZCHAN(5640,128, 0) ,
260 HDD5GHZCHAN(5660,132, 0) ,
261 HDD5GHZCHAN(5680,136, 0) ,
262 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800263#ifdef FEATURE_WLAN_CH144
264 HDD5GHZCHAN(5720,144, 0) ,
265#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700266 HDD5GHZCHAN(5745,149, 0) ,
267 HDD5GHZCHAN(5765,153, 0) ,
268 HDD5GHZCHAN(5785,157, 0) ,
269 HDD5GHZCHAN(5805,161, 0) ,
270 HDD5GHZCHAN(5825,165, 0) ,
271};
272
273static struct ieee80211_rate g_mode_rates[] =
274{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530275 HDD_G_MODE_RATETAB(10, 0x1, 0),
276 HDD_G_MODE_RATETAB(20, 0x2, 0),
277 HDD_G_MODE_RATETAB(55, 0x4, 0),
278 HDD_G_MODE_RATETAB(110, 0x8, 0),
279 HDD_G_MODE_RATETAB(60, 0x10, 0),
280 HDD_G_MODE_RATETAB(90, 0x20, 0),
281 HDD_G_MODE_RATETAB(120, 0x40, 0),
282 HDD_G_MODE_RATETAB(180, 0x80, 0),
283 HDD_G_MODE_RATETAB(240, 0x100, 0),
284 HDD_G_MODE_RATETAB(360, 0x200, 0),
285 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700286 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530287};
Jeff Johnson295189b2012-06-20 16:38:30 -0700288
289static struct ieee80211_rate a_mode_rates[] =
290{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530291 HDD_G_MODE_RATETAB(60, 0x10, 0),
292 HDD_G_MODE_RATETAB(90, 0x20, 0),
293 HDD_G_MODE_RATETAB(120, 0x40, 0),
294 HDD_G_MODE_RATETAB(180, 0x80, 0),
295 HDD_G_MODE_RATETAB(240, 0x100, 0),
296 HDD_G_MODE_RATETAB(360, 0x200, 0),
297 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700298 HDD_G_MODE_RATETAB(540, 0x800, 0),
299};
300
301static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
302{
Agrawal Ashish97dec502015-11-26 20:20:58 +0530303 .channels = NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700304 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
305 .band = IEEE80211_BAND_2GHZ,
306 .bitrates = g_mode_rates,
307 .n_bitrates = g_mode_rates_size,
308 .ht_cap.ht_supported = 1,
309 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
310 | IEEE80211_HT_CAP_GRN_FLD
311 | IEEE80211_HT_CAP_DSSSCCK40
312 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
313 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
314 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
315 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
316 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
317 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
318};
319
Jeff Johnson295189b2012-06-20 16:38:30 -0700320static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
321{
Agrawal Ashish97dec502015-11-26 20:20:58 +0530322 .channels = NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700323 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
324 .band = IEEE80211_BAND_5GHZ,
325 .bitrates = a_mode_rates,
326 .n_bitrates = a_mode_rates_size,
327 .ht_cap.ht_supported = 1,
328 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
329 | IEEE80211_HT_CAP_GRN_FLD
330 | IEEE80211_HT_CAP_DSSSCCK40
331 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
332 | IEEE80211_HT_CAP_SGI_40
333 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
334 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
335 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
336 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
337 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
338 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
339};
340
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530341/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700342 TX/RX direction for each kind of interface */
343static const struct ieee80211_txrx_stypes
344wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
345 [NL80211_IFTYPE_STATION] = {
346 .tx = 0xffff,
347 .rx = BIT(SIR_MAC_MGMT_ACTION) |
348 BIT(SIR_MAC_MGMT_PROBE_REQ),
349 },
350 [NL80211_IFTYPE_AP] = {
351 .tx = 0xffff,
352 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
353 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
354 BIT(SIR_MAC_MGMT_PROBE_REQ) |
355 BIT(SIR_MAC_MGMT_DISASSOC) |
356 BIT(SIR_MAC_MGMT_AUTH) |
357 BIT(SIR_MAC_MGMT_DEAUTH) |
358 BIT(SIR_MAC_MGMT_ACTION),
359 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700360 [NL80211_IFTYPE_ADHOC] = {
361 .tx = 0xffff,
362 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
363 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
364 BIT(SIR_MAC_MGMT_PROBE_REQ) |
365 BIT(SIR_MAC_MGMT_DISASSOC) |
366 BIT(SIR_MAC_MGMT_AUTH) |
367 BIT(SIR_MAC_MGMT_DEAUTH) |
368 BIT(SIR_MAC_MGMT_ACTION),
369 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700370 [NL80211_IFTYPE_P2P_CLIENT] = {
371 .tx = 0xffff,
372 .rx = BIT(SIR_MAC_MGMT_ACTION) |
373 BIT(SIR_MAC_MGMT_PROBE_REQ),
374 },
375 [NL80211_IFTYPE_P2P_GO] = {
376 /* This is also same as for SoftAP */
377 .tx = 0xffff,
378 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
379 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
380 BIT(SIR_MAC_MGMT_PROBE_REQ) |
381 BIT(SIR_MAC_MGMT_DISASSOC) |
382 BIT(SIR_MAC_MGMT_AUTH) |
383 BIT(SIR_MAC_MGMT_DEAUTH) |
384 BIT(SIR_MAC_MGMT_ACTION),
385 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700386};
387
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800388#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800389static const struct ieee80211_iface_limit
390wlan_hdd_iface_limit[] = {
391 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800392 /* max = 3 ; Our driver create two interfaces during driver init
393 * wlan0 and p2p0 interfaces. p2p0 is considered as station
394 * interface until a group is formed. In JB architecture, once the
395 * group is formed, interface type of p2p0 is changed to P2P GO or
396 * Client.
397 * When supplicant remove the group, it first issue a set interface
398 * cmd to change the mode back to Station. In JB this works fine as
399 * we advertize two station type interface during driver init.
400 * Some vendors create separate interface for P2P GO/Client,
401 * after group formation(Third one). But while group remove
402 * supplicant first tries to change the mode(3rd interface) to STATION
403 * But as we advertized only two sta type interfaces nl80211 was
404 * returning error for the third one which was leading to failure in
405 * delete interface. Ideally while removing the group, supplicant
406 * should not try to change the 3rd interface mode to Station type.
407 * Till we get a fix in wpa_supplicant, we advertize max STA
408 * interface type to 3
409 */
410 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800411 .types = BIT(NL80211_IFTYPE_STATION),
412 },
413 {
414 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700415 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800416 },
417 {
418 .max = 1,
419 .types = BIT(NL80211_IFTYPE_P2P_GO) |
420 BIT(NL80211_IFTYPE_P2P_CLIENT),
421 },
422};
423
424/* By default, only single channel concurrency is allowed */
425static struct ieee80211_iface_combination
426wlan_hdd_iface_combination = {
427 .limits = wlan_hdd_iface_limit,
428 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800429 /*
430 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
431 * and p2p0 interfaces during driver init
432 * Some vendors create separate interface for P2P operations.
433 * wlan0: STA interface
434 * p2p0: P2P Device interface, action frames goes
435 * through this interface.
436 * p2p-xx: P2P interface, After GO negotiation this interface is
437 * created for p2p operations(GO/CLIENT interface).
438 */
439 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800440 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
441 .beacon_int_infra_match = false,
442};
443#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800444
Jeff Johnson295189b2012-06-20 16:38:30 -0700445static struct cfg80211_ops wlan_hdd_cfg80211_ops;
446
447/* Data rate 100KBPS based on IE Index */
448struct index_data_rate_type
449{
450 v_U8_t beacon_rate_index;
451 v_U16_t supported_rate[4];
452};
453
454/* 11B, 11G Rate table include Basic rate and Extended rate
455 The IDX field is the rate index
456 The HI field is the rate when RSSI is strong or being ignored
457 (in this case we report actual rate)
458 The MID field is the rate when RSSI is moderate
459 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
460 The LO field is the rate when RSSI is low
461 (in this case we don't report rates, actual current rate used)
462 */
463static const struct
464{
465 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700466 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700467} supported_data_rate[] =
468{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700469/* IDX HI HM LM LO (RSSI-based index */
470 {2, { 10, 10, 10, 0}},
471 {4, { 20, 20, 10, 0}},
472 {11, { 55, 20, 10, 0}},
473 {12, { 60, 55, 20, 0}},
474 {18, { 90, 55, 20, 0}},
475 {22, {110, 55, 20, 0}},
476 {24, {120, 90, 60, 0}},
477 {36, {180, 120, 60, 0}},
478 {44, {220, 180, 60, 0}},
479 {48, {240, 180, 90, 0}},
480 {66, {330, 180, 90, 0}},
481 {72, {360, 240, 90, 0}},
482 {96, {480, 240, 120, 0}},
483 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700484};
485
486/* MCS Based rate table */
487static struct index_data_rate_type supported_mcs_rate[] =
488{
489/* MCS L20 L40 S20 S40 */
490 {0, {65, 135, 72, 150}},
491 {1, {130, 270, 144, 300}},
492 {2, {195, 405, 217, 450}},
493 {3, {260, 540, 289, 600}},
494 {4, {390, 810, 433, 900}},
495 {5, {520, 1080, 578, 1200}},
496 {6, {585, 1215, 650, 1350}},
497 {7, {650, 1350, 722, 1500}}
498};
499
Leo Chang6f8870f2013-03-26 18:11:36 -0700500#ifdef WLAN_FEATURE_11AC
501
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530502#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700503
504struct index_vht_data_rate_type
505{
506 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530507 v_U16_t supported_VHT80_rate[2];
508 v_U16_t supported_VHT40_rate[2];
509 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700510};
511
512typedef enum
513{
514 DATA_RATE_11AC_MAX_MCS_7,
515 DATA_RATE_11AC_MAX_MCS_8,
516 DATA_RATE_11AC_MAX_MCS_9,
517 DATA_RATE_11AC_MAX_MCS_NA
518} eDataRate11ACMaxMcs;
519
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530520/* SSID broadcast type */
521typedef enum eSSIDBcastType
522{
523 eBCAST_UNKNOWN = 0,
524 eBCAST_NORMAL = 1,
525 eBCAST_HIDDEN = 2,
526} tSSIDBcastType;
527
Leo Chang6f8870f2013-03-26 18:11:36 -0700528/* MCS Based VHT rate table */
529static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
530{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530531/* MCS L80 S80 L40 S40 L20 S40*/
532 {0, {293, 325}, {135, 150}, {65, 72}},
533 {1, {585, 650}, {270, 300}, {130, 144}},
534 {2, {878, 975}, {405, 450}, {195, 217}},
535 {3, {1170, 1300}, {540, 600}, {260, 289}},
536 {4, {1755, 1950}, {810, 900}, {390, 433}},
537 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
538 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
539 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
540 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
541 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700542};
543#endif /* WLAN_FEATURE_11AC */
544
c_hpothu79aab322014-07-14 21:11:01 +0530545/*array index points to MCS and array value points respective rssi*/
546static int rssiMcsTbl[][10] =
547{
548/*MCS 0 1 2 3 4 5 6 7 8 9*/
549 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
550 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
551 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
552};
553
Jeff Johnson295189b2012-06-20 16:38:30 -0700554extern struct net_device_ops net_ops_struct;
Dasari Srinivas7875a302014-09-26 17:50:57 +0530555#ifdef FEATURE_WLAN_SCAN_PNO
556static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
557#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700558
Leo Chang9056f462013-08-01 19:21:11 -0700559#ifdef WLAN_NL80211_TESTMODE
560enum wlan_hdd_tm_attr
561{
562 WLAN_HDD_TM_ATTR_INVALID = 0,
563 WLAN_HDD_TM_ATTR_CMD = 1,
564 WLAN_HDD_TM_ATTR_DATA = 2,
565 WLAN_HDD_TM_ATTR_TYPE = 3,
566 /* keep last */
567 WLAN_HDD_TM_ATTR_AFTER_LAST,
568 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
569};
570
571enum wlan_hdd_tm_cmd
572{
573 WLAN_HDD_TM_CMD_WLAN_HB = 1,
574};
575
576#define WLAN_HDD_TM_DATA_MAX_LEN 5000
577
578static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
579{
580 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
581 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
582 .len = WLAN_HDD_TM_DATA_MAX_LEN },
583};
584#endif /* WLAN_NL80211_TESTMODE */
585
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800586#ifdef FEATURE_WLAN_CH_AVOID
587/*
588 * FUNCTION: wlan_hdd_send_avoid_freq_event
589 * This is called when wlan driver needs to send vendor specific
590 * avoid frequency range event to userspace
591 */
592int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
593 tHddAvoidFreqList *pAvoidFreqList)
594{
595 struct sk_buff *vendor_event;
596
597 ENTER();
598
599 if (!pHddCtx)
600 {
601 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
602 "%s: HDD context is null", __func__);
603 return -1;
604 }
605
606 if (!pAvoidFreqList)
607 {
608 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
609 "%s: pAvoidFreqList is null", __func__);
610 return -1;
611 }
612
613 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530614#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
615 NULL,
616#endif
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800617 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530618 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800619 GFP_KERNEL);
620 if (!vendor_event)
621 {
622 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
623 "%s: cfg80211_vendor_event_alloc failed", __func__);
624 return -1;
625 }
626
627 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
628 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
629
630 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
631
632 EXIT();
633 return 0;
634}
635#endif /* FEATURE_WLAN_CH_AVOID */
636
Srinivas Dasari030bad32015-02-18 23:23:54 +0530637/*
638 * FUNCTION: __wlan_hdd_cfg80211_nan_request
639 * This is called when wlan driver needs to send vendor specific
640 * nan request event.
641 */
642static int __wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
643 struct wireless_dev *wdev,
644 const void *data, int data_len)
645{
646 tNanRequestReq nan_req;
647 VOS_STATUS status;
648 int ret_val = -1;
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530649 struct net_device *dev = wdev->netdev;
650 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
651 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530652 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
653
654 if (0 == data_len)
655 {
656 hddLog(VOS_TRACE_LEVEL_ERROR,
657 FL("NAN - Invalid Request, length = 0"));
658 return ret_val;
659 }
660
661 if (NULL == data)
662 {
663 hddLog(VOS_TRACE_LEVEL_ERROR,
664 FL("NAN - Invalid Request, data is NULL"));
665 return ret_val;
666 }
667
668 status = wlan_hdd_validate_context(pHddCtx);
669 if (0 != status)
670 {
671 hddLog(VOS_TRACE_LEVEL_ERROR,
672 FL("HDD context is not valid"));
673 return -EINVAL;
674 }
675
676 hddLog(LOG1, FL("Received NAN command"));
677 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
678 (tANI_U8 *)data, data_len);
679
680 /* check the NAN Capability */
681 if (TRUE != sme_IsFeatureSupportedByFW(NAN))
682 {
683 hddLog(VOS_TRACE_LEVEL_ERROR,
684 FL("NAN is not supported by Firmware"));
685 return -EINVAL;
686 }
687
688 nan_req.request_data_len = data_len;
689 nan_req.request_data = data;
690
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530691 status = sme_NanRequest(hHal, &nan_req, pAdapter->sessionId);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530692 if (VOS_STATUS_SUCCESS == status)
693 {
694 ret_val = 0;
695 }
696 return ret_val;
697}
698
699/*
700 * FUNCTION: wlan_hdd_cfg80211_nan_request
701 * Wrapper to protect the nan vendor command from ssr
702 */
703static int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
704 struct wireless_dev *wdev,
705 const void *data, int data_len)
706{
707 int ret;
708
709 vos_ssr_protect(__func__);
710 ret = __wlan_hdd_cfg80211_nan_request(wiphy, wdev, data, data_len);
711 vos_ssr_unprotect(__func__);
712
713 return ret;
714}
715
716/*
717 * FUNCTION: wlan_hdd_cfg80211_nan_callback
718 * This is a callback function and it gets called
719 * when we need to report nan response event to
720 * upper layers.
721 */
722static void wlan_hdd_cfg80211_nan_callback(void* ctx, tSirNanEvent* msg)
723{
724 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
725 struct sk_buff *vendor_event;
726 int status;
727 tSirNanEvent *data;
728
729 ENTER();
730 if (NULL == msg)
731 {
732 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
733 FL(" msg received here is null"));
734 return;
735 }
736 data = msg;
737
738 status = wlan_hdd_validate_context(pHddCtx);
739
740 if (0 != status)
741 {
742 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
743 FL("HDD context is not valid"));
744 return;
745 }
746
747 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530748#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
749 NULL,
750#endif
Srinivas Dasari030bad32015-02-18 23:23:54 +0530751 data->event_data_len +
752 NLMSG_HDRLEN,
753 QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX,
754 GFP_KERNEL);
755
756 if (!vendor_event)
757 {
758 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
759 FL("cfg80211_vendor_event_alloc failed"));
760 return;
761 }
762 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN,
763 data->event_data_len, data->event_data))
764 {
765 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
766 FL("QCA_WLAN_VENDOR_ATTR_NAN put fail"));
767 kfree_skb(vendor_event);
768 return;
769 }
770 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
771 EXIT();
772}
773
774/*
775 * FUNCTION: wlan_hdd_cfg80211_nan_init
776 * This function is called to register the callback to sme layer
777 */
778inline void wlan_hdd_cfg80211_nan_init(hdd_context_t *pHddCtx)
779{
780 sme_NanRegisterCallback(pHddCtx->hHal, wlan_hdd_cfg80211_nan_callback);
781}
782
Anurag Chouhanfcd20172017-07-19 17:25:19 +0530783/*
784 * define short names for the global vendor params
785 * used by __wlan_hdd_cfg80211_get_station_cmd()
786 */
787#define STATION_INVALID \
788 QCA_WLAN_VENDOR_ATTR_GET_STATION_INVALID
789#define STATION_INFO \
790 QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO
791#define STATION_ASSOC_FAIL_REASON \
792 QCA_WLAN_VENDOR_ATTR_GET_STATION_ASSOC_FAIL_REASON
793#define STATION_MAX \
794 QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX
795
796static const struct nla_policy
797hdd_get_station_policy[STATION_MAX + 1] = {
798 [STATION_INFO] = {.type = NLA_FLAG},
799 [STATION_ASSOC_FAIL_REASON] = {.type = NLA_FLAG},
800};
801
802/**
803 * hdd_get_station_assoc_fail() - Handle get station assoc fail
804 * @hdd_ctx: HDD context within host driver
805 * @wdev: wireless device
806 *
807 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION_ASSOC_FAIL.
808 * Validate cmd attributes and send the station info to upper layers.
809 *
810 * Return: Success(0) or reason code for failure
811 */
812static int hdd_get_station_assoc_fail(hdd_context_t *hdd_ctx,
813 hdd_adapter_t *adapter)
814{
815 struct sk_buff *skb = NULL;
816 uint32_t nl_buf_len;
817 hdd_station_ctx_t *hdd_sta_ctx;
818
819 nl_buf_len = NLMSG_HDRLEN;
820 nl_buf_len += sizeof(uint32_t);
821 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
822
823 if (!skb) {
824 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"cfg80211_vendor_cmd_alloc_reply_skb failed");
825 return -ENOMEM;
826 }
827
828 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
829
830 if (nla_put_u32(skb, INFO_ASSOC_FAIL_REASON,
831 hdd_sta_ctx->conn_info.assoc_status_code)) {
832 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
833 goto fail;
834 }
835 return cfg80211_vendor_cmd_reply(skb);
836fail:
837 if (skb)
838 kfree_skb(skb);
839 return -EINVAL;
840}
841
842/**
843 * hdd_map_auth_type() - transform auth type specific to
844 * vendor command
845 * @auth_type: csr auth type
846 *
847 * Return: Success(0) or reason code for failure
848 */
849static int hdd_convert_auth_type(uint32_t auth_type)
850{
851 uint32_t ret_val;
852
853 switch (auth_type) {
854 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
855 ret_val = QCA_WLAN_AUTH_TYPE_OPEN;
856 break;
857 case eCSR_AUTH_TYPE_SHARED_KEY:
858 ret_val = QCA_WLAN_AUTH_TYPE_SHARED;
859 break;
860 case eCSR_AUTH_TYPE_WPA:
861 ret_val = QCA_WLAN_AUTH_TYPE_WPA;
862 break;
863 case eCSR_AUTH_TYPE_WPA_PSK:
864 ret_val = QCA_WLAN_AUTH_TYPE_WPA_PSK;
865 break;
866 case eCSR_AUTH_TYPE_AUTOSWITCH:
867 ret_val = QCA_WLAN_AUTH_TYPE_AUTOSWITCH;
868 break;
869 case eCSR_AUTH_TYPE_WPA_NONE:
870 ret_val = QCA_WLAN_AUTH_TYPE_WPA_NONE;
871 break;
872 case eCSR_AUTH_TYPE_RSN:
873 ret_val = QCA_WLAN_AUTH_TYPE_RSN;
874 break;
875 case eCSR_AUTH_TYPE_RSN_PSK:
876 ret_val = QCA_WLAN_AUTH_TYPE_RSN_PSK;
877 break;
878 case eCSR_AUTH_TYPE_FT_RSN:
879 ret_val = QCA_WLAN_AUTH_TYPE_FT;
880 break;
881 case eCSR_AUTH_TYPE_FT_RSN_PSK:
882 ret_val = QCA_WLAN_AUTH_TYPE_FT_PSK;
883 break;
884 case eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE:
885 ret_val = QCA_WLAN_AUTH_TYPE_WAI;
886 break;
887 case eCSR_AUTH_TYPE_WAPI_WAI_PSK:
888 ret_val = QCA_WLAN_AUTH_TYPE_WAI_PSK;
889 break;
890#ifdef FEATURE_WLAN_ESE
891 case eCSR_AUTH_TYPE_CCKM_WPA:
892 ret_val = QCA_WLAN_AUTH_TYPE_CCKM_WPA;
893 break;
894 case eCSR_AUTH_TYPE_CCKM_RSN:
895 ret_val = QCA_WLAN_AUTH_TYPE_CCKM_RSN;
896 break;
897#endif
898 case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
899 ret_val = QCA_WLAN_AUTH_TYPE_SHA256_PSK;
900 break;
901 case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
902 ret_val = QCA_WLAN_AUTH_TYPE_SHA256;
903 break;
904 case eCSR_NUM_OF_SUPPORT_AUTH_TYPE:
905 case eCSR_AUTH_TYPE_FAILED:
906 case eCSR_AUTH_TYPE_NONE:
907 default:
908 ret_val = QCA_WLAN_AUTH_TYPE_INVALID;
909 break;
910 }
911 return ret_val;
912}
913
914/**
915 * hdd_map_dot_11_mode() - transform dot11mode type specific to
916 * vendor command
917 * @dot11mode: dot11mode
918 *
919 * Return: Success(0) or reason code for failure
920 */
921static int hdd_convert_dot11mode(uint32_t dot11mode)
922{
923 uint32_t ret_val;
924
925 switch (dot11mode) {
926 case eCSR_CFG_DOT11_MODE_11A:
927 ret_val = QCA_WLAN_802_11_MODE_11A;
928 break;
929 case eCSR_CFG_DOT11_MODE_11B:
930 ret_val = QCA_WLAN_802_11_MODE_11B;
931 break;
932 case eCSR_CFG_DOT11_MODE_11G:
933 ret_val = QCA_WLAN_802_11_MODE_11G;
934 break;
935 case eCSR_CFG_DOT11_MODE_11N:
936 ret_val = QCA_WLAN_802_11_MODE_11N;
937 break;
938 case eCSR_CFG_DOT11_MODE_11AC:
939 ret_val = QCA_WLAN_802_11_MODE_11AC;
940 break;
941 case eCSR_CFG_DOT11_MODE_AUTO:
942 case eCSR_CFG_DOT11_MODE_ABG:
943 default:
944 ret_val = QCA_WLAN_802_11_MODE_INVALID;
945 }
946 return ret_val;
947}
948
949/**
950 * hdd_add_tx_bitrate() - add tx bitrate attribute
951 * @skb: pointer to sk buff
952 * @hdd_sta_ctx: pointer to hdd station context
953 * @idx: attribute index
954 *
955 * Return: Success(0) or reason code for failure
956 */
957static int32_t hdd_add_tx_bitrate(struct sk_buff *skb,
958 hdd_station_ctx_t *hdd_sta_ctx,
959 int idx)
960{
961 struct nlattr *nla_attr;
962 uint32_t bitrate, bitrate_compat;
963
964 nla_attr = nla_nest_start(skb, idx);
965 if (!nla_attr)
966 goto fail;
967 /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
968 bitrate = cfg80211_calculate_bitrate(&hdd_sta_ctx->conn_info.txrate);
969
970 /* report 16-bit bitrate only if we can */
971 bitrate_compat = bitrate < (1UL << 16) ? bitrate : 0;
972 if (bitrate > 0 &&
973 nla_put_u32(skb, NL80211_RATE_INFO_BITRATE32, bitrate)) {
974 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
975 goto fail;
976 }
977 if (bitrate_compat > 0 &&
978 nla_put_u16(skb, NL80211_RATE_INFO_BITRATE, bitrate_compat)) {
979 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
980 goto fail;
981 }
982 if (nla_put_u8(skb, NL80211_RATE_INFO_VHT_NSS,
983 hdd_sta_ctx->conn_info.txrate.nss)) {
984 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
985 goto fail;
986 }
987 nla_nest_end(skb, nla_attr);
988 return 0;
989fail:
990 return -EINVAL;
991}
992
993/**
994 * hdd_add_sta_info() - add station info attribute
995 * @skb: pointer to sk buff
996 * @hdd_sta_ctx: pointer to hdd station context
997 * @idx: attribute index
998 *
999 * Return: Success(0) or reason code for failure
1000 */
1001static int32_t hdd_add_sta_info(struct sk_buff *skb,
1002 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1003{
1004 struct nlattr *nla_attr;
1005
1006 nla_attr = nla_nest_start(skb, idx);
1007 if (!nla_attr)
1008 goto fail;
1009 if (nla_put_u8(skb, NL80211_STA_INFO_SIGNAL,
1010 (hdd_sta_ctx->conn_info.signal + 100))) {
1011 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1012 goto fail;
1013 }
1014 if (hdd_add_tx_bitrate(skb, hdd_sta_ctx, NL80211_STA_INFO_TX_BITRATE))
1015 goto fail;
1016 nla_nest_end(skb, nla_attr);
1017 return 0;
1018fail:
1019 return -EINVAL;
1020}
1021
1022/**
1023 * hdd_add_survey_info() - add survey info attribute
1024 * @skb: pointer to sk buff
1025 * @hdd_sta_ctx: pointer to hdd station context
1026 * @idx: attribute index
1027 *
1028 * Return: Success(0) or reason code for failure
1029 */
1030static int32_t hdd_add_survey_info(struct sk_buff *skb,
1031 hdd_station_ctx_t *hdd_sta_ctx,
1032 int idx)
1033{
1034 struct nlattr *nla_attr;
1035
1036 nla_attr = nla_nest_start(skb, idx);
1037 if (!nla_attr)
1038 goto fail;
1039 if (nla_put_u32(skb, NL80211_SURVEY_INFO_FREQUENCY,
1040 hdd_sta_ctx->conn_info.freq) ||
1041 nla_put_u8(skb, NL80211_SURVEY_INFO_NOISE,
1042 (hdd_sta_ctx->conn_info.noise + 100))) {
1043 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1044 goto fail;
1045 }
1046 nla_nest_end(skb, nla_attr);
1047 return 0;
1048fail:
1049 return -EINVAL;
1050}
1051
1052/**
1053 * hdd_add_link_standard_info() - add link info attribute
1054 * @skb: pointer to sk buff
1055 * @hdd_sta_ctx: pointer to hdd station context
1056 * @idx: attribute index
1057 *
1058 * Return: Success(0) or reason code for failure
1059 */
1060static int32_t
1061hdd_add_link_standard_info(struct sk_buff *skb,
1062 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1063{
1064 struct nlattr *nla_attr;
1065
1066 nla_attr = nla_nest_start(skb, idx);
1067 if (!nla_attr)
1068 goto fail;
1069 if (nla_put(skb,
1070 NL80211_ATTR_SSID,
1071 hdd_sta_ctx->conn_info.SSID.SSID.length,
1072 hdd_sta_ctx->conn_info.SSID.SSID.ssId)) {
1073 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1074 goto fail;
1075 }
1076 if (hdd_add_survey_info(skb, hdd_sta_ctx, NL80211_ATTR_SURVEY_INFO))
1077 goto fail;
1078 if (hdd_add_sta_info(skb, hdd_sta_ctx, NL80211_ATTR_STA_INFO))
1079 goto fail;
1080 nla_nest_end(skb, nla_attr);
1081 return 0;
1082fail:
1083 return -EINVAL;
1084}
1085
1086/**
1087 * hdd_add_ap_standard_info() - add ap info attribute
1088 * @skb: pointer to sk buff
1089 * @hdd_sta_ctx: pointer to hdd station context
1090 * @idx: attribute index
1091 *
1092 * Return: Success(0) or reason code for failure
1093 */
1094static int32_t
1095hdd_add_ap_standard_info(struct sk_buff *skb,
1096 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1097{
1098 struct nlattr *nla_attr;
1099
1100 nla_attr = nla_nest_start(skb, idx);
1101 if (!nla_attr)
1102 goto fail;
1103 if (hdd_sta_ctx->conn_info.conn_flag.vht_present)
1104 if (nla_put(skb, NL80211_ATTR_VHT_CAPABILITY,
1105 sizeof(hdd_sta_ctx->conn_info.vht_caps),
1106 &hdd_sta_ctx->conn_info.vht_caps)) {
1107 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1108 goto fail;
1109 }
1110 if (hdd_sta_ctx->conn_info.conn_flag.ht_present)
1111 if (nla_put(skb, NL80211_ATTR_HT_CAPABILITY,
1112 sizeof(hdd_sta_ctx->conn_info.ht_caps),
1113 &hdd_sta_ctx->conn_info.ht_caps)) {
1114 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1115 goto fail;
1116 }
1117 nla_nest_end(skb, nla_attr);
1118 return 0;
1119fail:
1120 return -EINVAL;
1121}
1122
1123/**
1124 * hdd_get_station_info() - send BSS information to supplicant
1125 * @hdd_ctx: pointer to hdd context
1126 * @adapter: pointer to adapter
1127 *
1128 * Return: 0 if success else error status
1129 */
1130static int hdd_get_station_info(hdd_context_t *hdd_ctx,
1131 hdd_adapter_t *adapter)
1132{
1133 struct sk_buff *skb = NULL;
1134 uint8_t *tmp_hs20 = NULL;
1135 uint32_t nl_buf_len;
1136 hdd_station_ctx_t *hdd_sta_ctx;
1137
1138 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
1139
1140 nl_buf_len = NLMSG_HDRLEN;
1141 nl_buf_len += sizeof(hdd_sta_ctx->conn_info.SSID.SSID.length) +
1142 sizeof(hdd_sta_ctx->conn_info.freq) +
1143 sizeof(hdd_sta_ctx->conn_info.noise) +
1144 sizeof(hdd_sta_ctx->conn_info.signal) +
1145 (sizeof(uint32_t) * 2) +
1146 sizeof(hdd_sta_ctx->conn_info.txrate.nss) +
1147 sizeof(hdd_sta_ctx->conn_info.roam_count) +
1148 sizeof(hdd_sta_ctx->conn_info.authType) +
1149 sizeof(hdd_sta_ctx->conn_info.dot11Mode);
1150 if (hdd_sta_ctx->conn_info.conn_flag.vht_present)
1151 nl_buf_len += sizeof(hdd_sta_ctx->conn_info.vht_caps);
1152 if (hdd_sta_ctx->conn_info.conn_flag.ht_present)
1153 nl_buf_len += sizeof(hdd_sta_ctx->conn_info.ht_caps);
1154 if (hdd_sta_ctx->conn_info.conn_flag.hs20_present) {
1155 tmp_hs20 = (uint8_t *)&(hdd_sta_ctx->conn_info.hs20vendor_ie);
1156 nl_buf_len += (sizeof(hdd_sta_ctx->conn_info.hs20vendor_ie) -
1157 1);
1158 }
1159 if (hdd_sta_ctx->conn_info.conn_flag.ht_op_present)
1160 nl_buf_len += sizeof(hdd_sta_ctx->conn_info.ht_operation);
1161 if (hdd_sta_ctx->conn_info.conn_flag.vht_op_present)
1162 nl_buf_len += sizeof(hdd_sta_ctx->conn_info.vht_operation);
1163
1164
1165 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
1166 if (!skb) {
1167 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"%s: %d cfg80211_vendor_cmd_alloc_reply_skb failed",
1168 __func__, __LINE__);
1169 return -ENOMEM;
1170 }
1171
1172 if (hdd_add_link_standard_info(skb, hdd_sta_ctx,
1173 LINK_INFO_STANDARD_NL80211_ATTR)) {
1174 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1175 goto fail;
1176 }
1177 if (hdd_add_ap_standard_info(skb, hdd_sta_ctx,
1178 AP_INFO_STANDARD_NL80211_ATTR)) {
1179 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1180 goto fail;
1181 }
1182 if (nla_put_u32(skb, INFO_ROAM_COUNT,
1183 hdd_sta_ctx->conn_info.roam_count) ||
1184 nla_put_u32(skb, INFO_AKM,
1185 hdd_convert_auth_type(
1186 hdd_sta_ctx->conn_info.authType)) ||
1187 nla_put_u32(skb, WLAN802_11_MODE,
1188 hdd_convert_dot11mode(
1189 hdd_sta_ctx->conn_info.dot11Mode))) {
1190 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1191 goto fail;
1192 }
1193 if (hdd_sta_ctx->conn_info.conn_flag.ht_op_present)
1194 if (nla_put(skb, HT_OPERATION,
1195 (sizeof(hdd_sta_ctx->conn_info.ht_operation)),
1196 &hdd_sta_ctx->conn_info.ht_operation)) {
1197 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1198 goto fail;
1199 }
1200 if (hdd_sta_ctx->conn_info.conn_flag.vht_op_present)
1201 if (nla_put(skb, VHT_OPERATION,
1202 (sizeof(hdd_sta_ctx->conn_info.vht_operation)),
1203 &hdd_sta_ctx->conn_info.vht_operation)) {
1204 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1205 goto fail;
1206 }
1207 if (hdd_sta_ctx->conn_info.conn_flag.hs20_present)
1208 if (nla_put(skb, AP_INFO_HS20_INDICATION,
1209 (sizeof(hdd_sta_ctx->conn_info.hs20vendor_ie) - 1),
1210 tmp_hs20 + 1)) {
1211 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1212 goto fail;
1213 }
1214
1215 return cfg80211_vendor_cmd_reply(skb);
1216fail:
1217 if (skb)
1218 kfree_skb(skb);
1219 return -EINVAL;
1220}
1221
1222/**
1223 * __hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
1224 * @wiphy: corestack handler
1225 * @wdev: wireless device
1226 * @data: data
1227 * @data_len: data length
1228 *
1229 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
1230 * Validate cmd attributes and send the station info to upper layers.
1231 *
1232 * Return: Success(0) or reason code for failure
1233 */
1234static int32_t
1235__hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
1236 struct wireless_dev *wdev,
1237 const void *data,
1238 int data_len)
1239{
1240 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
1241 struct net_device *dev = wdev->netdev;
1242 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
1243 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX + 1];
1244 int32_t status;
1245
1246 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"Enter");
1247 if (VOS_FTM_MODE == hdd_get_conparam()) {
1248 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"Command not allowed in FTM mode");
1249 status = -EPERM;
1250 goto out;
1251 }
1252
1253 status = wlan_hdd_validate_context(hdd_ctx);
1254 if (0 != status)
1255 goto out;
1256
1257
1258 status = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX,
1259 data, data_len, NULL);
1260 if (status) {
1261 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"Invalid ATTR");
1262 goto out;
1263 }
1264
1265 /* Parse and fetch Command Type*/
1266 if (tb[STATION_INFO]) {
1267 status = hdd_get_station_info(hdd_ctx, adapter);
1268 } else if (tb[STATION_ASSOC_FAIL_REASON]) {
1269 status = hdd_get_station_assoc_fail(hdd_ctx, adapter);
1270 } else {
1271 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"get station info cmd type failed");
1272 status = -EINVAL;
1273 goto out;
1274 }
1275 EXIT();
1276out:
1277 return status;
1278}
1279
1280/**
1281 * wlan_hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
1282 * @wiphy: corestack handler
1283 * @wdev: wireless device
1284 * @data: data
1285 * @data_len: data length
1286 *
1287 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
1288 * Validate cmd attributes and send the station info to upper layers.
1289 *
1290 * Return: Success(0) or reason code for failure
1291 */
1292static int32_t
1293hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
1294 struct wireless_dev *wdev,
1295 const void *data,
1296 int data_len)
1297{
1298 int ret;
1299
1300 vos_ssr_protect(__func__);
1301 ret = __hdd_cfg80211_get_station_cmd(wiphy, wdev, data, data_len);
1302 vos_ssr_unprotect(__func__);
1303
1304 return ret;
1305}
1306
1307/*
1308 * undef short names defined for get station command
1309 * used by __wlan_hdd_cfg80211_get_station_cmd()
1310 */
1311#undef STATION_INVALID
1312#undef STATION_INFO
1313#undef STATION_ASSOC_FAIL_REASON
1314#undef STATION_MAX
Srinivas Dasari030bad32015-02-18 23:23:54 +05301315
Sunil Duttc69bccb2014-05-26 21:30:20 +05301316#ifdef WLAN_FEATURE_LINK_LAYER_STATS
1317
1318static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
1319 struct sk_buff *vendor_event)
1320{
1321 if (nla_put_u8(vendor_event,
1322 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
1323 stats->rate.preamble) ||
1324 nla_put_u8(vendor_event,
1325 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
1326 stats->rate.nss) ||
1327 nla_put_u8(vendor_event,
1328 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
1329 stats->rate.bw) ||
1330 nla_put_u8(vendor_event,
1331 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
1332 stats->rate.rateMcsIdx) ||
1333 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
1334 stats->rate.bitrate ) ||
1335 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
1336 stats->txMpdu ) ||
1337 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
1338 stats->rxMpdu ) ||
1339 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
1340 stats->mpduLost ) ||
1341 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
1342 stats->retries) ||
1343 nla_put_u32(vendor_event,
1344 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
1345 stats->retriesShort ) ||
1346 nla_put_u32(vendor_event,
1347 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
1348 stats->retriesLong))
1349 {
1350 hddLog(VOS_TRACE_LEVEL_ERROR,
1351 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1352 return FALSE;
1353 }
1354 return TRUE;
1355}
1356
1357static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
1358 struct sk_buff *vendor_event)
1359{
1360 u32 i = 0;
1361 struct nlattr *rateInfo;
1362 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
1363 stats->type) ||
1364 nla_put(vendor_event,
1365 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
1366 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
1367 nla_put_u32(vendor_event,
1368 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
1369 stats->capabilities) ||
1370 nla_put_u32(vendor_event,
1371 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
1372 stats->numRate))
1373 {
1374 hddLog(VOS_TRACE_LEVEL_ERROR,
1375 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1376 goto error;
1377 }
1378
1379 rateInfo = nla_nest_start(vendor_event,
1380 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301381 if(!rateInfo)
1382 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301383 for (i = 0; i < stats->numRate; i++)
1384 {
1385 struct nlattr *rates;
1386 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
1387 stats->rateStats +
1388 (i * sizeof(tSirWifiRateStat)));
1389 rates = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301390 if(!rates)
1391 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301392
1393 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
1394 {
1395 hddLog(VOS_TRACE_LEVEL_ERROR,
1396 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1397 return FALSE;
1398 }
1399 nla_nest_end(vendor_event, rates);
1400 }
1401 nla_nest_end(vendor_event, rateInfo);
1402
1403 return TRUE;
1404error:
1405 return FALSE;
1406}
1407
1408static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
1409 struct sk_buff *vendor_event)
1410{
1411 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
1412 stats->ac ) ||
1413 nla_put_u32(vendor_event,
1414 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
1415 stats->txMpdu ) ||
1416 nla_put_u32(vendor_event,
1417 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
1418 stats->rxMpdu ) ||
1419 nla_put_u32(vendor_event,
1420 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
1421 stats->txMcast ) ||
1422 nla_put_u32(vendor_event,
1423 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
1424 stats->rxMcast ) ||
1425 nla_put_u32(vendor_event,
1426 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
1427 stats->rxAmpdu ) ||
1428 nla_put_u32(vendor_event,
1429 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
1430 stats->txAmpdu ) ||
1431 nla_put_u32(vendor_event,
1432 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
1433 stats->mpduLost )||
1434 nla_put_u32(vendor_event,
1435 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
1436 stats->retries ) ||
1437 nla_put_u32(vendor_event,
1438 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
1439 stats->retriesShort ) ||
1440 nla_put_u32(vendor_event,
1441 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
1442 stats->retriesLong ) ||
1443 nla_put_u32(vendor_event,
1444 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
1445 stats->contentionTimeMin ) ||
1446 nla_put_u32(vendor_event,
1447 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
1448 stats->contentionTimeMax ) ||
1449 nla_put_u32(vendor_event,
1450 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
1451 stats->contentionTimeAvg ) ||
1452 nla_put_u32(vendor_event,
1453 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
1454 stats->contentionNumSamples ))
1455 {
1456 hddLog(VOS_TRACE_LEVEL_ERROR,
1457 FL("QCA_WLAN_VENDOR_ATTR put fail") );
1458 return FALSE;
1459 }
1460 return TRUE;
1461}
1462
1463static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
1464 struct sk_buff *vendor_event)
1465{
Dino Myclec8f3f332014-07-21 16:48:27 +05301466 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301467 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
1468 nla_put(vendor_event,
1469 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
1470 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
1471 nla_put_u32(vendor_event,
1472 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
1473 stats->state ) ||
1474 nla_put_u32(vendor_event,
1475 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
1476 stats->roaming ) ||
1477 nla_put_u32(vendor_event,
1478 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
1479 stats->capabilities ) ||
1480 nla_put(vendor_event,
1481 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
1482 strlen(stats->ssid), stats->ssid) ||
1483 nla_put(vendor_event,
1484 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
1485 WNI_CFG_BSSID_LEN, stats->bssid) ||
1486 nla_put(vendor_event,
1487 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
1488 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
1489 nla_put(vendor_event,
1490 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
1491 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
1492 )
1493 {
1494 hddLog(VOS_TRACE_LEVEL_ERROR,
1495 FL("QCA_WLAN_VENDOR_ATTR put fail") );
1496 return FALSE;
1497 }
1498 return TRUE;
1499}
1500
Dino Mycle3b9536d2014-07-09 22:05:24 +05301501static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
1502 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301503 struct sk_buff *vendor_event)
1504{
1505 int i = 0;
1506 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301507 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1508 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05301509 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301510
Sunil Duttc69bccb2014-05-26 21:30:20 +05301511 if (FALSE == put_wifi_interface_info(
1512 &pWifiIfaceStat->info,
1513 vendor_event))
1514 {
1515 hddLog(VOS_TRACE_LEVEL_ERROR,
1516 FL("QCA_WLAN_VENDOR_ATTR put fail") );
1517 return FALSE;
1518
1519 }
Dino Mycle3b9536d2014-07-09 22:05:24 +05301520 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
1521 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
1522 if (NULL == pWifiIfaceStatTL)
1523 {
1524 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
1525 return FALSE;
1526 }
1527
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05301528 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
1529 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
1530 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
1531 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
1532
1533 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
1534 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
1535 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
1536 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301537
1538 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
1539 {
1540 if (VOS_STATUS_SUCCESS ==
1541 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1542 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
1543 {
1544 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
1545 * obtained from TL structure
1546 */
1547
1548 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
1549 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301550 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
1551
Srinivas Dasari98947432014-11-07 19:41:24 +05301552 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
1553 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
1554 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
1555 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
1556 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
1557 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
1558 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
1559 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301560
Srinivas Dasari98947432014-11-07 19:41:24 +05301561 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
1562 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
1563 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
1564 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
1565 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
1566 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
1567 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
1568 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301569
Srinivas Dasari98947432014-11-07 19:41:24 +05301570 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
1571 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
1572 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
1573 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
1574 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
1575 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
1576 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
1577 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301578 }
1579 else
1580 {
1581 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
1582 }
1583
Dino Mycle3b9536d2014-07-09 22:05:24 +05301584 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
1585 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
1586 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
1587 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
1588 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
1589 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
1590 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
1591 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
1592 }
1593 else
1594 {
1595 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
1596 }
1597
1598
Sunil Duttc69bccb2014-05-26 21:30:20 +05301599
1600 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301601 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1602 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_IFACE) ||
1603 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301604 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
1605 pWifiIfaceStat->beaconRx) ||
1606 nla_put_u32(vendor_event,
1607 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
1608 pWifiIfaceStat->mgmtRx) ||
1609 nla_put_u32(vendor_event,
1610 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
1611 pWifiIfaceStat->mgmtActionRx) ||
1612 nla_put_u32(vendor_event,
1613 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
1614 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301615 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301616 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
1617 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301618 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301619 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
1620 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301621 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301622 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
1623 pWifiIfaceStat->rssiAck))
1624 {
1625 hddLog(VOS_TRACE_LEVEL_ERROR,
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05301626 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1627 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301628 return FALSE;
1629 }
1630
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05301631#ifdef FEATURE_EXT_LL_STAT
1632 /*
1633 * Ensure when EXT_LL_STAT is supported by both host and fwr,
1634 * then host should send Leaky AP stats to upper layer,
1635 * otherwise no need to send these stats.
1636 */
1637 if(sme_IsFeatureSupportedByFW(EXT_LL_STAT) &&
1638 sme_IsFeatureSupportedByDriver(EXT_LL_STAT)
1639 )
1640 {
1641 hddLog(VOS_TRACE_LEVEL_INFO,
1642 FL("EXT_LL_STAT is supported by fwr and host %u %u %u %llu"),
1643 pWifiIfaceStat->leakyApStat.is_leaky_ap,
1644 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked,
1645 pWifiIfaceStat->leakyApStat.rx_leak_window,
1646 pWifiIfaceStat->leakyApStat.avg_bcn_spread);
1647 if (nla_put_u32(vendor_event,
1648 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_DETECTED,
1649 pWifiIfaceStat->leakyApStat.is_leaky_ap) ||
1650 nla_put_u32(vendor_event,
1651 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_AVG_NUM_FRAMES_LEAKED,
1652 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked) ||
1653 nla_put_u32(vendor_event,
1654 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_GUARD_TIME,
1655 pWifiIfaceStat->leakyApStat.rx_leak_window) ||
1656 nla_put_u64(vendor_event,
1657 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_AVERAGE_TSF_OFFSET,
1658 pWifiIfaceStat->leakyApStat.avg_bcn_spread))
1659 {
1660 hddLog(VOS_TRACE_LEVEL_ERROR,
1661 FL("EXT_LL_STAT put fail"));
1662 vos_mem_free(pWifiIfaceStatTL);
1663 return FALSE;
1664 }
1665 }
1666#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +05301667 wmmInfo = nla_nest_start(vendor_event,
1668 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301669 if(!wmmInfo)
1670 {
1671 vos_mem_free(pWifiIfaceStatTL);
1672 return FALSE;
1673 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301674 for (i = 0; i < WIFI_AC_MAX; i++)
1675 {
1676 struct nlattr *wmmStats;
1677 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301678 if(!wmmStats)
1679 {
1680 vos_mem_free(pWifiIfaceStatTL);
1681 return FALSE;
1682 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301683 if (FALSE == put_wifi_wmm_ac_stat(
1684 &pWifiIfaceStat->AccessclassStats[i],
1685 vendor_event))
1686 {
1687 hddLog(VOS_TRACE_LEVEL_ERROR,
1688 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05301689 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301690 return FALSE;
1691 }
1692
1693 nla_nest_end(vendor_event, wmmStats);
1694 }
1695 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +05301696 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301697 return TRUE;
1698}
1699
1700static tSirWifiInterfaceMode
1701 hdd_map_device_to_ll_iface_mode ( int deviceMode )
1702{
1703 switch (deviceMode)
1704 {
1705 case WLAN_HDD_INFRA_STATION:
1706 return WIFI_INTERFACE_STA;
1707 case WLAN_HDD_SOFTAP:
1708 return WIFI_INTERFACE_SOFTAP;
1709 case WLAN_HDD_P2P_CLIENT:
1710 return WIFI_INTERFACE_P2P_CLIENT;
1711 case WLAN_HDD_P2P_GO:
1712 return WIFI_INTERFACE_P2P_GO;
1713 case WLAN_HDD_IBSS:
1714 return WIFI_INTERFACE_IBSS;
1715 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05301716 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301717 }
1718}
1719
1720static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
1721 tpSirWifiInterfaceInfo pInfo)
1722{
1723 v_U8_t *staMac = NULL;
1724 hdd_station_ctx_t *pHddStaCtx;
1725 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1726 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
1727
1728 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
1729
1730 vos_mem_copy(pInfo->macAddr,
1731 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1732
1733 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1734 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
1735 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
1736 {
1737 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1738 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
1739 {
1740 pInfo->state = WIFI_DISCONNECTED;
1741 }
1742 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
1743 {
1744 hddLog(VOS_TRACE_LEVEL_ERROR,
1745 "%s: Session ID %d, Connection is in progress", __func__,
1746 pAdapter->sessionId);
1747 pInfo->state = WIFI_ASSOCIATING;
1748 }
1749 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1750 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
1751 {
1752 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
1753 hddLog(VOS_TRACE_LEVEL_ERROR,
1754 "%s: client " MAC_ADDRESS_STR
1755 " is in the middle of WPS/EAPOL exchange.", __func__,
1756 MAC_ADDR_ARRAY(staMac));
1757 pInfo->state = WIFI_AUTHENTICATING;
1758 }
1759 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
1760 {
1761 pInfo->state = WIFI_ASSOCIATED;
1762 vos_mem_copy(pInfo->bssid,
1763 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
1764 vos_mem_copy(pInfo->ssid,
1765 pHddStaCtx->conn_info.SSID.SSID.ssId,
1766 pHddStaCtx->conn_info.SSID.SSID.length);
1767 //NULL Terminate the string.
1768 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
1769 }
1770 }
1771 vos_mem_copy(pInfo->countryStr,
1772 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1773
1774 vos_mem_copy(pInfo->apCountryStr,
1775 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1776
1777 return TRUE;
1778}
1779
1780/*
1781 * hdd_link_layer_process_peer_stats () - This function is called after
1782 * receiving Link Layer Peer statistics from FW.This function converts
1783 * the firmware data to the NL data and sends the same to the kernel/upper
1784 * layers.
1785 */
1786static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
1787 v_VOID_t *pData)
1788{
1789 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301790 tpSirWifiPeerStat pWifiPeerStat;
1791 tpSirWifiPeerInfo pWifiPeerInfo;
1792 struct nlattr *peerInfo;
1793 struct sk_buff *vendor_event;
1794 int status, i;
1795
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301796 ENTER();
1797
Sunil Duttc69bccb2014-05-26 21:30:20 +05301798 status = wlan_hdd_validate_context(pHddCtx);
1799 if (0 != status)
1800 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301801 return;
1802 }
1803
1804 pWifiPeerStat = (tpSirWifiPeerStat) pData;
1805
1806 hddLog(VOS_TRACE_LEVEL_INFO,
1807 "LL_STATS_PEER_ALL : numPeers %u",
1808 pWifiPeerStat->numPeers);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301809 /*
1810 * Allocate a size of 4096 for the peer stats comprising
1811 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1812 * sizeof (tSirWifiRateStat).Each field is put with an
1813 * NL attribute.The size of 4096 is considered assuming
1814 * that number of rates shall not exceed beyond 50 with
1815 * the sizeof (tSirWifiRateStat) being 32.
1816 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301817 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1818 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301819 if (!vendor_event)
1820 {
1821 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301822 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
Sunil Duttc69bccb2014-05-26 21:30:20 +05301823 __func__);
1824 return;
1825 }
1826 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301827 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1828 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_PEER) ||
1829 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301830 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1831 pWifiPeerStat->numPeers))
1832 {
1833 hddLog(VOS_TRACE_LEVEL_ERROR,
1834 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1835 kfree_skb(vendor_event);
1836 return;
1837 }
1838
1839 peerInfo = nla_nest_start(vendor_event,
1840 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301841 if(!peerInfo)
1842 {
1843 hddLog(VOS_TRACE_LEVEL_ERROR,
1844 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
1845 __func__);
1846 kfree_skb(vendor_event);
1847 return;
1848 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301849
1850 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1851 pWifiPeerStat->peerInfo);
1852
1853 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1854 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301855 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301856 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301857
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301858 if(!peers)
1859 {
1860 hddLog(VOS_TRACE_LEVEL_ERROR,
1861 "%s: peer stats put fail",
1862 __func__);
1863 kfree_skb(vendor_event);
1864 return;
1865 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301866 if (FALSE == put_wifi_peer_info(
1867 pWifiPeerInfo, vendor_event))
1868 {
1869 hddLog(VOS_TRACE_LEVEL_ERROR,
1870 "%s: put_wifi_peer_info put fail", __func__);
1871 kfree_skb(vendor_event);
1872 return;
1873 }
1874
1875 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1876 pWifiPeerStat->peerInfo +
1877 (i * sizeof(tSirWifiPeerInfo)) +
1878 (numRate * sizeof (tSirWifiRateStat)));
1879 nla_nest_end(vendor_event, peers);
1880 }
1881 nla_nest_end(vendor_event, peerInfo);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301882 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301883 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301884}
1885
1886/*
1887 * hdd_link_layer_process_iface_stats () - This function is called after
1888 * receiving Link Layer Interface statistics from FW.This function converts
1889 * the firmware data to the NL data and sends the same to the kernel/upper
1890 * layers.
1891 */
1892static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1893 v_VOID_t *pData)
1894{
1895 tpSirWifiIfaceStat pWifiIfaceStat;
1896 struct sk_buff *vendor_event;
1897 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1898 int status;
1899
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301900 ENTER();
1901
Sunil Duttc69bccb2014-05-26 21:30:20 +05301902 status = wlan_hdd_validate_context(pHddCtx);
1903 if (0 != status)
1904 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301905 return;
1906 }
1907 /*
1908 * Allocate a size of 4096 for the interface stats comprising
1909 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1910 * assuming that all these fit with in the limit.Please take
1911 * a call on the limit based on the data requirements on
1912 * interface statistics.
1913 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301914 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1915 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301916 if (!vendor_event)
1917 {
1918 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301919 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301920 return;
1921 }
1922
1923 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1924
Dino Mycle3b9536d2014-07-09 22:05:24 +05301925
1926 if (FALSE == hdd_get_interface_info( pAdapter,
1927 &pWifiIfaceStat->info))
1928 {
1929 hddLog(VOS_TRACE_LEVEL_ERROR,
1930 FL("hdd_get_interface_info get fail") );
1931 kfree_skb(vendor_event);
1932 return;
1933 }
1934
1935 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
1936 vendor_event))
1937 {
1938 hddLog(VOS_TRACE_LEVEL_ERROR,
1939 FL("put_wifi_iface_stats fail") );
1940 kfree_skb(vendor_event);
1941 return;
1942 }
1943
Sunil Duttc69bccb2014-05-26 21:30:20 +05301944 hddLog(VOS_TRACE_LEVEL_INFO,
1945 "WMI_LINK_STATS_IFACE Data");
1946
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301947 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301948
1949 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301950}
1951
1952/*
1953 * hdd_link_layer_process_radio_stats () - This function is called after
1954 * receiving Link Layer Radio statistics from FW.This function converts
1955 * the firmware data to the NL data and sends the same to the kernel/upper
1956 * layers.
1957 */
1958static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1959 v_VOID_t *pData)
1960{
1961 int status, i;
1962 tpSirWifiRadioStat pWifiRadioStat;
1963 tpSirWifiChannelStats pWifiChannelStats;
1964 struct sk_buff *vendor_event;
1965 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1966 struct nlattr *chList;
1967
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301968 ENTER();
1969
Sunil Duttc69bccb2014-05-26 21:30:20 +05301970 status = wlan_hdd_validate_context(pHddCtx);
1971 if (0 != status)
1972 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301973 return;
1974 }
1975 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1976
1977 hddLog(VOS_TRACE_LEVEL_INFO,
1978 "LL_STATS_RADIO"
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05301979 " number of radios = %u"
Sunil Duttc69bccb2014-05-26 21:30:20 +05301980 " radio is %d onTime is %u "
1981 " txTime is %u rxTime is %u "
1982 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301983 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301984 " onTimePnoScan is %u onTimeHs20 is %u "
1985 " numChannels is %u",
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05301986 NUM_RADIOS,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301987 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1988 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1989 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301990 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301991 pWifiRadioStat->onTimeRoamScan,
1992 pWifiRadioStat->onTimePnoScan,
1993 pWifiRadioStat->onTimeHs20,
1994 pWifiRadioStat->numChannels);
1995 /*
1996 * Allocate a size of 4096 for the Radio stats comprising
1997 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1998 * (tSirWifiChannelStats).Each channel data is put with an
1999 * NL attribute.The size of 4096 is considered assuming that
2000 * number of channels shall not exceed beyond 60 with the
2001 * sizeof (tSirWifiChannelStats) being 24 bytes.
2002 */
2003
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302004 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2005 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302006 if (!vendor_event)
2007 {
2008 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302009 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05302010 return;
2011 }
2012
2013 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302014 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2015 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO) ||
2016 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302017 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
2018 pWifiRadioStat->radio) ||
2019 nla_put_u32(vendor_event,
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302020 QCA_WLAN_VENDOR_ATTR_LL_STATS_NUM_RADIOS,
2021 NUM_RADIOS) ||
2022 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302023 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
2024 pWifiRadioStat->onTime) ||
2025 nla_put_u32(vendor_event,
2026 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
2027 pWifiRadioStat->txTime) ||
2028 nla_put_u32(vendor_event,
2029 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
2030 pWifiRadioStat->rxTime) ||
2031 nla_put_u32(vendor_event,
2032 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
2033 pWifiRadioStat->onTimeScan) ||
2034 nla_put_u32(vendor_event,
2035 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
2036 pWifiRadioStat->onTimeNbd) ||
2037 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302038 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
2039 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05302040 nla_put_u32(vendor_event,
2041 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
2042 pWifiRadioStat->onTimeRoamScan) ||
2043 nla_put_u32(vendor_event,
2044 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
2045 pWifiRadioStat->onTimePnoScan) ||
2046 nla_put_u32(vendor_event,
2047 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
2048 pWifiRadioStat->onTimeHs20) ||
2049 nla_put_u32(vendor_event,
2050 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
2051 pWifiRadioStat->numChannels))
2052 {
2053 hddLog(VOS_TRACE_LEVEL_ERROR,
2054 FL("QCA_WLAN_VENDOR_ATTR put fail"));
2055 kfree_skb(vendor_event);
2056 return ;
2057 }
2058
2059 chList = nla_nest_start(vendor_event,
2060 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302061 if(!chList)
2062 {
2063 hddLog(VOS_TRACE_LEVEL_ERROR,
2064 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
2065 __func__);
2066 kfree_skb(vendor_event);
2067 return;
2068 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302069 for (i = 0; i < pWifiRadioStat->numChannels; i++)
2070 {
2071 struct nlattr *chInfo;
2072
2073 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
2074 pWifiRadioStat->channels +
2075 (i * sizeof(tSirWifiChannelStats)));
2076
Sunil Duttc69bccb2014-05-26 21:30:20 +05302077 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302078 if(!chInfo)
2079 {
2080 hddLog(VOS_TRACE_LEVEL_ERROR,
2081 "%s: failed to put chInfo",
2082 __func__);
2083 kfree_skb(vendor_event);
2084 return;
2085 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302086
2087 if (nla_put_u32(vendor_event,
2088 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
2089 pWifiChannelStats->channel.width) ||
2090 nla_put_u32(vendor_event,
2091 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
2092 pWifiChannelStats->channel.centerFreq) ||
2093 nla_put_u32(vendor_event,
2094 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
2095 pWifiChannelStats->channel.centerFreq0) ||
2096 nla_put_u32(vendor_event,
2097 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
2098 pWifiChannelStats->channel.centerFreq1) ||
2099 nla_put_u32(vendor_event,
2100 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
2101 pWifiChannelStats->onTime) ||
2102 nla_put_u32(vendor_event,
2103 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
2104 pWifiChannelStats->ccaBusyTime))
2105 {
2106 hddLog(VOS_TRACE_LEVEL_ERROR,
2107 FL("cfg80211_vendor_event_alloc failed") );
2108 kfree_skb(vendor_event);
2109 return ;
2110 }
2111 nla_nest_end(vendor_event, chInfo);
2112 }
2113 nla_nest_end(vendor_event, chList);
2114
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302115 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302116
2117 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302118 return;
2119}
2120
2121/*
2122 * hdd_link_layer_stats_ind_callback () - This function is called after
2123 * receiving Link Layer indications from FW.This callback converts the firmware
2124 * data to the NL data and send the same to the kernel/upper layers.
2125 */
2126static void hdd_link_layer_stats_ind_callback ( void *pCtx,
2127 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05302128 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302129{
Dino Mycled3d50022014-07-07 12:58:25 +05302130 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
2131 hdd_adapter_t *pAdapter = NULL;
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302132 struct hdd_ll_stats_context *context;
Dino Mycled3d50022014-07-07 12:58:25 +05302133 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302134 int status;
2135
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302136 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302137
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302138 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302139 if (0 != status)
2140 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302141 return;
2142 }
2143
Dino Mycled3d50022014-07-07 12:58:25 +05302144 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
2145 if (NULL == pAdapter)
2146 {
2147 hddLog(VOS_TRACE_LEVEL_ERROR,
2148 FL(" MAC address %pM does not exist with host"),
2149 macAddr);
2150 return;
2151 }
2152
Sunil Duttc69bccb2014-05-26 21:30:20 +05302153 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05302154 "%s: Interface: %s LLStats indType: %d", __func__,
2155 pAdapter->dev->name, indType);
2156
Sunil Duttc69bccb2014-05-26 21:30:20 +05302157 switch (indType)
2158 {
2159 case SIR_HAL_LL_STATS_RESULTS_RSP:
2160 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302161 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302162 "LL_STATS RESP paramID = 0x%x, ifaceId = %u MAC: %pM "
2163 "respId = %u, moreResultToFollow = %u",
2164 linkLayerStatsResults->paramId, linkLayerStatsResults->ifaceId,
2165 macAddr, linkLayerStatsResults->respId,
2166 linkLayerStatsResults->moreResultToFollow);
2167
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302168 spin_lock(&hdd_context_lock);
2169 context = &pHddCtx->ll_stats_context;
2170 /* validate response received from target */
2171 if ((context->request_id != linkLayerStatsResults->respId) ||
2172 !(context->request_bitmap & linkLayerStatsResults->paramId))
2173 {
2174 spin_unlock(&hdd_context_lock);
2175 hddLog(LOGE,
2176 FL("Error : Request id %d response id %d request bitmap 0x%x"
2177 "response bitmap 0x%x"),
2178 context->request_id, linkLayerStatsResults->respId,
2179 context->request_bitmap, linkLayerStatsResults->paramId);
2180 return;
2181 }
2182 spin_unlock(&hdd_context_lock);
2183
Sunil Duttc69bccb2014-05-26 21:30:20 +05302184 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
2185 {
2186 hdd_link_layer_process_radio_stats(pAdapter,
2187 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302188 spin_lock(&hdd_context_lock);
2189 context->request_bitmap &= ~(WMI_LINK_STATS_RADIO);
2190 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302191 }
2192 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
2193 {
2194 hdd_link_layer_process_iface_stats(pAdapter,
2195 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302196 spin_lock(&hdd_context_lock);
2197 context->request_bitmap &= ~(WMI_LINK_STATS_IFACE);
2198 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302199 }
2200 else if ( linkLayerStatsResults->paramId &
2201 WMI_LINK_STATS_ALL_PEER )
2202 {
2203 hdd_link_layer_process_peer_stats(pAdapter,
2204 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302205 spin_lock(&hdd_context_lock);
2206 context->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER);
2207 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302208 } /* WMI_LINK_STATS_ALL_PEER */
2209 else
2210 {
2211 hddLog(VOS_TRACE_LEVEL_ERROR,
2212 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
2213 }
2214
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302215 spin_lock(&hdd_context_lock);
2216 /* complete response event if all requests are completed */
2217 if (0 == context->request_bitmap)
2218 complete(&context->response_event);
2219 spin_unlock(&hdd_context_lock);
2220
Sunil Duttc69bccb2014-05-26 21:30:20 +05302221 break;
2222 }
2223 default:
2224 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
2225 break;
2226 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302227
2228 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302229 return;
2230}
2231
2232const struct
2233nla_policy
2234qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
2235{
2236 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
2237 { .type = NLA_U32 },
2238 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
2239 { .type = NLA_U32 },
2240};
2241
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302242static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
2243 struct wireless_dev *wdev,
2244 const void *data,
2245 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302246{
2247 int status;
2248 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302249 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302250 struct net_device *dev = wdev->netdev;
2251 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2252 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2253
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302254 ENTER();
2255
Sunil Duttc69bccb2014-05-26 21:30:20 +05302256 status = wlan_hdd_validate_context(pHddCtx);
2257 if (0 != status)
2258 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302259 return -EINVAL;
2260 }
2261
2262 if (NULL == pAdapter)
2263 {
2264 hddLog(VOS_TRACE_LEVEL_ERROR,
2265 FL("HDD adapter is Null"));
2266 return -ENODEV;
2267 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302268 /* check the LLStats Capability */
2269 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2270 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2271 {
Anurag Chouhan65ea6dc2016-10-25 19:59:14 +05302272 hddLog(VOS_TRACE_LEVEL_WARN,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302273 FL("Link Layer Statistics not supported by Firmware"));
2274 return -EINVAL;
2275 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302276
2277 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
2278 (struct nlattr *)data,
2279 data_len, qca_wlan_vendor_ll_set_policy))
2280 {
2281 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2282 return -EINVAL;
2283 }
2284 if (!tb_vendor
2285 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
2286 {
2287 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
2288 return -EINVAL;
2289 }
2290 if (!tb_vendor[
2291 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
2292 {
2293 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
2294 return -EINVAL;
2295 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302296 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302297 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302298
Dino Mycledf0a5d92014-07-04 09:41:55 +05302299 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302300 nla_get_u32(
2301 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
2302
Dino Mycledf0a5d92014-07-04 09:41:55 +05302303 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302304 nla_get_u32(
2305 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
2306
Dino Mycled3d50022014-07-07 12:58:25 +05302307 vos_mem_copy(linkLayerStatsSetReq.macAddr,
2308 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302309
2310
2311 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302312 "LL_STATS_SET reqId = %d, MAC = %pM, mpduSizeThreshold = %d "
2313 "Statistics Gathering = %d ",
2314 linkLayerStatsSetReq.reqId, linkLayerStatsSetReq.macAddr,
2315 linkLayerStatsSetReq.mpduSizeThreshold,
2316 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302317
2318 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
2319 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05302320 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302321 {
2322 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2323 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302324 return -EINVAL;
2325
2326 }
Srinivas Dasari98947432014-11-07 19:41:24 +05302327
Sunil Duttc69bccb2014-05-26 21:30:20 +05302328 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302329 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302330 {
2331 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2332 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302333 return -EINVAL;
2334 }
2335
2336 pAdapter->isLinkLayerStatsSet = 1;
2337
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302338 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302339 return 0;
2340}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302341static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
2342 struct wireless_dev *wdev,
2343 const void *data,
2344 int data_len)
2345{
2346 int ret = 0;
2347
2348 vos_ssr_protect(__func__);
2349 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
2350 vos_ssr_unprotect(__func__);
2351
2352 return ret;
2353}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302354
2355const struct
2356nla_policy
2357qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
2358{
2359 /* Unsigned 32bit value provided by the caller issuing the GET stats
2360 * command. When reporting
2361 * the stats results, the driver uses the same value to indicate
2362 * which GET request the results
2363 * correspond to.
2364 */
2365 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
2366
2367 /* Unsigned 32bit value . bit mask to identify what statistics are
2368 requested for retrieval */
2369 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
2370};
2371
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302372static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
2373 struct wireless_dev *wdev,
2374 const void *data,
2375 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302376{
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302377 unsigned long rc;
2378 struct hdd_ll_stats_context *context;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302379 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2380 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302381 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302382 struct net_device *dev = wdev->netdev;
2383 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma10313ba2015-07-29 19:14:39 +05302384 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302385 int status;
2386
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302387 ENTER();
2388
Sunil Duttc69bccb2014-05-26 21:30:20 +05302389 status = wlan_hdd_validate_context(pHddCtx);
2390 if (0 != status)
2391 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302392 return -EINVAL ;
2393 }
2394
2395 if (NULL == pAdapter)
2396 {
2397 hddLog(VOS_TRACE_LEVEL_FATAL,
2398 "%s: HDD adapter is Null", __func__);
2399 return -ENODEV;
2400 }
Mukul Sharma10313ba2015-07-29 19:14:39 +05302401
2402 if (pHddStaCtx == NULL)
2403 {
2404 hddLog(VOS_TRACE_LEVEL_FATAL,
2405 "%s: HddStaCtx is Null", __func__);
2406 return -ENODEV;
2407 }
2408
Dino Mycledf0a5d92014-07-04 09:41:55 +05302409 /* check the LLStats Capability */
2410 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2411 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2412 {
2413 hddLog(VOS_TRACE_LEVEL_ERROR,
2414 FL("Link Layer Statistics not supported by Firmware"));
2415 return -EINVAL;
2416 }
2417
Sunil Duttc69bccb2014-05-26 21:30:20 +05302418
2419 if (!pAdapter->isLinkLayerStatsSet)
2420 {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05302421 hddLog(VOS_TRACE_LEVEL_ERROR,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302422 "%s: isLinkLayerStatsSet : %d",
2423 __func__, pAdapter->isLinkLayerStatsSet);
2424 return -EINVAL;
2425 }
2426
Mukul Sharma10313ba2015-07-29 19:14:39 +05302427 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
2428 {
2429 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2430 "%s: Roaming in progress, so unable to proceed this request", __func__);
2431 return -EBUSY;
2432 }
2433
Sunil Duttc69bccb2014-05-26 21:30:20 +05302434 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
2435 (struct nlattr *)data,
2436 data_len, qca_wlan_vendor_ll_get_policy))
2437 {
2438 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2439 return -EINVAL;
2440 }
2441
2442 if (!tb_vendor
2443 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
2444 {
2445 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
2446 return -EINVAL;
2447 }
2448
2449 if (!tb_vendor
2450 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
2451 {
2452 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
2453 return -EINVAL;
2454 }
2455
Sunil Duttc69bccb2014-05-26 21:30:20 +05302456
Dino Mycledf0a5d92014-07-04 09:41:55 +05302457 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302458 nla_get_u32( tb_vendor[
2459 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05302460 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302461 nla_get_u32( tb_vendor[
2462 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
2463
Dino Mycled3d50022014-07-07 12:58:25 +05302464 vos_mem_copy(linkLayerStatsGetReq.macAddr,
2465 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302466
2467 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302468 "LL_STATS_GET reqId = %d, MAC = %pM, paramIdMask = %d",
2469 linkLayerStatsGetReq.reqId, linkLayerStatsGetReq.macAddr,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302470 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302471
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302472 spin_lock(&hdd_context_lock);
2473 context = &pHddCtx->ll_stats_context;
2474 context->request_id = linkLayerStatsGetReq.reqId;
2475 context->request_bitmap = linkLayerStatsGetReq.paramIdMask;
2476 INIT_COMPLETION(context->response_event);
2477 spin_unlock(&hdd_context_lock);
2478
Sunil Duttc69bccb2014-05-26 21:30:20 +05302479 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302480 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302481 {
2482 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2483 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302484 return -EINVAL;
2485 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302486
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302487 rc = wait_for_completion_timeout(&context->response_event,
2488 msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS));
2489 if (!rc)
2490 {
2491 hddLog(LOGE,
2492 FL("Target response timed out request id %d request bitmap 0x%x"),
2493 context->request_id, context->request_bitmap);
2494 return -ETIMEDOUT;
2495 }
2496
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302497 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302498 return 0;
2499}
2500
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302501static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
2502 struct wireless_dev *wdev,
2503 const void *data,
2504 int data_len)
2505{
2506 int ret = 0;
2507
2508 vos_ssr_protect(__func__);
2509 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
2510 vos_ssr_unprotect(__func__);
2511
2512 return ret;
2513}
2514
Sunil Duttc69bccb2014-05-26 21:30:20 +05302515const struct
2516nla_policy
2517qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
2518{
2519 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
2520 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
2521 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
2522 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
2523};
2524
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302525static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2526 struct wireless_dev *wdev,
2527 const void *data,
2528 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302529{
2530 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2531 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302532 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302533 struct net_device *dev = wdev->netdev;
2534 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2535 u32 statsClearReqMask;
2536 u8 stopReq;
2537 int status;
2538
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302539 ENTER();
2540
Sunil Duttc69bccb2014-05-26 21:30:20 +05302541 status = wlan_hdd_validate_context(pHddCtx);
2542 if (0 != status)
2543 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302544 return -EINVAL;
2545 }
2546
2547 if (NULL == pAdapter)
2548 {
2549 hddLog(VOS_TRACE_LEVEL_FATAL,
2550 "%s: HDD adapter is Null", __func__);
2551 return -ENODEV;
2552 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302553 /* check the LLStats Capability */
2554 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2555 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2556 {
2557 hddLog(VOS_TRACE_LEVEL_ERROR,
2558 FL("Enable LLStats Capability"));
2559 return -EINVAL;
2560 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302561
2562 if (!pAdapter->isLinkLayerStatsSet)
2563 {
2564 hddLog(VOS_TRACE_LEVEL_FATAL,
2565 "%s: isLinkLayerStatsSet : %d",
2566 __func__, pAdapter->isLinkLayerStatsSet);
2567 return -EINVAL;
2568 }
2569
2570 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
2571 (struct nlattr *)data,
2572 data_len, qca_wlan_vendor_ll_clr_policy))
2573 {
2574 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2575 return -EINVAL;
2576 }
2577
2578 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
2579
2580 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
2581 {
2582 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
2583 return -EINVAL;
2584
2585 }
2586
Sunil Duttc69bccb2014-05-26 21:30:20 +05302587
Dino Mycledf0a5d92014-07-04 09:41:55 +05302588 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302589 nla_get_u32(
2590 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
2591
Dino Mycledf0a5d92014-07-04 09:41:55 +05302592 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302593 nla_get_u8(
2594 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
2595
2596 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302597 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302598
Dino Mycled3d50022014-07-07 12:58:25 +05302599 vos_mem_copy(linkLayerStatsClearReq.macAddr,
2600 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302601
2602 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302603 "LL_STATS_CLEAR reqId = %d, MAC = %pM,"
2604 "statsClearReqMask = 0x%X, stopReq = %d",
2605 linkLayerStatsClearReq.reqId,
2606 linkLayerStatsClearReq.macAddr,
2607 linkLayerStatsClearReq.statsClearReqMask,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302608 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302609
2610 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302611 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302612 {
2613 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05302614 hdd_station_ctx_t *pHddStaCtx;
2615
2616 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2617 if (VOS_STATUS_SUCCESS !=
2618 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2619 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
2620 {
2621 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2622 "WLANTL_ClearInterfaceStats Failed", __func__);
2623 return -EINVAL;
2624 }
2625 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
2626 (statsClearReqMask & WIFI_STATS_IFACE)) {
2627 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
2628 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
2629 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
2630 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
2631 }
2632
Sunil Duttc69bccb2014-05-26 21:30:20 +05302633 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
2634 2 * sizeof(u32) +
2635 NLMSG_HDRLEN);
2636
2637 if (temp_skbuff != NULL)
2638 {
2639
2640 if (nla_put_u32(temp_skbuff,
2641 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
2642 statsClearReqMask) ||
2643 nla_put_u32(temp_skbuff,
2644 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
2645 stopReq))
2646 {
2647 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
2648 kfree_skb(temp_skbuff);
2649 return -EINVAL;
2650 }
2651 /* If the ask is to stop the stats collection as part of clear
2652 * (stopReq = 1) , ensure that no further requests of get
2653 * go to the firmware by having isLinkLayerStatsSet set to 0.
2654 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302655 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05302656 * case the firmware is just asked to clear the statistics.
2657 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05302658 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302659 pAdapter->isLinkLayerStatsSet = 0;
2660 return cfg80211_vendor_cmd_reply(temp_skbuff);
2661 }
2662 return -ENOMEM;
2663 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302664
2665 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302666 return -EINVAL;
2667}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302668static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2669 struct wireless_dev *wdev,
2670 const void *data,
2671 int data_len)
2672{
2673 int ret = 0;
2674
2675 vos_ssr_protect(__func__);
2676 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
2677 vos_ssr_unprotect(__func__);
2678
2679 return ret;
2680
2681
2682}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302683#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
2684
Dino Mycle6fb96c12014-06-10 11:52:40 +05302685#ifdef WLAN_FEATURE_EXTSCAN
2686static const struct nla_policy
2687wlan_hdd_extscan_config_policy
2688 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
2689{
2690 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
2691 { .type = NLA_U32 },
2692 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
2693 { .type = NLA_U32 },
SaidiReddy Yenugaf2145922017-05-26 18:19:31 +05302694 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS] =
2695 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302696 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
2697 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
2698 { .type = NLA_U32 },
2699 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
2700 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
2701
2702 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
2703 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
2704 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
2705 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
2706 { .type = NLA_U8 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302707 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] =
2708 { .type = NLA_U32 },
2709 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT] =
2710 { .type = NLA_U32 },
2711 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] =
2712 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302713 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
2714 { .type = NLA_U32 },
2715 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
2716 { .type = NLA_U32 },
2717 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
2718 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302719 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] =
2720 { .type = NLA_U8 },
2721 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302722 { .type = NLA_U8 },
2723 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
2724 { .type = NLA_U8 },
2725 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
2726 { .type = NLA_U8 },
2727
2728 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
2729 { .type = NLA_U32 },
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05302730 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] = {
2731 .type = NLA_UNSPEC,
2732 .len = HDD_MAC_ADDR_LEN},
Dino Mycle6fb96c12014-06-10 11:52:40 +05302733 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
2734 { .type = NLA_S32 },
2735 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
2736 { .type = NLA_S32 },
2737 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
2738 { .type = NLA_U32 },
2739 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
2740 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302741 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] =
2742 { .type = NLA_U32 },
2743 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] =
2744 { .type = NLA_BINARY,
2745 .len = IEEE80211_MAX_SSID_LEN + 1 },
2746 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302747 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302748 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] =
2749 { .type = NLA_U32 },
2750 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] =
2751 { .type = NLA_U8 },
2752 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] =
2753 { .type = NLA_S32 },
2754 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] =
2755 { .type = NLA_S32 },
2756 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] =
2757 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302758};
2759
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302760/**
2761 * wlan_hdd_cfg80211_extscan_get_capabilities_rsp() - response from target
2762 * @ctx: hdd global context
2763 * @data: capabilities data
2764 *
2765 * Return: none
2766 */
2767static void
2768wlan_hdd_cfg80211_extscan_get_capabilities_rsp(void *ctx, void *pMsg)
Dino Mycle6fb96c12014-06-10 11:52:40 +05302769{
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302770 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302771 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302772 tSirEXTScanCapabilitiesEvent *data =
2773 (tSirEXTScanCapabilitiesEvent *) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302774
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302775 ENTER();
2776
2777 if (wlan_hdd_validate_context(pHddCtx))
2778 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302779 return;
2780 }
2781
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302782 if (!pMsg)
2783 {
2784 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2785 return;
2786 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302787
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302788 vos_spin_lock_acquire(&hdd_context_lock);
2789
2790 context = &pHddCtx->ext_scan_context;
2791 /* validate response received from target*/
2792 if (context->request_id != data->requestId)
2793 {
2794 vos_spin_lock_release(&hdd_context_lock);
2795 hddLog(LOGE,
2796 FL("Target response id did not match: request_id %d resposne_id %d"),
2797 context->request_id, data->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302798 return;
2799 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302800 else
2801 {
2802 context->capability_response = *data;
2803 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302804 }
2805
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302806 vos_spin_lock_release(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302807
Dino Mycle6fb96c12014-06-10 11:52:40 +05302808 return;
2809}
2810
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302811/*
2812 * define short names for the global vendor params
2813 * used by wlan_hdd_send_ext_scan_capability()
2814 */
2815#define PARAM_REQUEST_ID \
2816 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
2817#define PARAM_STATUS \
2818 QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS
2819#define MAX_SCAN_CACHE_SIZE \
2820 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE
2821#define MAX_SCAN_BUCKETS \
2822 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS
2823#define MAX_AP_CACHE_PER_SCAN \
2824 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN
2825#define MAX_RSSI_SAMPLE_SIZE \
2826 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE
2827#define MAX_SCAN_RPT_THRHOLD \
2828 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
2829#define MAX_HOTLIST_BSSIDS \
2830 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS
2831#define MAX_BSSID_HISTORY_ENTRIES \
2832 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
2833#define MAX_HOTLIST_SSIDS \
2834 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302835#define MAX_SIGNIFICANT_WIFI_CHANGE_APS \
2836 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302837
2838static int wlan_hdd_send_ext_scan_capability(void *ctx)
2839{
2840 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2841 struct sk_buff *skb = NULL;
2842 int ret;
2843 tSirEXTScanCapabilitiesEvent *data;
2844 tANI_U32 nl_buf_len;
2845
2846 ret = wlan_hdd_validate_context(pHddCtx);
2847 if (0 != ret)
2848 {
2849 return ret;
2850 }
2851
2852 data = &(pHddCtx->ext_scan_context.capability_response);
2853
2854 nl_buf_len = NLMSG_HDRLEN;
2855 nl_buf_len += (sizeof(data->requestId) + NLA_HDRLEN) +
2856 (sizeof(data->status) + NLA_HDRLEN) +
2857 (sizeof(data->scanCacheSize) + NLA_HDRLEN) +
2858 (sizeof(data->scanBuckets) + NLA_HDRLEN) +
2859 (sizeof(data->maxApPerScan) + NLA_HDRLEN) +
2860 (sizeof(data->maxRssiSampleSize) + NLA_HDRLEN) +
2861 (sizeof(data->maxScanReportingThreshold) + NLA_HDRLEN) +
2862 (sizeof(data->maxHotlistAPs) + NLA_HDRLEN) +
2863 (sizeof(data->maxBsidHistoryEntries) + NLA_HDRLEN) +
2864 (sizeof(data->maxHotlistSSIDs) + NLA_HDRLEN);
2865
2866 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, nl_buf_len);
2867
2868 if (!skb)
2869 {
2870 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
2871 return -ENOMEM;
2872 }
2873
2874 hddLog(LOG1, "Req Id (%u) Status (%u)", data->requestId, data->status);
2875 hddLog(LOG1, "Scan cache size (%u) Scan buckets (%u) Max AP per scan (%u)",
2876 data->scanCacheSize, data->scanBuckets, data->maxApPerScan);
2877 hddLog(LOG1, "max_rssi_sample_size (%u) max_scan_reporting_threshold (%u)",
2878 data->maxRssiSampleSize, data->maxScanReportingThreshold);
2879 hddLog(LOG1, "max_hotlist_bssids (%u) max_bssid_history_entries (%u)"
2880 "max_hotlist_ssids (%u)", data->maxHotlistAPs,
2881 data->maxBsidHistoryEntries, data->maxHotlistSSIDs);
2882
2883 if (nla_put_u32(skb, PARAM_REQUEST_ID, data->requestId) ||
2884 nla_put_u32(skb, PARAM_STATUS, data->status) ||
2885 nla_put_u32(skb, MAX_SCAN_CACHE_SIZE, data->scanCacheSize) ||
2886 nla_put_u32(skb, MAX_SCAN_BUCKETS, data->scanBuckets) ||
2887 nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN,
2888 data->maxApPerScan) ||
2889 nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE,
2890 data->maxRssiSampleSize) ||
2891 nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD,
2892 data->maxScanReportingThreshold) ||
2893 nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->maxHotlistAPs) ||
2894 nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES,
2895 data->maxBsidHistoryEntries) ||
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302896 nla_put_u32(skb, MAX_HOTLIST_SSIDS, data->maxHotlistSSIDs) ||
2897 nla_put_u32(skb, MAX_SIGNIFICANT_WIFI_CHANGE_APS, 0))
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302898 {
2899 hddLog(LOGE, FL("nla put fail"));
2900 goto nla_put_failure;
2901 }
2902
2903 cfg80211_vendor_cmd_reply(skb);
2904 return 0;
2905
2906nla_put_failure:
2907 kfree_skb(skb);
2908 return -EINVAL;;
2909}
2910
2911/*
2912 * done with short names for the global vendor params
2913 * used by wlan_hdd_send_ext_scan_capability()
2914 */
2915#undef PARAM_REQUEST_ID
2916#undef PARAM_STATUS
2917#undef MAX_SCAN_CACHE_SIZE
2918#undef MAX_SCAN_BUCKETS
2919#undef MAX_AP_CACHE_PER_SCAN
2920#undef MAX_RSSI_SAMPLE_SIZE
2921#undef MAX_SCAN_RPT_THRHOLD
2922#undef MAX_HOTLIST_BSSIDS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302923#undef MAX_BSSID_HISTORY_ENTRIES
2924#undef MAX_HOTLIST_SSIDS
Dino Mycle6fb96c12014-06-10 11:52:40 +05302925
2926static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
2927{
2928 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
2929 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302930 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302931 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302932
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302933 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302934
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302935 if (wlan_hdd_validate_context(pHddCtx))
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302936 return;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302937
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302938 if (!pMsg)
2939 {
2940 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302941 return;
2942 }
2943
Dino Mycle6fb96c12014-06-10 11:52:40 +05302944 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2945 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2946
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302947 context = &pHddCtx->ext_scan_context;
2948 spin_lock(&hdd_context_lock);
2949 if (context->request_id == pData->requestId) {
2950 context->response_status = pData->status ? -EINVAL : 0;
2951 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302952 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302953 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302954
2955 /*
2956 * Store the Request ID for comparing with the requestID obtained
2957 * in other requests.HDD shall return a failure is the extscan_stop
2958 * request is issued with a different requestId as that of the
2959 * extscan_start request. Also, This requestId shall be used while
2960 * indicating the full scan results to the upper layers.
2961 * The requestId is stored with the assumption that the firmware
2962 * shall return the ext scan start request's requestId in ext scan
2963 * start response.
2964 */
2965 if (pData->status == 0)
2966 pMac->sme.extScanStartReqId = pData->requestId;
2967
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302968 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302969 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302970}
2971
2972
2973static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2974{
2975 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2976 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302977 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302978
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302979 ENTER();
2980
2981 if (wlan_hdd_validate_context(pHddCtx)){
2982 return;
2983 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302984
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302985 if (!pMsg)
2986 {
2987 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302988 return;
2989 }
2990
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302991 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2992 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302993
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302994 context = &pHddCtx->ext_scan_context;
2995 spin_lock(&hdd_context_lock);
2996 if (context->request_id == pData->requestId) {
2997 context->response_status = pData->status ? -EINVAL : 0;
2998 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302999 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303000 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303001
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303002 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303003 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303004}
3005
Dino Mycle6fb96c12014-06-10 11:52:40 +05303006static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
3007 void *pMsg)
3008{
3009 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303010 tpSirEXTScanSetBssidHotListRspParams pData =
3011 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303012 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303013
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303014 ENTER();
3015
3016 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05303017 return;
3018 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303019
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303020 if (!pMsg)
3021 {
3022 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3023 return;
3024 }
3025
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303026 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3027 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303028
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303029 context = &pHddCtx->ext_scan_context;
3030 spin_lock(&hdd_context_lock);
3031 if (context->request_id == pData->requestId) {
3032 context->response_status = pData->status ? -EINVAL : 0;
3033 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303034 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303035 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303036
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303037 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303038 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303039}
3040
3041static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
3042 void *pMsg)
3043{
3044 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303045 tpSirEXTScanResetBssidHotlistRspParams pData =
3046 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303047 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303048
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303049 ENTER();
3050
3051 if (wlan_hdd_validate_context(pHddCtx)) {
3052 return;
3053 }
3054 if (!pMsg)
3055 {
3056 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303057 return;
3058 }
3059
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303060 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3061 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303062
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303063 context = &pHddCtx->ext_scan_context;
3064 spin_lock(&hdd_context_lock);
3065 if (context->request_id == pData->requestId) {
3066 context->response_status = pData->status ? -EINVAL : 0;
3067 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303068 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303069 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303070
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303071 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303072 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303073}
3074
Dino Mycle6fb96c12014-06-10 11:52:40 +05303075static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
3076 void *pMsg)
3077{
3078 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3079 struct sk_buff *skb = NULL;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303080 tANI_U32 i = 0, j, resultsPerEvent, scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303081 tANI_S32 totalResults;
3082 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303083 tpSirWifiScanResult pSirWifiScanResult, head_ptr;
3084 struct hdd_ext_scan_context *context;
3085 bool ignore_cached_results = false;
3086 tExtscanCachedScanResult *result;
3087 struct nlattr *nla_results;
3088 tANI_U16 ieLength= 0;
3089 tANI_U8 *ie = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303090
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303091 ENTER();
3092
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303093 if (wlan_hdd_validate_context(pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303094 return;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303095
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303096 if (!pMsg)
3097 {
3098 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3099 return;
3100 }
3101
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303102 spin_lock(&hdd_context_lock);
3103 context = &pHddCtx->ext_scan_context;
3104 ignore_cached_results = context->ignore_cached_results;
3105 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303106
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303107 if (ignore_cached_results) {
3108 hddLog(LOGE,
3109 FL("Ignore the cached results received after timeout"));
3110 return;
3111 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303112
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303113 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u More Data %u No of scan ids %u",
3114 pData->requestId, pData->moreData, pData->scanResultSize);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303115
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303116 result = (tExtscanCachedScanResult *)&(pData->result);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303117
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303118 for (scan_id_index = 0; scan_id_index < pData->scanResultSize;
3119 scan_id_index++) {
3120 result+= scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303121
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303122 totalResults = result->num_results;
3123 hddLog(VOS_TRACE_LEVEL_INFO, "scan_id %u flags %u Num results %u",
3124 result->scan_id, result->flags, totalResults);
3125 i = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303126
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303127 do{
3128 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
3129 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
3130 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303131
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303132 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
3133 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN);
3134
3135 if (!skb) {
3136 hddLog(VOS_TRACE_LEVEL_ERROR,
3137 FL("cfg80211_vendor_event_alloc failed"));
3138 return;
3139 }
3140
3141 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
3142
3143 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3144 pData->requestId) ||
3145 nla_put_u32(skb,
3146 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3147 resultsPerEvent)) {
3148 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3149 goto fail;
3150 }
3151 if (nla_put_u8(skb,
3152 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3153 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303154 {
3155 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3156 goto fail;
3157 }
3158
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303159 if (nla_put_u32(skb,
3160 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
3161 result->scan_id)) {
3162 hddLog(LOGE, FL("put fail"));
3163 goto fail;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303164 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303165
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303166 nla_results = nla_nest_start(skb,
3167 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_LIST);
3168 if (!nla_results)
3169 goto fail;
3170
3171 if (resultsPerEvent) {
3172 struct nlattr *aps;
3173 struct nlattr *nla_result;
3174
3175 nla_result = nla_nest_start(skb, scan_id_index);
3176 if(!nla_result)
3177 goto fail;
3178
3179 if (nla_put_u32(skb,
3180 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
3181 result->scan_id) ||
3182 nla_put_u32(skb,
3183 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_FLAGS,
3184 result->flags) ||
3185 nla_put_u32(skb,
3186 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3187 totalResults)) {
3188 hddLog(LOGE, FL("put fail"));
3189 goto fail;
3190 }
3191
3192 aps = nla_nest_start(skb,
3193 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3194 if (!aps)
3195 {
3196 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3197 goto fail;
3198 }
3199
3200 head_ptr = (tpSirWifiScanResult) &(result->ap);
3201
3202 for (j = 0; j < resultsPerEvent; j++, i++) {
3203 struct nlattr *ap;
3204 pSirWifiScanResult = head_ptr + i;
3205
3206 /*
Srinivas Dasari91727c12016-03-23 17:59:06 +05303207 * Firmware returns timestamp from extscan_start till
3208 * BSSID was cached (in micro seconds). Add this with
3209 * time gap between system boot up to extscan_start
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303210 * to derive the time since boot when the
3211 * BSSID was cached.
3212 */
Srinivas Dasari91727c12016-03-23 17:59:06 +05303213 pSirWifiScanResult->ts +=
3214 pHddCtx->extscan_start_time_since_boot;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303215 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
3216 "Ssid (%s)"
3217 "Bssid: %pM "
3218 "Channel (%u)"
3219 "Rssi (%d)"
3220 "RTT (%u)"
3221 "RTT_SD (%u)"
3222 "Beacon Period %u"
3223 "Capability 0x%x "
3224 "Ie length %d",
3225 i,
3226 pSirWifiScanResult->ts,
3227 pSirWifiScanResult->ssid,
3228 pSirWifiScanResult->bssid,
3229 pSirWifiScanResult->channel,
3230 pSirWifiScanResult->rssi,
3231 pSirWifiScanResult->rtt,
3232 pSirWifiScanResult->rtt_sd,
3233 pSirWifiScanResult->beaconPeriod,
3234 pSirWifiScanResult->capability,
3235 ieLength);
3236
3237 ap = nla_nest_start(skb, j + 1);
3238 if (!ap)
3239 {
3240 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3241 goto fail;
3242 }
3243
3244 if (nla_put_u64(skb,
3245 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3246 pSirWifiScanResult->ts) )
3247 {
3248 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3249 goto fail;
3250 }
3251 if (nla_put(skb,
3252 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3253 sizeof(pSirWifiScanResult->ssid),
3254 pSirWifiScanResult->ssid) )
3255 {
3256 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3257 goto fail;
3258 }
3259 if (nla_put(skb,
3260 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3261 sizeof(pSirWifiScanResult->bssid),
3262 pSirWifiScanResult->bssid) )
3263 {
3264 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3265 goto fail;
3266 }
3267 if (nla_put_u32(skb,
3268 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3269 pSirWifiScanResult->channel) )
3270 {
3271 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3272 goto fail;
3273 }
3274 if (nla_put_s32(skb,
3275 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
3276 pSirWifiScanResult->rssi) )
3277 {
3278 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3279 goto fail;
3280 }
3281 if (nla_put_u32(skb,
3282 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3283 pSirWifiScanResult->rtt) )
3284 {
3285 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3286 goto fail;
3287 }
3288 if (nla_put_u32(skb,
3289 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3290 pSirWifiScanResult->rtt_sd))
3291 {
3292 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3293 goto fail;
3294 }
3295 if (nla_put_u32(skb,
3296 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3297 pSirWifiScanResult->beaconPeriod))
3298 {
3299 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3300 goto fail;
3301 }
3302 if (nla_put_u32(skb,
3303 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3304 pSirWifiScanResult->capability))
3305 {
3306 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3307 goto fail;
3308 }
3309 if (nla_put_u32(skb,
3310 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
3311 ieLength))
3312 {
3313 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3314 goto fail;
3315 }
3316
3317 if (ieLength)
3318 if (nla_put(skb,
3319 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3320 ieLength, ie)) {
3321 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3322 goto fail;
3323 }
3324
3325 nla_nest_end(skb, ap);
3326 }
3327 nla_nest_end(skb, aps);
3328 nla_nest_end(skb, nla_result);
3329 }
3330
3331 nla_nest_end(skb, nla_results);
3332
3333 cfg80211_vendor_cmd_reply(skb);
3334
3335 } while (totalResults > 0);
3336 }
3337
3338 if (!pData->moreData) {
3339 spin_lock(&hdd_context_lock);
3340 context->response_status = 0;
3341 complete(&context->response_event);
3342 spin_unlock(&hdd_context_lock);
3343 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303344
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303345 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303346 return;
3347fail:
3348 kfree_skb(skb);
3349 return;
3350}
3351
3352static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
3353 void *pMsg)
3354{
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303355 tpSirEXTScanHotlistMatch pData = (tpSirEXTScanHotlistMatch) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303356 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3357 struct sk_buff *skb = NULL;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303358 tANI_U32 i, index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303359
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303360 ENTER();
3361
3362 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303363 hddLog(LOGE,
3364 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303365 return;
3366 }
3367 if (!pMsg)
3368 {
3369 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303370 return;
3371 }
3372
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303373 if (pData->bss_found)
3374 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX;
3375 else
3376 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX;
3377
Dino Mycle6fb96c12014-06-10 11:52:40 +05303378 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303379#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3380 NULL,
3381#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303382 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303383 index, GFP_KERNEL);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303384
3385 if (!skb) {
3386 hddLog(VOS_TRACE_LEVEL_ERROR,
3387 FL("cfg80211_vendor_event_alloc failed"));
3388 return;
3389 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303390
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303391 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3392 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numHotlistBss);
3393 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
3394 hddLog(VOS_TRACE_LEVEL_INFO, "ap_found %u", pData->bss_found);
3395
3396 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303397 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
3398 "Ssid (%s) "
3399 "Bssid (" MAC_ADDRESS_STR ") "
3400 "Channel (%u) "
3401 "Rssi (%d) "
3402 "RTT (%u) "
3403 "RTT_SD (%u) ",
3404 i,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303405 pData->bssHotlist[i].ts,
3406 pData->bssHotlist[i].ssid,
3407 MAC_ADDR_ARRAY(pData->bssHotlist[i].bssid),
3408 pData->bssHotlist[i].channel,
3409 pData->bssHotlist[i].rssi,
3410 pData->bssHotlist[i].rtt,
3411 pData->bssHotlist[i].rtt_sd);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303412 }
3413
3414 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3415 pData->requestId) ||
3416 nla_put_u32(skb,
3417 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303418 pData->numHotlistBss)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303419 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3420 goto fail;
3421 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303422 if (pData->numHotlistBss) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303423 struct nlattr *aps;
3424
3425 aps = nla_nest_start(skb,
3426 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3427 if (!aps)
3428 goto fail;
3429
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303430 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303431 struct nlattr *ap;
3432
3433 ap = nla_nest_start(skb, i + 1);
3434 if (!ap)
3435 goto fail;
3436
3437 if (nla_put_u64(skb,
3438 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303439 pData->bssHotlist[i].ts) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303440 nla_put(skb,
3441 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303442 sizeof(pData->bssHotlist[i].ssid),
3443 pData->bssHotlist[i].ssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303444 nla_put(skb,
3445 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303446 sizeof(pData->bssHotlist[i].bssid),
3447 pData->bssHotlist[i].bssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303448 nla_put_u32(skb,
3449 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303450 pData->bssHotlist[i].channel) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303451 nla_put_s32(skb,
3452 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303453 pData->bssHotlist[i].rssi) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303454 nla_put_u32(skb,
3455 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303456 pData->bssHotlist[i].rtt) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303457 nla_put_u32(skb,
3458 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303459 pData->bssHotlist[i].rtt_sd))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303460 goto fail;
3461
3462 nla_nest_end(skb, ap);
3463 }
3464 nla_nest_end(skb, aps);
3465
3466 if (nla_put_u8(skb,
3467 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3468 pData->moreData))
3469 goto fail;
3470 }
3471
3472 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303473 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303474 return;
3475
3476fail:
3477 kfree_skb(skb);
3478 return;
3479
3480}
Dino Mycle6fb96c12014-06-10 11:52:40 +05303481
3482static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
3483 void *pMsg)
3484{
3485 struct sk_buff *skb;
3486 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3487 tpSirWifiFullScanResultEvent pData =
3488 (tpSirWifiFullScanResultEvent) (pMsg);
3489
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303490 ENTER();
3491
3492 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303493 hddLog(LOGE,
3494 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303495 return;
3496 }
3497 if (!pMsg)
3498 {
3499 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303500 return;
3501 }
3502
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303503 /*
3504 * If the full scan result including IE data exceeds NL 4K size
3505 * limitation, drop that beacon/probe rsp frame.
3506 */
3507 if ((sizeof(*pData) + pData->ieLength) >= EXTSCAN_EVENT_BUF_SIZE) {
3508 hddLog(LOGE, FL("Frame exceeded NL size limilation, drop it!"));
3509 return;
3510 }
3511
Dino Mycle6fb96c12014-06-10 11:52:40 +05303512 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303513#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3514 NULL,
3515#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303516 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3517 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
3518 GFP_KERNEL);
3519
3520 if (!skb) {
3521 hddLog(VOS_TRACE_LEVEL_ERROR,
3522 FL("cfg80211_vendor_event_alloc failed"));
3523 return;
3524 }
3525
Dino Mycle6fb96c12014-06-10 11:52:40 +05303526 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
3527 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
3528 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
3529 "Ssid (%s)"
3530 "Bssid (" MAC_ADDRESS_STR ")"
3531 "Channel (%u)"
3532 "Rssi (%d)"
3533 "RTT (%u)"
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303534 "RTT_SD (%u)"
3535 "Bcn Period %d"
3536 "Capability 0x%X "),
Dino Mycle6fb96c12014-06-10 11:52:40 +05303537 pData->ap.ts,
3538 pData->ap.ssid,
3539 MAC_ADDR_ARRAY(pData->ap.bssid),
3540 pData->ap.channel,
3541 pData->ap.rssi,
3542 pData->ap.rtt,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303543 pData->ap.rtt_sd,
3544 pData->ap.beaconPeriod,
3545 pData->ap.capability);
3546
Dino Mycle6fb96c12014-06-10 11:52:40 +05303547 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
3548 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3549 pData->requestId) ||
3550 nla_put_u64(skb,
3551 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3552 pData->ap.ts) ||
3553 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3554 sizeof(pData->ap.ssid),
3555 pData->ap.ssid) ||
3556 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3557 WNI_CFG_BSSID_LEN,
3558 pData->ap.bssid) ||
3559 nla_put_u32(skb,
3560 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3561 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05303562 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303563 pData->ap.rssi) ||
3564 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3565 pData->ap.rtt) ||
3566 nla_put_u32(skb,
3567 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3568 pData->ap.rtt_sd) ||
3569 nla_put_u16(skb,
3570 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3571 pData->ap.beaconPeriod) ||
3572 nla_put_u16(skb,
3573 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3574 pData->ap.capability) ||
3575 nla_put_u32(skb,
3576 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303577 pData->ieLength) ||
3578 nla_put_u8(skb,
3579 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3580 pData->moreData))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303581 {
3582 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3583 goto nla_put_failure;
3584 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303585
3586 if (pData->ieLength) {
3587 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3588 pData->ieLength,
3589 pData->ie))
3590 {
3591 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3592 goto nla_put_failure;
3593 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303594 }
3595
3596 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303597 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303598 return;
3599
3600nla_put_failure:
3601 kfree_skb(skb);
3602 return;
3603}
3604
3605static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
3606 void *pMsg)
3607{
3608 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3609 struct sk_buff *skb = NULL;
3610 tpSirEXTScanResultsAvailableIndParams pData =
3611 (tpSirEXTScanResultsAvailableIndParams) pMsg;
3612
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303613 ENTER();
3614
3615 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303616 hddLog(LOGE,
3617 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303618 return;
3619 }
3620 if (!pMsg)
3621 {
3622 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303623 return;
3624 }
3625
3626 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303627#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3628 NULL,
3629#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303630 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3631 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
3632 GFP_KERNEL);
3633
3634 if (!skb) {
3635 hddLog(VOS_TRACE_LEVEL_ERROR,
3636 FL("cfg80211_vendor_event_alloc failed"));
3637 return;
3638 }
3639
Dino Mycle6fb96c12014-06-10 11:52:40 +05303640 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3641 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
3642 pData->numResultsAvailable);
3643 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3644 pData->requestId) ||
3645 nla_put_u32(skb,
3646 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3647 pData->numResultsAvailable)) {
3648 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3649 goto nla_put_failure;
3650 }
3651
3652 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303653 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303654 return;
3655
3656nla_put_failure:
3657 kfree_skb(skb);
3658 return;
3659}
3660
3661static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
3662{
3663 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3664 struct sk_buff *skb = NULL;
3665 tpSirEXTScanProgressIndParams pData =
3666 (tpSirEXTScanProgressIndParams) pMsg;
3667
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303668 ENTER();
3669
3670 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303671 hddLog(LOGE,
3672 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303673 return;
3674 }
3675 if (!pMsg)
3676 {
3677 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303678 return;
3679 }
3680
3681 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303682#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3683 NULL,
3684#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303685 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3686 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
3687 GFP_KERNEL);
3688
3689 if (!skb) {
3690 hddLog(VOS_TRACE_LEVEL_ERROR,
3691 FL("cfg80211_vendor_event_alloc failed"));
3692 return;
3693 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303694 hddLog(VOS_TRACE_LEVEL_INFO, FL("Request Id (%u) "), pData->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303695 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
3696 pData->extScanEventType);
3697 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
3698 pData->status);
3699
3700 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
3701 pData->extScanEventType) ||
3702 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05303703 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3704 pData->requestId) ||
3705 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303706 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
3707 pData->status)) {
3708 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3709 goto nla_put_failure;
3710 }
3711
3712 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303713 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303714 return;
3715
3716nla_put_failure:
3717 kfree_skb(skb);
3718 return;
3719}
3720
3721void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
3722 void *pMsg)
3723{
3724 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3725
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303726 ENTER();
3727
Dino Mycle6fb96c12014-06-10 11:52:40 +05303728 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303729 return;
3730 }
3731
3732 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
3733
3734
3735 switch(evType) {
3736 case SIR_HAL_EXTSCAN_START_RSP:
3737 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
3738 break;
3739
3740 case SIR_HAL_EXTSCAN_STOP_RSP:
3741 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
3742 break;
3743 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
3744 /* There is no need to send this response to upper layer
3745 Just log the message */
3746 hddLog(VOS_TRACE_LEVEL_INFO,
3747 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
3748 break;
3749 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
3750 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
3751 break;
3752
3753 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
3754 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
3755 break;
3756
Dino Mycle6fb96c12014-06-10 11:52:40 +05303757 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303758 wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx, pMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303759 break;
3760 case SIR_HAL_EXTSCAN_PROGRESS_IND:
3761 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
3762 break;
3763 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
3764 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
3765 break;
3766 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
3767 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
3768 break;
3769 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
3770 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
3771 break;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303772 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
3773 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
3774 break;
3775 default:
3776 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
3777 break;
3778 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303779 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303780}
3781
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303782static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3783 struct wireless_dev *wdev,
3784 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303785{
Dino Myclee8843b32014-07-04 14:21:45 +05303786 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303787 struct net_device *dev = wdev->netdev;
3788 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3789 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3790 struct nlattr
3791 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3792 eHalStatus status;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303793 struct hdd_ext_scan_context *context;
3794 unsigned long rc;
3795 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303796
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303797 ENTER();
3798
Dino Mycle6fb96c12014-06-10 11:52:40 +05303799 status = wlan_hdd_validate_context(pHddCtx);
3800 if (0 != status)
3801 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303802 return -EINVAL;
3803 }
Dino Myclee8843b32014-07-04 14:21:45 +05303804 /* check the EXTScan Capability */
3805 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303806 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3807 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303808 {
3809 hddLog(VOS_TRACE_LEVEL_ERROR,
3810 FL("EXTScan not enabled/supported by Firmware"));
3811 return -EINVAL;
3812 }
3813
Dino Mycle6fb96c12014-06-10 11:52:40 +05303814 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3815 data, dataLen,
3816 wlan_hdd_extscan_config_policy)) {
3817 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3818 return -EINVAL;
3819 }
3820
3821 /* Parse and fetch request Id */
3822 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3823 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3824 return -EINVAL;
3825 }
3826
Dino Myclee8843b32014-07-04 14:21:45 +05303827 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303828 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303829 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303830
Dino Myclee8843b32014-07-04 14:21:45 +05303831 reqMsg.sessionId = pAdapter->sessionId;
3832 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303833
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303834 vos_spin_lock_acquire(&hdd_context_lock);
3835 context = &pHddCtx->ext_scan_context;
3836 context->request_id = reqMsg.requestId;
3837 INIT_COMPLETION(context->response_event);
3838 vos_spin_lock_release(&hdd_context_lock);
3839
Dino Myclee8843b32014-07-04 14:21:45 +05303840 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303841 if (!HAL_STATUS_SUCCESS(status)) {
3842 hddLog(VOS_TRACE_LEVEL_ERROR,
3843 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303844 return -EINVAL;
3845 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303846
3847 rc = wait_for_completion_timeout(&context->response_event,
3848 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3849 if (!rc) {
3850 hddLog(LOGE, FL("Target response timed out"));
3851 return -ETIMEDOUT;
3852 }
3853
3854 ret = wlan_hdd_send_ext_scan_capability(pHddCtx);
3855 if (ret)
3856 hddLog(LOGE, FL("Failed to send ext scan capability to user space"));
3857
3858 return ret;
3859
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303860 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303861 return 0;
3862}
3863
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303864static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3865 struct wireless_dev *wdev,
3866 const void *data, int dataLen)
3867{
3868 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303869
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303870 vos_ssr_protect(__func__);
3871 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
3872 vos_ssr_unprotect(__func__);
3873
3874 return ret;
3875}
3876
3877static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3878 struct wireless_dev *wdev,
3879 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303880{
Dino Myclee8843b32014-07-04 14:21:45 +05303881 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303882 struct net_device *dev = wdev->netdev;
3883 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3884 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3885 struct nlattr
3886 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3887 eHalStatus status;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303888 struct hdd_ext_scan_context *context;
3889 unsigned long rc;
3890 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303891
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303892 ENTER();
3893
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303894 if (VOS_FTM_MODE == hdd_get_conparam()) {
3895 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3896 return -EINVAL;
3897 }
3898
Dino Mycle6fb96c12014-06-10 11:52:40 +05303899 status = wlan_hdd_validate_context(pHddCtx);
3900 if (0 != status)
3901 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303902 return -EINVAL;
3903 }
Dino Myclee8843b32014-07-04 14:21:45 +05303904 /* check the EXTScan Capability */
3905 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303906 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3907 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303908 {
3909 hddLog(VOS_TRACE_LEVEL_ERROR,
3910 FL("EXTScan not enabled/supported by Firmware"));
3911 return -EINVAL;
3912 }
3913
Dino Mycle6fb96c12014-06-10 11:52:40 +05303914 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3915 data, dataLen,
3916 wlan_hdd_extscan_config_policy)) {
3917 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3918 return -EINVAL;
3919 }
3920 /* Parse and fetch request Id */
3921 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3922 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3923 return -EINVAL;
3924 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303925
Dino Myclee8843b32014-07-04 14:21:45 +05303926 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303927 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3928
Dino Myclee8843b32014-07-04 14:21:45 +05303929 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303930
Dino Myclee8843b32014-07-04 14:21:45 +05303931 reqMsg.sessionId = pAdapter->sessionId;
3932 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303933
3934 /* Parse and fetch flush parameter */
3935 if (!tb
3936 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3937 {
3938 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3939 goto failed;
3940 }
Dino Myclee8843b32014-07-04 14:21:45 +05303941 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303942 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3943
Dino Myclee8843b32014-07-04 14:21:45 +05303944 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303945
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303946 spin_lock(&hdd_context_lock);
3947 context = &pHddCtx->ext_scan_context;
3948 context->request_id = reqMsg.requestId;
3949 context->ignore_cached_results = false;
3950 INIT_COMPLETION(context->response_event);
3951 spin_unlock(&hdd_context_lock);
3952
Dino Myclee8843b32014-07-04 14:21:45 +05303953 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303954 if (!HAL_STATUS_SUCCESS(status)) {
3955 hddLog(VOS_TRACE_LEVEL_ERROR,
3956 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303957 return -EINVAL;
3958 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303959
3960 rc = wait_for_completion_timeout(&context->response_event,
3961 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3962 if (!rc) {
3963 hddLog(LOGE, FL("Target response timed out"));
3964 retval = -ETIMEDOUT;
3965 spin_lock(&hdd_context_lock);
3966 context->ignore_cached_results = true;
3967 spin_unlock(&hdd_context_lock);
3968 } else {
3969 spin_lock(&hdd_context_lock);
3970 retval = context->response_status;
3971 spin_unlock(&hdd_context_lock);
3972 }
3973
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303974 EXIT();
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303975 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303976
3977failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303978 return -EINVAL;
3979}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303980static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3981 struct wireless_dev *wdev,
3982 const void *data, int dataLen)
3983{
3984 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303985
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303986 vos_ssr_protect(__func__);
3987 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
3988 vos_ssr_unprotect(__func__);
3989
3990 return ret;
3991}
3992
3993static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303994 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05303995 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303996{
3997 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3998 struct net_device *dev = wdev->netdev;
3999 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4000 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4001 struct nlattr
4002 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4003 struct nlattr
4004 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4005 struct nlattr *apTh;
4006 eHalStatus status;
4007 tANI_U8 i = 0;
4008 int rem;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304009 struct hdd_ext_scan_context *context;
4010 tANI_U32 request_id;
4011 unsigned long rc;
4012 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304013
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304014 ENTER();
4015
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304016 if (VOS_FTM_MODE == hdd_get_conparam()) {
4017 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4018 return -EINVAL;
4019 }
4020
Dino Mycle6fb96c12014-06-10 11:52:40 +05304021 status = wlan_hdd_validate_context(pHddCtx);
4022 if (0 != status)
4023 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304024 return -EINVAL;
4025 }
Dino Myclee8843b32014-07-04 14:21:45 +05304026 /* check the EXTScan Capability */
4027 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304028 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4029 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304030 {
4031 hddLog(VOS_TRACE_LEVEL_ERROR,
4032 FL("EXTScan not enabled/supported by Firmware"));
4033 return -EINVAL;
4034 }
4035
Dino Mycle6fb96c12014-06-10 11:52:40 +05304036 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4037 data, dataLen,
4038 wlan_hdd_extscan_config_policy)) {
4039 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4040 return -EINVAL;
4041 }
4042
4043 /* Parse and fetch request Id */
4044 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4045 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4046 return -EINVAL;
4047 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304048 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
4049 vos_mem_malloc(sizeof(*pReqMsg));
4050 if (!pReqMsg) {
4051 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4052 return -ENOMEM;
4053 }
4054
Dino Myclee8843b32014-07-04 14:21:45 +05304055
Dino Mycle6fb96c12014-06-10 11:52:40 +05304056 pReqMsg->requestId = nla_get_u32(
4057 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4058 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4059
4060 /* Parse and fetch number of APs */
4061 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
4062 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
4063 goto fail;
4064 }
4065
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304066 /* Parse and fetch lost ap sample size */
4067 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]) {
4068 hddLog(LOGE, FL("attr lost ap sample size failed"));
4069 goto fail;
4070 }
4071
4072 pReqMsg->lostBssidSampleSize = nla_get_u32(
4073 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]);
4074 hddLog(LOG1, FL("Lost ap sample size %d"), pReqMsg->lostBssidSampleSize);
4075
Dino Mycle6fb96c12014-06-10 11:52:40 +05304076 pReqMsg->sessionId = pAdapter->sessionId;
4077 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4078
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304079 pReqMsg->numBssid = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304080 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304081 if (pReqMsg->numBssid > WLAN_EXTSCAN_MAX_HOTLIST_APS) {
4082 hddLog(LOGE, FL("Number of AP: %u exceeds max: %u"),
4083 pReqMsg->numBssid, WLAN_EXTSCAN_MAX_HOTLIST_APS);
4084 goto fail;
4085 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304086 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numBssid);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304087
4088 nla_for_each_nested(apTh,
4089 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304090 if (i == pReqMsg->numBssid) {
4091 hddLog(LOGW, FL("Ignoring excess AP"));
4092 break;
4093 }
4094
Dino Mycle6fb96c12014-06-10 11:52:40 +05304095 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4096 nla_data(apTh), nla_len(apTh),
4097 NULL)) {
4098 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
4099 goto fail;
4100 }
4101
4102 /* Parse and fetch MAC address */
4103 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
4104 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
4105 goto fail;
4106 }
4107 memcpy(pReqMsg->ap[i].bssid, nla_data(
4108 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
4109 sizeof(tSirMacAddr));
4110 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
4111
4112 /* Parse and fetch low RSSI */
4113 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
4114 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
4115 goto fail;
4116 }
4117 pReqMsg->ap[i].low = nla_get_s32(
4118 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
4119 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
4120
4121 /* Parse and fetch high RSSI */
4122 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
4123 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
4124 goto fail;
4125 }
4126 pReqMsg->ap[i].high = nla_get_s32(
4127 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
4128 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
4129 pReqMsg->ap[i].high);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304130 i++;
4131 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304132
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304133 if (i < pReqMsg->numBssid) {
4134 hddLog(LOGW, FL("Number of AP %u less than expected %u"),
4135 i, pReqMsg->numBssid);
4136 pReqMsg->numBssid = i;
4137 }
4138
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304139 context = &pHddCtx->ext_scan_context;
4140 spin_lock(&hdd_context_lock);
4141 INIT_COMPLETION(context->response_event);
4142 context->request_id = request_id = pReqMsg->requestId;
4143 spin_unlock(&hdd_context_lock);
4144
Dino Mycle6fb96c12014-06-10 11:52:40 +05304145 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
4146 if (!HAL_STATUS_SUCCESS(status)) {
4147 hddLog(VOS_TRACE_LEVEL_ERROR,
4148 FL("sme_SetBssHotlist failed(err=%d)"), status);
4149 vos_mem_free(pReqMsg);
4150 return -EINVAL;
4151 }
4152
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304153 /* request was sent -- wait for the response */
4154 rc = wait_for_completion_timeout(&context->response_event,
4155 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4156
4157 if (!rc) {
4158 hddLog(LOGE, FL("sme_SetBssHotlist timed out"));
4159 retval = -ETIMEDOUT;
4160 } else {
4161 spin_lock(&hdd_context_lock);
4162 if (context->request_id == request_id)
4163 retval = context->response_status;
4164 else
4165 retval = -EINVAL;
4166 spin_unlock(&hdd_context_lock);
4167 }
4168
Dino Myclee8843b32014-07-04 14:21:45 +05304169 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304170 EXIT();
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304171 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304172
4173fail:
4174 vos_mem_free(pReqMsg);
4175 return -EINVAL;
4176}
4177
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304178static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
4179 struct wireless_dev *wdev,
4180 const void *data, int dataLen)
4181{
4182 int ret = 0;
4183
4184 vos_ssr_protect(__func__);
4185 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
4186 dataLen);
4187 vos_ssr_unprotect(__func__);
4188
4189 return ret;
4190}
4191
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304192static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304193 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304194 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304195{
Agrawal Ashish16abf782016-08-18 22:42:59 +05304196 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4197 struct net_device *dev = wdev->netdev;
4198 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4199 uint32_t chan_list[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4200 uint8_t num_channels = 0;
4201 uint8_t num_chan_new = 0;
4202 uint8_t buf[256] = {0};
Dino Mycle6fb96c12014-06-10 11:52:40 +05304203 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304204 tANI_U32 requestId, maxChannels;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304205 tWifiBand wifiBand;
4206 eHalStatus status;
4207 struct sk_buff *replySkb;
Agrawal Ashish16abf782016-08-18 22:42:59 +05304208 tANI_U8 i,j,k;
4209 int ret,len = 0;;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304210
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304211 ENTER();
4212
Dino Mycle6fb96c12014-06-10 11:52:40 +05304213 status = wlan_hdd_validate_context(pHddCtx);
4214 if (0 != status)
4215 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304216 return -EINVAL;
4217 }
Dino Myclee8843b32014-07-04 14:21:45 +05304218
Dino Mycle6fb96c12014-06-10 11:52:40 +05304219 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4220 data, dataLen,
4221 wlan_hdd_extscan_config_policy)) {
4222 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4223 return -EINVAL;
4224 }
4225
4226 /* Parse and fetch request Id */
4227 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4228 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4229 return -EINVAL;
4230 }
4231 requestId = nla_get_u32(
4232 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4233 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
4234
4235 /* Parse and fetch wifi band */
4236 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
4237 {
4238 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4239 return -EINVAL;
4240 }
4241 wifiBand = nla_get_u32(
4242 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
4243 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
4244
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304245 /* Parse and fetch max channels */
4246 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
4247 {
4248 hddLog(LOGE, FL("attr max channels failed"));
4249 return -EINVAL;
4250 }
4251 maxChannels = nla_get_u32(
4252 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
4253 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);
4254
Dino Mycle6fb96c12014-06-10 11:52:40 +05304255 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
Agrawal Ashish16abf782016-08-18 22:42:59 +05304256 wifiBand, chan_list,
4257 &num_channels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304258 if (eHAL_STATUS_SUCCESS != status) {
4259 hddLog(VOS_TRACE_LEVEL_ERROR,
4260 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
4261 return -EINVAL;
4262 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304263
Agrawal Ashish16abf782016-08-18 22:42:59 +05304264 num_channels = VOS_MIN(num_channels, maxChannels);
4265 num_chan_new = num_channels;
4266 /* remove the indoor only channels if iface is SAP */
4267 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
4268 {
4269 num_chan_new = 0;
4270 for (i = 0; i < num_channels; i++)
4271 for (j = 0; j < IEEE80211_NUM_BANDS; j++) {
4272 if (wiphy->bands[j] == NULL)
4273 continue;
4274 for (k = 0; k < wiphy->bands[j]->n_channels; k++) {
4275 if ((chan_list[i] ==
4276 wiphy->bands[j]->channels[k].center_freq) &&
4277 (!(wiphy->bands[j]->channels[k].flags &
4278 IEEE80211_CHAN_INDOOR_ONLY))) {
4279 chan_list[num_chan_new] = chan_list[i];
4280 num_chan_new++;
4281 }
4282 }
4283 }
4284 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304285
Agrawal Ashish16abf782016-08-18 22:42:59 +05304286 hddLog(LOG1, FL("Number of channels: %d"), num_chan_new);
4287 for (i = 0; i < num_chan_new; i++)
4288 len += scnprintf(buf + len, sizeof(buf) - len, "%u ", chan_list[i]);
4289 hddLog(LOG1, "Channels: %s", buf);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304290
4291 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
Agrawal Ashish16abf782016-08-18 22:42:59 +05304292 sizeof(u32) * num_chan_new +
Dino Mycle6fb96c12014-06-10 11:52:40 +05304293 NLMSG_HDRLEN);
4294
4295 if (!replySkb) {
4296 hddLog(VOS_TRACE_LEVEL_ERROR,
4297 FL("valid channels: buffer alloc fail"));
4298 return -EINVAL;
4299 }
4300 if (nla_put_u32(replySkb,
4301 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304302 num_chan_new) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05304303 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304304 sizeof(u32) * num_chan_new, chan_list)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304305
4306 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4307 kfree_skb(replySkb);
4308 return -EINVAL;
4309 }
4310
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304311 ret = cfg80211_vendor_cmd_reply(replySkb);
4312
4313 EXIT();
4314 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304315}
4316
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304317static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
4318 struct wireless_dev *wdev,
4319 const void *data, int dataLen)
4320{
4321 int ret = 0;
4322
4323 vos_ssr_protect(__func__);
4324 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
4325 dataLen);
4326 vos_ssr_unprotect(__func__);
4327
4328 return ret;
4329}
4330
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304331static int hdd_extscan_start_fill_bucket_channel_spec(
4332 hdd_context_t *pHddCtx,
4333 tpSirEXTScanStartReqParams pReqMsg,
4334 struct nlattr **tb)
4335{
4336 struct nlattr *bucket[
4337 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4338 struct nlattr *channel[
4339 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4340 struct nlattr *buckets;
4341 struct nlattr *channels;
4342 int rem1, rem2;
4343 eHalStatus status;
4344 tANI_U8 bktIndex, j, numChannels;
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304345 uint32_t expected_buckets;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304346 tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4347 tANI_U32 passive_max_chn_time, active_max_chn_time;
4348
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304349 expected_buckets = pReqMsg->numBuckets;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304350 bktIndex = 0;
4351
4352 nla_for_each_nested(buckets,
4353 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304354 if (bktIndex >= expected_buckets) {
4355 hddLog(LOGW, FL("ignoring excess buckets"));
4356 break;
4357 }
4358
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304359 if (nla_parse(bucket,
Ashish Kumar Dhanotiya9c93f562017-06-20 12:13:33 +05304360 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4361 nla_data(buckets), nla_len(buckets),
4362 wlan_hdd_extscan_config_policy)) {
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304363 hddLog(LOGE, FL("nla_parse failed"));
4364 return -EINVAL;
4365 }
4366
4367 /* Parse and fetch bucket spec */
4368 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4369 hddLog(LOGE, FL("attr bucket index failed"));
4370 return -EINVAL;
4371 }
4372 pReqMsg->buckets[bktIndex].bucket = nla_get_u8(
4373 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4374 hddLog(LOG1, FL("Bucket spec Index %d"),
4375 pReqMsg->buckets[bktIndex].bucket);
4376
4377 /* Parse and fetch wifi band */
4378 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4379 hddLog(LOGE, FL("attr wifi band failed"));
4380 return -EINVAL;
4381 }
4382 pReqMsg->buckets[bktIndex].band = nla_get_u8(
4383 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4384 hddLog(LOG1, FL("Wifi band %d"),
4385 pReqMsg->buckets[bktIndex].band);
4386
4387 /* Parse and fetch period */
4388 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4389 hddLog(LOGE, FL("attr period failed"));
4390 return -EINVAL;
4391 }
4392 pReqMsg->buckets[bktIndex].period = nla_get_u32(
4393 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4394 hddLog(LOG1, FL("period %d"),
4395 pReqMsg->buckets[bktIndex].period);
4396
4397 /* Parse and fetch report events */
4398 if (!bucket[
4399 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4400 hddLog(LOGE, FL("attr report events failed"));
4401 return -EINVAL;
4402 }
4403 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
4404 bucket[
4405 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4406 hddLog(LOG1, FL("report events %d"),
4407 pReqMsg->buckets[bktIndex].reportEvents);
4408
4409 /* Parse and fetch max period */
4410 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
4411 hddLog(LOGE, FL("attr max period failed"));
4412 return -EINVAL;
4413 }
4414 pReqMsg->buckets[bktIndex].max_period = nla_get_u32(
4415 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);
4416 hddLog(LOG1, FL("max period %u"),
4417 pReqMsg->buckets[bktIndex].max_period);
4418
4419 /* Parse and fetch exponent */
4420 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
4421 hddLog(LOGE, FL("attr exponent failed"));
4422 return -EINVAL;
4423 }
4424 pReqMsg->buckets[bktIndex].exponent = nla_get_u32(
4425 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
4426 hddLog(LOG1, FL("exponent %u"),
4427 pReqMsg->buckets[bktIndex].exponent);
4428
4429 /* Parse and fetch step count */
4430 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
4431 hddLog(LOGE, FL("attr step count failed"));
4432 return -EINVAL;
4433 }
4434 pReqMsg->buckets[bktIndex].step_count = nla_get_u32(
4435 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
4436 hddLog(LOG1, FL("Step count %u"),
4437 pReqMsg->buckets[bktIndex].step_count);
4438
4439 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time);
4440 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time);
4441
4442 /* Framework shall pass the channel list if the input WiFi band is
4443 * WIFI_BAND_UNSPECIFIED.
4444 * If the input WiFi band is specified (any value other than
4445 * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
4446 */
4447 if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) {
4448 numChannels = 0;
4449 hddLog(LOG1, "WiFi band is specified, driver to fill channel list");
4450 status = sme_GetValidChannelsByBand(pHddCtx->hHal,
4451 pReqMsg->buckets[bktIndex].band,
4452 chanList, &numChannels);
4453 if (!HAL_STATUS_SUCCESS(status)) {
4454 hddLog(LOGE,
4455 FL("sme_GetValidChannelsByBand failed (err=%d)"),
4456 status);
4457 return -EINVAL;
4458 }
4459
4460 pReqMsg->buckets[bktIndex].numChannels =
4461 VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS);
4462 hddLog(LOG1, FL("Num channels %d"),
4463 pReqMsg->buckets[bktIndex].numChannels);
4464
4465 for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels;
4466 j++) {
4467 pReqMsg->buckets[bktIndex].channels[j].channel =
4468 chanList[j];
4469 pReqMsg->buckets[bktIndex].channels[j].
4470 chnlClass = 0;
4471 if (CSR_IS_CHANNEL_DFS(
4472 vos_freq_to_chan(chanList[j]))) {
4473 pReqMsg->buckets[bktIndex].channels[j].
4474 passive = 1;
4475 pReqMsg->buckets[bktIndex].channels[j].
4476 dwellTimeMs = passive_max_chn_time;
4477 } else {
4478 pReqMsg->buckets[bktIndex].channels[j].
4479 passive = 0;
4480 pReqMsg->buckets[bktIndex].channels[j].
4481 dwellTimeMs = active_max_chn_time;
4482 }
4483
4484 hddLog(LOG1,
4485 "Channel %u Passive %u Dwell time %u ms",
4486 pReqMsg->buckets[bktIndex].channels[j].channel,
4487 pReqMsg->buckets[bktIndex].channels[j].passive,
4488 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4489 }
4490
4491 bktIndex++;
4492 continue;
4493 }
4494
4495 /* Parse and fetch number of channels */
4496 if (!bucket[
4497 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
4498 hddLog(LOGE, FL("attr num channels failed"));
4499 return -EINVAL;
4500 }
4501
4502 pReqMsg->buckets[bktIndex].numChannels =
4503 nla_get_u32(bucket[
4504 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
4505 hddLog(LOG1, FL("num channels %d"),
4506 pReqMsg->buckets[bktIndex].numChannels);
4507
4508 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
4509 hddLog(LOGE, FL("attr channel spec failed"));
4510 return -EINVAL;
4511 }
4512
4513 j = 0;
4514 nla_for_each_nested(channels,
4515 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
4516 if (nla_parse(channel,
4517 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4518 nla_data(channels), nla_len(channels),
4519 wlan_hdd_extscan_config_policy)) {
4520 hddLog(LOGE, FL("nla_parse failed"));
4521 return -EINVAL;
4522 }
4523
4524 /* Parse and fetch channel */
4525 if (!channel[
4526 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
4527 hddLog(LOGE, FL("attr channel failed"));
4528 return -EINVAL;
4529 }
4530 pReqMsg->buckets[bktIndex].channels[j].channel =
4531 nla_get_u32(channel[
4532 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
4533 hddLog(LOG1, FL("channel %u"),
4534 pReqMsg->buckets[bktIndex].channels[j].channel);
4535
4536 /* Parse and fetch dwell time */
4537 if (!channel[
4538 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
4539 hddLog(LOGE, FL("attr dwelltime failed"));
4540 return -EINVAL;
4541 }
4542 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
4543 nla_get_u32(channel[
4544 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
4545
4546 hddLog(LOG1, FL("Dwell time (%u ms)"),
4547 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4548
4549
4550 /* Parse and fetch channel spec passive */
4551 if (!channel[
4552 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
4553 hddLog(LOGE,
4554 FL("attr channel spec passive failed"));
4555 return -EINVAL;
4556 }
4557 pReqMsg->buckets[bktIndex].channels[j].passive =
4558 nla_get_u8(channel[
4559 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
4560 hddLog(LOG1, FL("Chnl spec passive %u"),
4561 pReqMsg->buckets[bktIndex].channels[j].passive);
4562
4563 j++;
4564 }
4565
4566 bktIndex++;
4567 }
4568
4569 return 0;
4570}
4571
4572
4573/*
4574 * define short names for the global vendor params
4575 * used by wlan_hdd_cfg80211_extscan_start()
4576 */
4577#define PARAM_MAX \
4578QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
4579#define PARAM_REQUEST_ID \
4580QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
4581#define PARAM_BASE_PERIOD \
4582QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
4583#define PARAM_MAX_AP_PER_SCAN \
4584QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
4585#define PARAM_RPT_THRHLD_PERCENT \
4586QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
4587#define PARAM_RPT_THRHLD_NUM_SCANS \
4588QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
4589#define PARAM_NUM_BUCKETS \
4590QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
4591
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304592static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304593 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304594 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304595{
Dino Myclee8843b32014-07-04 14:21:45 +05304596 tpSirEXTScanStartReqParams pReqMsg = NULL;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304597 struct net_device *dev = wdev->netdev;
4598 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4599 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4600 struct nlattr *tb[PARAM_MAX + 1];
4601 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304602 eHalStatus status;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304603 tANI_U32 request_id;
4604 struct hdd_ext_scan_context *context;
4605 unsigned long rc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304606
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304607 ENTER();
4608
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304609 if (VOS_FTM_MODE == hdd_get_conparam()) {
4610 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4611 return -EINVAL;
4612 }
4613
Dino Mycle6fb96c12014-06-10 11:52:40 +05304614 status = wlan_hdd_validate_context(pHddCtx);
4615 if (0 != status)
4616 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304617 return -EINVAL;
4618 }
Dino Myclee8843b32014-07-04 14:21:45 +05304619 /* check the EXTScan Capability */
4620 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304621 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4622 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304623 {
4624 hddLog(VOS_TRACE_LEVEL_ERROR,
4625 FL("EXTScan not enabled/supported by Firmware"));
4626 return -EINVAL;
4627 }
4628
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304629 if (nla_parse(tb, PARAM_MAX,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304630 data, dataLen,
4631 wlan_hdd_extscan_config_policy)) {
4632 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4633 return -EINVAL;
4634 }
4635
4636 /* Parse and fetch request Id */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304637 if (!tb[PARAM_REQUEST_ID]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304638 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4639 return -EINVAL;
4640 }
4641
Dino Myclee8843b32014-07-04 14:21:45 +05304642 pReqMsg = (tpSirEXTScanStartReqParams)
4643 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304644 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05304645 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4646 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304647 }
4648
4649 pReqMsg->requestId = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304650 tb[PARAM_REQUEST_ID]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304651 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4652
4653 pReqMsg->sessionId = pAdapter->sessionId;
4654 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4655
4656 /* Parse and fetch base period */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304657 if (!tb[PARAM_BASE_PERIOD]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304658 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
4659 goto fail;
4660 }
4661 pReqMsg->basePeriod = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304662 tb[PARAM_BASE_PERIOD]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304663 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
4664 pReqMsg->basePeriod);
4665
4666 /* Parse and fetch max AP per scan */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304667 if (!tb[PARAM_MAX_AP_PER_SCAN]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304668 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
4669 goto fail;
4670 }
4671 pReqMsg->maxAPperScan = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304672 tb[PARAM_MAX_AP_PER_SCAN]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304673 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
4674 pReqMsg->maxAPperScan);
4675
4676 /* Parse and fetch report threshold */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304677 if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304678 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
4679 goto fail;
4680 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304681 pReqMsg->reportThresholdPercent = nla_get_u8(
4682 tb[PARAM_RPT_THRHLD_PERCENT]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304683 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304684 pReqMsg->reportThresholdPercent);
4685
4686 /* Parse and fetch report threshold num scans */
4687 if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
4688 hddLog(LOGE, FL("attr report_threshold num scans failed"));
4689 goto fail;
4690 }
4691 pReqMsg->reportThresholdNumScans = nla_get_u8(
4692 tb[PARAM_RPT_THRHLD_NUM_SCANS]);
4693 hddLog(LOG1, FL("Report Threshold num scans %d"),
4694 pReqMsg->reportThresholdNumScans);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304695
4696 /* Parse and fetch number of buckets */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304697 if (!tb[PARAM_NUM_BUCKETS]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304698 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
4699 goto fail;
4700 }
4701 pReqMsg->numBuckets = nla_get_u8(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304702 tb[PARAM_NUM_BUCKETS]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304703 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
4704 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
4705 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
4706 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
4707 }
4708 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
4709 pReqMsg->numBuckets);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304710
Dino Mycle6fb96c12014-06-10 11:52:40 +05304711 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
4712 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
4713 goto fail;
4714 }
4715
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304716 pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304717
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304718 if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
4719 goto fail;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304720
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304721 context = &pHddCtx->ext_scan_context;
4722 spin_lock(&hdd_context_lock);
4723 INIT_COMPLETION(context->response_event);
4724 context->request_id = request_id = pReqMsg->requestId;
4725 spin_unlock(&hdd_context_lock);
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304726
Dino Mycle6fb96c12014-06-10 11:52:40 +05304727 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
4728 if (!HAL_STATUS_SUCCESS(status)) {
4729 hddLog(VOS_TRACE_LEVEL_ERROR,
4730 FL("sme_EXTScanStart failed(err=%d)"), status);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304731 goto fail;
4732 }
4733
Srinivas Dasari91727c12016-03-23 17:59:06 +05304734 pHddCtx->extscan_start_time_since_boot = vos_get_monotonic_boottime();
4735
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304736 /* request was sent -- wait for the response */
4737 rc = wait_for_completion_timeout(&context->response_event,
4738 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4739
4740 if (!rc) {
4741 hddLog(LOGE, FL("sme_ExtScanStart timed out"));
4742 retval = -ETIMEDOUT;
4743 } else {
4744 spin_lock(&hdd_context_lock);
4745 if (context->request_id == request_id)
4746 retval = context->response_status;
4747 else
4748 retval = -EINVAL;
4749 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304750 }
4751
Dino Myclee8843b32014-07-04 14:21:45 +05304752 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304753 EXIT();
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304754 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304755
4756fail:
4757 vos_mem_free(pReqMsg);
4758 return -EINVAL;
4759}
4760
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304761/*
4762 * done with short names for the global vendor params
4763 * used by wlan_hdd_cfg80211_extscan_start()
4764 */
4765#undef PARAM_MAX
4766#undef PARAM_REQUEST_ID
4767#undef PARAM_BASE_PERIOD
4768#undef PARAMS_MAX_AP_PER_SCAN
4769#undef PARAMS_RPT_THRHLD_PERCENT
4770#undef PARAMS_RPT_THRHLD_NUM_SCANS
4771#undef PARAMS_NUM_BUCKETS
4772
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304773static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
4774 struct wireless_dev *wdev,
4775 const void *data, int dataLen)
4776{
4777 int ret = 0;
4778
4779 vos_ssr_protect(__func__);
4780 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
4781 vos_ssr_unprotect(__func__);
4782
4783 return ret;
4784}
4785
4786static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304787 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304788 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304789{
Dino Myclee8843b32014-07-04 14:21:45 +05304790 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304791 struct net_device *dev = wdev->netdev;
4792 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4793 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4794 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4795 eHalStatus status;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304796 int retval;
4797 unsigned long rc;
4798 struct hdd_ext_scan_context *context;
4799 tANI_U32 request_id;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304800
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304801 ENTER();
4802
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304803 if (VOS_FTM_MODE == hdd_get_conparam()) {
4804 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4805 return -EINVAL;
4806 }
4807
Dino Mycle6fb96c12014-06-10 11:52:40 +05304808 status = wlan_hdd_validate_context(pHddCtx);
4809 if (0 != status)
4810 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304811 return -EINVAL;
4812 }
Dino Myclee8843b32014-07-04 14:21:45 +05304813 /* check the EXTScan Capability */
4814 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304815 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4816 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304817 {
4818 hddLog(VOS_TRACE_LEVEL_ERROR,
4819 FL("EXTScan not enabled/supported by Firmware"));
4820 return -EINVAL;
4821 }
4822
Dino Mycle6fb96c12014-06-10 11:52:40 +05304823 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4824 data, dataLen,
4825 wlan_hdd_extscan_config_policy)) {
4826 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4827 return -EINVAL;
4828 }
4829
4830 /* Parse and fetch request Id */
4831 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4832 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4833 return -EINVAL;
4834 }
4835
Dino Myclee8843b32014-07-04 14:21:45 +05304836 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304837 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304838 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304839
Dino Myclee8843b32014-07-04 14:21:45 +05304840 reqMsg.sessionId = pAdapter->sessionId;
4841 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304842
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304843 context = &pHddCtx->ext_scan_context;
4844 spin_lock(&hdd_context_lock);
4845 INIT_COMPLETION(context->response_event);
Sravanti Palakonda7539fb92016-02-26 17:49:21 +05304846 context->request_id = request_id = reqMsg.requestId;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304847 spin_unlock(&hdd_context_lock);
4848
Dino Myclee8843b32014-07-04 14:21:45 +05304849 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304850 if (!HAL_STATUS_SUCCESS(status)) {
4851 hddLog(VOS_TRACE_LEVEL_ERROR,
4852 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304853 return -EINVAL;
4854 }
4855
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304856 /* request was sent -- wait for the response */
4857 rc = wait_for_completion_timeout(&context->response_event,
4858 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4859
4860 if (!rc) {
4861 hddLog(LOGE, FL("sme_ExtScanStop timed out"));
4862 retval = -ETIMEDOUT;
4863 } else {
4864 spin_lock(&hdd_context_lock);
4865 if (context->request_id == request_id)
4866 retval = context->response_status;
4867 else
4868 retval = -EINVAL;
4869 spin_unlock(&hdd_context_lock);
4870 }
4871
4872 return retval;
4873
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304874 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304875 return 0;
4876}
4877
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304878static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
4879 struct wireless_dev *wdev,
4880 const void *data, int dataLen)
4881{
4882 int ret = 0;
4883
4884 vos_ssr_protect(__func__);
4885 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
4886 vos_ssr_unprotect(__func__);
4887
4888 return ret;
4889}
4890
4891static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304892 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304893 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304894{
Dino Myclee8843b32014-07-04 14:21:45 +05304895 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304896 struct net_device *dev = wdev->netdev;
4897 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4898 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4899 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4900 eHalStatus status;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304901 struct hdd_ext_scan_context *context;
4902 tANI_U32 request_id;
4903 unsigned long rc;
4904 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304905
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304906 ENTER();
4907
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304908 if (VOS_FTM_MODE == hdd_get_conparam()) {
4909 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4910 return -EINVAL;
4911 }
4912
Dino Mycle6fb96c12014-06-10 11:52:40 +05304913 status = wlan_hdd_validate_context(pHddCtx);
4914 if (0 != status)
4915 {
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304916 hddLog(LOGE, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304917 return -EINVAL;
4918 }
Dino Myclee8843b32014-07-04 14:21:45 +05304919 /* check the EXTScan Capability */
4920 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304921 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4922 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304923 {
4924 hddLog(VOS_TRACE_LEVEL_ERROR,
4925 FL("EXTScan not enabled/supported by Firmware"));
4926 return -EINVAL;
4927 }
4928
Dino Mycle6fb96c12014-06-10 11:52:40 +05304929 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4930 data, dataLen,
4931 wlan_hdd_extscan_config_policy)) {
4932 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4933 return -EINVAL;
4934 }
4935
4936 /* Parse and fetch request Id */
4937 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4938 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4939 return -EINVAL;
4940 }
4941
Dino Myclee8843b32014-07-04 14:21:45 +05304942 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304943 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304944 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304945
Dino Myclee8843b32014-07-04 14:21:45 +05304946 reqMsg.sessionId = pAdapter->sessionId;
4947 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304948
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304949 context = &pHddCtx->ext_scan_context;
4950 spin_lock(&hdd_context_lock);
4951 INIT_COMPLETION(context->response_event);
4952 context->request_id = request_id = reqMsg.requestId;
4953 spin_unlock(&hdd_context_lock);
4954
Dino Myclee8843b32014-07-04 14:21:45 +05304955 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304956 if (!HAL_STATUS_SUCCESS(status)) {
4957 hddLog(VOS_TRACE_LEVEL_ERROR,
4958 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304959 return -EINVAL;
4960 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304961
4962 /* request was sent -- wait for the response */
4963 rc = wait_for_completion_timeout(&context->response_event,
4964 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4965 if (!rc) {
4966 hddLog(LOGE, FL("sme_ResetBssHotlist timed out"));
4967 retval = -ETIMEDOUT;
4968 } else {
4969 spin_lock(&hdd_context_lock);
4970 if (context->request_id == request_id)
4971 retval = context->response_status;
4972 else
4973 retval = -EINVAL;
4974 spin_unlock(&hdd_context_lock);
4975 }
4976
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304977 EXIT();
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304978 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304979}
4980
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304981static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
4982 struct wireless_dev *wdev,
4983 const void *data, int dataLen)
4984{
4985 int ret = 0;
4986
4987 vos_ssr_protect(__func__);
4988 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
4989 vos_ssr_unprotect(__func__);
4990
4991 return ret;
4992}
Dino Mycle6fb96c12014-06-10 11:52:40 +05304993#endif /* WLAN_FEATURE_EXTSCAN */
4994
Atul Mittal115287b2014-07-08 13:26:33 +05304995/*EXT TDLS*/
4996static const struct nla_policy
4997wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
4998{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05304999 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {
5000 .type = NLA_UNSPEC,
5001 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305002 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
5003 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
5004 {.type = NLA_S32 },
5005 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
5006 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
5007
5008};
5009
5010static const struct nla_policy
5011wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
5012{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305013 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {
5014 .type = NLA_UNSPEC,
5015 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305016
5017};
5018
5019static const struct nla_policy
5020wlan_hdd_tdls_config_state_change_policy[
5021 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
5022{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305023 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {
5024 .type = NLA_UNSPEC,
5025 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305026 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
5027 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305028 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
5029 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
5030 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305031
5032};
5033
5034static const struct nla_policy
5035wlan_hdd_tdls_config_get_status_policy[
5036 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
5037{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305038 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {
5039 .type = NLA_UNSPEC,
5040 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305041 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
5042 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305043 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
5044 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
5045 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305046
5047};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305048
5049static const struct nla_policy
5050wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
5051{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305052 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {
5053 .type = NLA_UNSPEC,
5054 .len = VOS_MAC_ADDR_FIRST_3_BYTES},
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305055};
5056
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305057static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305058 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305059 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305060 int data_len)
5061{
5062
5063 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5064 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
5065
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305066 ENTER();
5067
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305068 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305069 return -EINVAL;
5070 }
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +05305071 if (0 == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05305072 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305073 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05305074 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305075 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05305076 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305077 return -ENOTSUPP;
5078 }
5079
5080 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
5081 data, data_len, wlan_hdd_mac_config)) {
5082 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5083 return -EINVAL;
5084 }
5085
5086 /* Parse and fetch mac address */
5087 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
5088 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5089 return -EINVAL;
5090 }
5091
5092 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
5093 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5094 VOS_MAC_ADDR_LAST_3_BYTES);
5095
Siddharth Bhal76972212014-10-15 16:22:51 +05305096 pHddCtx->spoofMacAddr.isEnabled = TRUE;
5097
5098 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305099 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5100 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05305101 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
5102 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
5103 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
5104 {
5105 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
5106 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
5107 VOS_MAC_ADDRESS_LEN);
5108 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305109 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305110
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +05305111 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
5112 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305113
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305114 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305115 return 0;
5116}
5117
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305118static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
5119 struct wireless_dev *wdev,
5120 const void *data,
5121 int data_len)
5122{
5123 int ret = 0;
5124
5125 vos_ssr_protect(__func__);
5126 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
5127 vos_ssr_unprotect(__func__);
5128
5129 return ret;
5130}
5131
5132static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305133 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305134 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305135 int data_len)
5136{
5137 u8 peer[6] = {0};
5138 struct net_device *dev = wdev->netdev;
5139 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5140 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5141 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
5142 eHalStatus ret;
5143 tANI_S32 state;
5144 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305145 tANI_S32 global_operating_class = 0;
5146 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05305147 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305148 int retVal;
5149
5150 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305151
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305152 if (!pAdapter) {
5153 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5154 return -EINVAL;
5155 }
5156
Atul Mittal115287b2014-07-08 13:26:33 +05305157 ret = wlan_hdd_validate_context(pHddCtx);
5158 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305159 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305160 return -EINVAL;
5161 }
5162 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305163 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305164 return -ENOTSUPP;
5165 }
5166 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
5167 data, data_len,
5168 wlan_hdd_tdls_config_get_status_policy)) {
5169 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5170 return -EINVAL;
5171 }
5172
5173 /* Parse and fetch mac address */
5174 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
5175 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5176 return -EINVAL;
5177 }
5178
5179 memcpy(peer, nla_data(
5180 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
5181 sizeof(peer));
5182 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5183
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05305184 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05305185
Atul Mittal115287b2014-07-08 13:26:33 +05305186 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305187 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05305188 NLMSG_HDRLEN);
5189
5190 if (!skb) {
5191 hddLog(VOS_TRACE_LEVEL_ERROR,
5192 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5193 return -EINVAL;
5194 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305195 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reason (%d) Status (%d) class (%d) channel (%d) peer" MAC_ADDRESS_STR),
Atul Mittal115287b2014-07-08 13:26:33 +05305196 reason,
5197 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305198 global_operating_class,
5199 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05305200 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305201 if (nla_put_s32(skb,
5202 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
5203 state) ||
5204 nla_put_s32(skb,
5205 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
5206 reason) ||
5207 nla_put_s32(skb,
5208 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
5209 global_operating_class) ||
5210 nla_put_s32(skb,
5211 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
5212 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05305213
5214 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5215 goto nla_put_failure;
5216 }
5217
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305218 retVal = cfg80211_vendor_cmd_reply(skb);
5219 EXIT();
5220 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05305221
5222nla_put_failure:
5223 kfree_skb(skb);
5224 return -EINVAL;
5225}
5226
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305227static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
5228 struct wireless_dev *wdev,
5229 const void *data,
5230 int data_len)
5231{
5232 int ret = 0;
5233
5234 vos_ssr_protect(__func__);
5235 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
5236 vos_ssr_unprotect(__func__);
5237
5238 return ret;
5239}
5240
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05305241static int wlan_hdd_cfg80211_exttdls_callback(
5242#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
5243 const tANI_U8* mac,
5244#else
5245 tANI_U8* mac,
5246#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305247 tANI_S32 state,
5248 tANI_S32 reason,
5249 void *ctx)
5250{
5251 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05305252 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305253 tANI_S32 global_operating_class = 0;
5254 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305255 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05305256
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305257 ENTER();
5258
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305259 if (!pAdapter) {
5260 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5261 return -EINVAL;
5262 }
5263
5264 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05305265 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305266 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305267 return -EINVAL;
5268 }
5269
5270 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305271 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305272 return -ENOTSUPP;
5273 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05305274 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
5275#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
5276 NULL,
5277#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305278 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
5279 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
5280 GFP_KERNEL);
5281
5282 if (!skb) {
5283 hddLog(VOS_TRACE_LEVEL_ERROR,
5284 FL("cfg80211_vendor_event_alloc failed"));
5285 return -EINVAL;
5286 }
5287 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305288 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
5289 reason,
5290 state,
5291 global_operating_class,
5292 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05305293 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
5294 MAC_ADDR_ARRAY(mac));
5295
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305296 if (nla_put(skb,
5297 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
5298 VOS_MAC_ADDR_SIZE, mac) ||
5299 nla_put_s32(skb,
5300 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
5301 state) ||
5302 nla_put_s32(skb,
5303 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
5304 reason) ||
5305 nla_put_s32(skb,
5306 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
5307 channel) ||
5308 nla_put_s32(skb,
5309 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
5310 global_operating_class)
5311 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05305312 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5313 goto nla_put_failure;
5314 }
5315
5316 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305317 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05305318 return (0);
5319
5320nla_put_failure:
5321 kfree_skb(skb);
5322 return -EINVAL;
5323}
5324
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305325static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305326 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305327 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305328 int data_len)
5329{
5330 u8 peer[6] = {0};
5331 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305332 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5333 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
5334 eHalStatus status;
5335 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305336 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305337 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305338
5339 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305340
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305341 if (!dev) {
5342 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5343 return -EINVAL;
5344 }
5345
5346 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5347 if (!pAdapter) {
5348 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5349 return -EINVAL;
5350 }
5351
Atul Mittal115287b2014-07-08 13:26:33 +05305352 status = wlan_hdd_validate_context(pHddCtx);
5353 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305354 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305355 return -EINVAL;
5356 }
5357 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305358 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305359 return -ENOTSUPP;
5360 }
5361 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
5362 data, data_len,
5363 wlan_hdd_tdls_config_enable_policy)) {
5364 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5365 return -EINVAL;
5366 }
5367
5368 /* Parse and fetch mac address */
5369 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
5370 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5371 return -EINVAL;
5372 }
5373
5374 memcpy(peer, nla_data(
5375 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
5376 sizeof(peer));
5377 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5378
5379 /* Parse and fetch channel */
5380 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
5381 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
5382 return -EINVAL;
5383 }
5384 pReqMsg.channel = nla_get_s32(
5385 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
5386 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
5387
5388 /* Parse and fetch global operating class */
5389 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
5390 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
5391 return -EINVAL;
5392 }
5393 pReqMsg.global_operating_class = nla_get_s32(
5394 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
5395 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
5396 pReqMsg.global_operating_class);
5397
5398 /* Parse and fetch latency ms */
5399 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
5400 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
5401 return -EINVAL;
5402 }
5403 pReqMsg.max_latency_ms = nla_get_s32(
5404 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
5405 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
5406 pReqMsg.max_latency_ms);
5407
5408 /* Parse and fetch required bandwidth kbps */
5409 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
5410 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
5411 return -EINVAL;
5412 }
5413
5414 pReqMsg.min_bandwidth_kbps = nla_get_s32(
5415 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
5416 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
5417 pReqMsg.min_bandwidth_kbps);
5418
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305419 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05305420 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05305421 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305422 wlan_hdd_cfg80211_exttdls_callback);
5423
5424 EXIT();
5425 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305426}
5427
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305428static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
5429 struct wireless_dev *wdev,
5430 const void *data,
5431 int data_len)
5432{
5433 int ret = 0;
5434
5435 vos_ssr_protect(__func__);
5436 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
5437 vos_ssr_unprotect(__func__);
5438
5439 return ret;
5440}
5441
5442static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305443 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305444 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305445 int data_len)
5446{
5447 u8 peer[6] = {0};
5448 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305449 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5450 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
5451 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305452 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305453 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305454
5455 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305456
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305457 if (!dev) {
5458 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5459 return -EINVAL;
5460 }
5461
5462 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5463 if (!pAdapter) {
5464 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
5465 return -EINVAL;
5466 }
5467
Atul Mittal115287b2014-07-08 13:26:33 +05305468 status = wlan_hdd_validate_context(pHddCtx);
5469 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305470 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305471 return -EINVAL;
5472 }
5473 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305474 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305475 return -ENOTSUPP;
5476 }
5477 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
5478 data, data_len,
5479 wlan_hdd_tdls_config_disable_policy)) {
5480 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5481 return -EINVAL;
5482 }
5483 /* Parse and fetch mac address */
5484 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
5485 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5486 return -EINVAL;
5487 }
5488
5489 memcpy(peer, nla_data(
5490 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
5491 sizeof(peer));
5492 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5493
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305494 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
5495
5496 EXIT();
5497 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305498}
5499
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305500static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
5501 struct wireless_dev *wdev,
5502 const void *data,
5503 int data_len)
5504{
5505 int ret = 0;
5506
5507 vos_ssr_protect(__func__);
5508 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
5509 vos_ssr_unprotect(__func__);
5510
5511 return ret;
5512}
5513
Dasari Srinivas7875a302014-09-26 17:50:57 +05305514static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305515__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05305516 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305517 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05305518{
5519 struct net_device *dev = wdev->netdev;
5520 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5521 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5522 struct sk_buff *skb = NULL;
5523 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305524 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305525
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305526 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305527
5528 ret = wlan_hdd_validate_context(pHddCtx);
5529 if (0 != ret)
5530 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305531 return ret;
5532 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305533 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
5534 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
5535 fset |= WIFI_FEATURE_INFRA;
5536 }
5537
5538 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
5539 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
5540 fset |= WIFI_FEATURE_INFRA_5G;
5541 }
5542
5543#ifdef WLAN_FEATURE_P2P
5544 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
5545 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
5546 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
5547 fset |= WIFI_FEATURE_P2P;
5548 }
5549#endif
5550
5551 /* Soft-AP is supported currently by default */
5552 fset |= WIFI_FEATURE_SOFT_AP;
5553
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05305554 /* HOTSPOT is a supplicant feature, enable it by default */
5555 fset |= WIFI_FEATURE_HOTSPOT;
5556
Dasari Srinivas7875a302014-09-26 17:50:57 +05305557#ifdef WLAN_FEATURE_EXTSCAN
5558 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305559 sme_IsFeatureSupportedByFW(EXTENDED_SCAN) &&
5560 sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)) {
5561 hddLog(LOG1, FL("Enhanced EXTScan is supported by firmware"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05305562 fset |= WIFI_FEATURE_EXTSCAN;
5563 }
5564#endif
5565
Dasari Srinivas7875a302014-09-26 17:50:57 +05305566 if (sme_IsFeatureSupportedByFW(NAN)) {
5567 hddLog(LOG1, FL("NAN is supported by firmware"));
5568 fset |= WIFI_FEATURE_NAN;
5569 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305570
5571 /* D2D RTT is not supported currently by default */
Sourav Mohapatradf8b23c2017-11-17 17:50:31 +05305572 if (sme_IsFeatureSupportedByFW(RTT) &&
5573 pHddCtx->cfg_ini->enable_rtt_support) {
5574 hddLog(LOG1, FL("RTT is supported by firmware and framework"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05305575 fset |= WIFI_FEATURE_D2AP_RTT;
5576 }
5577
Padma, Santhosh Kumaraac4c4d2015-12-08 16:07:47 +05305578 if (sme_IsFeatureSupportedByFW(RTT3)) {
5579 hddLog(LOG1, FL("RTT3 is supported by firmware"));
5580 fset |= WIFI_FEATURE_RTT3;
5581 }
5582
Dasari Srinivas7875a302014-09-26 17:50:57 +05305583#ifdef FEATURE_WLAN_BATCH_SCAN
5584 if (fset & WIFI_FEATURE_EXTSCAN) {
5585 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
5586 fset &= ~WIFI_FEATURE_BATCH_SCAN;
5587 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
5588 hddLog(LOG1, FL("Batch scan is supported by firmware"));
5589 fset |= WIFI_FEATURE_BATCH_SCAN;
5590 }
5591#endif
5592
5593#ifdef FEATURE_WLAN_SCAN_PNO
5594 if (pHddCtx->cfg_ini->configPNOScanSupport &&
5595 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
5596 hddLog(LOG1, FL("PNO is supported by firmware"));
5597 fset |= WIFI_FEATURE_PNO;
5598 }
5599#endif
5600
5601 /* STA+STA is supported currently by default */
5602 fset |= WIFI_FEATURE_ADDITIONAL_STA;
5603
5604#ifdef FEATURE_WLAN_TDLS
5605 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
5606 sme_IsFeatureSupportedByFW(TDLS)) {
5607 hddLog(LOG1, FL("TDLS is supported by firmware"));
5608 fset |= WIFI_FEATURE_TDLS;
5609 }
5610
5611 /* TDLS_OFFCHANNEL is not supported currently by default */
5612#endif
5613
5614#ifdef WLAN_AP_STA_CONCURRENCY
5615 /* AP+STA concurrency is supported currently by default */
5616 fset |= WIFI_FEATURE_AP_STA;
5617#endif
5618
Mukul Sharma5add0532015-08-17 15:57:47 +05305619#ifdef WLAN_FEATURE_LINK_LAYER_STATS
Ajit Vaishya8353cfb2017-11-10 16:22:36 +05305620 if ((TRUE == pHddCtx->cfg_ini->fEnableLLStats) &&
5621 (TRUE == sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS))) {
Mukul Sharma5add0532015-08-17 15:57:47 +05305622 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
5623 hddLog(LOG1, FL("Link layer stats is supported by driver"));
Ajit Vaishya8353cfb2017-11-10 16:22:36 +05305624 }
Mukul Sharma5add0532015-08-17 15:57:47 +05305625#endif
5626
Dasari Srinivas7875a302014-09-26 17:50:57 +05305627 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
5628 NLMSG_HDRLEN);
5629
5630 if (!skb) {
5631 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5632 return -EINVAL;
5633 }
5634 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
5635
5636 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
5637 hddLog(LOGE, FL("nla put fail"));
5638 goto nla_put_failure;
5639 }
5640
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305641 ret = cfg80211_vendor_cmd_reply(skb);
5642 EXIT();
5643 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305644
5645nla_put_failure:
5646 kfree_skb(skb);
5647 return -EINVAL;
5648}
5649
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305650static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305651wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
5652 struct wireless_dev *wdev,
5653 const void *data, int data_len)
5654{
5655 int ret = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305656 vos_ssr_protect(__func__);
5657 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
5658 vos_ssr_unprotect(__func__);
5659
5660 return ret;
5661}
5662
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305663
5664static const struct
5665nla_policy
5666qca_wlan_vendor_wifi_logger_get_ring_data_policy
5667[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1] = {
5668 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]
5669 = {.type = NLA_U32 },
5670};
5671
5672static int
5673 __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
5674 struct wireless_dev *wdev,
5675 const void *data,
5676 int data_len)
5677{
5678 int ret;
5679 VOS_STATUS status;
5680 uint32_t ring_id;
5681 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5682 struct nlattr *tb
5683 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1];
5684
5685 ENTER();
5686
5687 ret = wlan_hdd_validate_context(hdd_ctx);
5688 if (0 != ret) {
5689 return ret;
5690 }
5691
5692 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX,
5693 data, data_len,
5694 qca_wlan_vendor_wifi_logger_get_ring_data_policy)) {
5695 hddLog(LOGE, FL("Invalid attribute"));
5696 return -EINVAL;
5697 }
5698
5699 /* Parse and fetch ring id */
5700 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]) {
5701 hddLog(LOGE, FL("attr ATTR failed"));
5702 return -EINVAL;
5703 }
5704
5705 ring_id = nla_get_u32(
5706 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]);
5707
5708 hddLog(LOG1, FL("Bug report triggered by framework"));
5709
5710 status = vos_fatal_event_logs_req(WLAN_LOG_TYPE_NON_FATAL,
5711 WLAN_LOG_INDICATOR_FRAMEWORK,
5712 WLAN_LOG_REASON_CODE_FRAMEWORK,
Abhishek Singh837adf22015-10-01 17:37:37 +05305713 TRUE, TRUE
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305714 );
5715 if (VOS_STATUS_SUCCESS != status) {
5716 hddLog(LOGE, FL("Failed to trigger bug report"));
5717
5718 return -EINVAL;
5719 }
5720
5721 return 0;
5722
5723
5724}
5725
5726
5727static int
5728 wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
5729 struct wireless_dev *wdev,
5730 const void *data,
5731 int data_len)
5732{
5733 int ret = 0;
5734
5735 vos_ssr_protect(__func__);
5736 ret = __wlan_hdd_cfg80211_wifi_logger_get_ring_data(wiphy,
5737 wdev, data, data_len);
5738 vos_ssr_unprotect(__func__);
5739
5740 return ret;
5741
5742}
5743
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05305744#define MAX_CONCURRENT_MATRIX \
5745 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX
5746#define MATRIX_CONFIG_PARAM_SET_SIZE_MAX \
5747 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX
5748static const struct nla_policy
5749wlan_hdd_get_concurrency_matrix_policy[MAX_CONCURRENT_MATRIX + 1] = {
5750 [MATRIX_CONFIG_PARAM_SET_SIZE_MAX] = {.type = NLA_U32},
5751};
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305752
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305753static int
5754__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305755 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305756 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305757{
5758 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
5759 uint8_t i, feature_sets, max_feature_sets;
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05305760 struct nlattr *tb[MAX_CONCURRENT_MATRIX + 1];
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305761 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305762 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5763 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305764
5765 ENTER();
5766
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305767 ret = wlan_hdd_validate_context(pHddCtx);
5768 if (0 != ret)
5769 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305770 return ret;
5771 }
5772
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05305773 if (nla_parse(tb, MAX_CONCURRENT_MATRIX, data, data_len,
5774 wlan_hdd_get_concurrency_matrix_policy)) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305775 hddLog(LOGE, FL("Invalid ATTR"));
5776 return -EINVAL;
5777 }
5778
5779 /* Parse and fetch max feature set */
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05305780 if (!tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305781 hddLog(LOGE, FL("Attr max feature set size failed"));
5782 return -EINVAL;
5783 }
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05305784 max_feature_sets = nla_get_u32(tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305785 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
5786
5787 /* Fill feature combination matrix */
5788 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305789 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5790 WIFI_FEATURE_P2P;
5791
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305792 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5793 WIFI_FEATURE_SOFT_AP;
5794
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305795 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
5796 WIFI_FEATURE_SOFT_AP;
5797
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305798 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5799 WIFI_FEATURE_SOFT_AP |
5800 WIFI_FEATURE_P2P;
5801
5802 /* Add more feature combinations here */
5803
5804 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
5805 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
5806 hddLog(LOG1, "Feature set matrix");
5807 for (i = 0; i < feature_sets; i++)
5808 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
5809
5810 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
5811 sizeof(u32) * feature_sets +
5812 NLMSG_HDRLEN);
5813
5814 if (reply_skb) {
5815 if (nla_put_u32(reply_skb,
5816 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
5817 feature_sets) ||
5818 nla_put(reply_skb,
5819 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
5820 sizeof(u32) * feature_sets, feature_set_matrix)) {
5821 hddLog(LOGE, FL("nla put fail"));
5822 kfree_skb(reply_skb);
5823 return -EINVAL;
5824 }
5825
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305826 ret = cfg80211_vendor_cmd_reply(reply_skb);
5827 EXIT();
5828 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305829 }
5830 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
5831 return -ENOMEM;
5832
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305833}
5834
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05305835#undef MAX_CONCURRENT_MATRIX
5836#undef MATRIX_CONFIG_PARAM_SET_SIZE_MAX
5837
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305838static int
5839wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
5840 struct wireless_dev *wdev,
5841 const void *data, int data_len)
5842{
5843 int ret = 0;
5844
5845 vos_ssr_protect(__func__);
5846 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
5847 data_len);
5848 vos_ssr_unprotect(__func__);
5849
5850 return ret;
5851}
5852
c_manjeecfd1efb2015-09-25 19:32:34 +05305853
5854static int
5855__wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5856 struct wireless_dev *wdev,
5857 const void *data, int data_len)
5858{
5859 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5860 int ret;
5861 ENTER();
5862
5863 ret = wlan_hdd_validate_context(pHddCtx);
5864 if (0 != ret)
5865 {
5866 return ret;
5867 }
5868
5869 if( !pHddCtx->cfg_ini->enableFwrMemDump ||
5870 (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
5871 {
5872 hddLog(VOS_TRACE_LEVEL_INFO, FL("FW dump Logging not supported"));
Ajit Vaishyac5ba8482017-11-16 14:10:37 +05305873 return -EOPNOTSUPP;
c_manjeecfd1efb2015-09-25 19:32:34 +05305874 }
5875 /*call common API for FW mem dump req*/
5876 ret = wlan_hdd_fw_mem_dump_req(pHddCtx);
5877
Abhishek Singhc783fa72015-12-09 18:07:34 +05305878 if (!ret)
c_manjee04b4c5c2015-10-13 18:35:01 +05305879 {
5880 /*indicate to userspace the status of fw mem dump */
5881 wlan_indicate_mem_dump_complete(true);
5882 }
5883 else
5884 {
5885 /*else send failure to userspace */
5886 wlan_indicate_mem_dump_complete(false);
5887 }
c_manjeecfd1efb2015-09-25 19:32:34 +05305888 EXIT();
5889 return ret;
5890}
5891
5892/**
5893 * wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump
5894 * @wiphy: pointer to wireless wiphy structure.
5895 * @wdev: pointer to wireless_dev structure.
5896 * @data: Pointer to the NL data.
5897 * @data_len:Length of @data
5898 *
5899 * This is called when wlan driver needs to get the firmware memory dump
5900 * via vendor specific command.
5901 *
5902 * Return: 0 on success, error number otherwise.
5903 */
5904
5905static int
5906wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5907 struct wireless_dev *wdev,
5908 const void *data, int data_len)
Sushant Kaushik8e644982015-09-23 12:18:54 +05305909{
5910 int ret = 0;
5911 vos_ssr_protect(__func__);
5912 ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data,
5913 data_len);
5914 vos_ssr_unprotect(__func__);
5915 return ret;
5916}
c_manjeecfd1efb2015-09-25 19:32:34 +05305917
Sushant Kaushik8e644982015-09-23 12:18:54 +05305918static const struct
5919nla_policy
5920qca_wlan_vendor_wifi_logger_start_policy
5921[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
5922 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
5923 = {.type = NLA_U32 },
5924 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
5925 = {.type = NLA_U32 },
5926 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
5927 = {.type = NLA_U32 },
5928};
5929
5930/**
5931 * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
5932 * or disable the collection of packet statistics from the firmware
5933 * @wiphy: WIPHY structure pointer
5934 * @wdev: Wireless device structure pointer
5935 * @data: Pointer to the data received
5936 * @data_len: Length of the data received
5937 *
5938 * This function is used to enable or disable the collection of packet
5939 * statistics from the firmware
5940 *
5941 * Return: 0 on success and errno on failure
5942 */
5943static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
5944 struct wireless_dev *wdev,
5945 const void *data,
5946 int data_len)
5947{
5948 eHalStatus status;
5949 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5950 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
5951 tAniWifiStartLog start_log;
5952
5953 status = wlan_hdd_validate_context(hdd_ctx);
5954 if (0 != status) {
5955 return -EINVAL;
5956 }
5957
5958 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
5959 data, data_len,
5960 qca_wlan_vendor_wifi_logger_start_policy)) {
5961 hddLog(LOGE, FL("Invalid attribute"));
5962 return -EINVAL;
5963 }
5964
5965 /* Parse and fetch ring id */
5966 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
5967 hddLog(LOGE, FL("attr ATTR failed"));
5968 return -EINVAL;
5969 }
5970 start_log.ringId = nla_get_u32(
5971 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
5972 hddLog(LOG1, FL("Ring ID=%d"), start_log.ringId);
5973
5974 /* Parse and fetch verbose level */
5975 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
5976 hddLog(LOGE, FL("attr verbose_level failed"));
5977 return -EINVAL;
5978 }
5979 start_log.verboseLevel = nla_get_u32(
5980 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
5981 hddLog(LOG1, FL("verbose_level=%d"), start_log.verboseLevel);
5982
5983 /* Parse and fetch flag */
5984 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
5985 hddLog(LOGE, FL("attr flag failed"));
5986 return -EINVAL;
5987 }
5988 start_log.flag = nla_get_u32(
5989 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
5990 hddLog(LOG1, FL("flag=%d"), start_log.flag);
5991
5992 if ((RING_ID_PER_PACKET_STATS == start_log.ringId) &&
Sushant Kaushik33200572015-08-05 16:46:20 +05305993 (!hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable ||
5994 !vos_isPktStatsEnabled()))
5995
Sushant Kaushik8e644982015-09-23 12:18:54 +05305996 {
5997 hddLog(LOGE, FL("per pkt stats not enabled"));
5998 return -EINVAL;
5999 }
Sushant Kaushik8e644982015-09-23 12:18:54 +05306000
Sushant Kaushik33200572015-08-05 16:46:20 +05306001 vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306002 return 0;
6003}
6004
6005/**
6006 * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
6007 * or disable the collection of packet statistics from the firmware
6008 * @wiphy: WIPHY structure pointer
6009 * @wdev: Wireless device structure pointer
6010 * @data: Pointer to the data received
6011 * @data_len: Length of the data received
6012 *
6013 * This function is used to enable or disable the collection of packet
6014 * statistics from the firmware
6015 *
6016 * Return: 0 on success and errno on failure
6017 */
6018static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6019 struct wireless_dev *wdev,
6020 const void *data,
6021 int data_len)
c_manjeecfd1efb2015-09-25 19:32:34 +05306022{
6023 int ret = 0;
6024
6025 vos_ssr_protect(__func__);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306026
6027 ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
6028 wdev, data, data_len);
c_manjeecfd1efb2015-09-25 19:32:34 +05306029 vos_ssr_unprotect(__func__);
6030
6031 return ret;
c_manjeecfd1efb2015-09-25 19:32:34 +05306032}
6033
6034
Agarwal Ashish738843c2014-09-25 12:27:56 +05306035static const struct nla_policy
6036wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
6037 +1] =
6038{
6039 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
6040};
6041
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306042static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306043 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306044 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306045 int data_len)
6046{
6047 struct net_device *dev = wdev->netdev;
6048 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6049 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6050 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6051 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
6052 eHalStatus status;
6053 u32 dfsFlag = 0;
6054
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306055 ENTER();
6056
Agarwal Ashish738843c2014-09-25 12:27:56 +05306057 status = wlan_hdd_validate_context(pHddCtx);
6058 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05306059 return -EINVAL;
6060 }
6061 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
6062 data, data_len,
6063 wlan_hdd_set_no_dfs_flag_config_policy)) {
6064 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6065 return -EINVAL;
6066 }
6067
6068 /* Parse and fetch required bandwidth kbps */
6069 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
6070 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
6071 return -EINVAL;
6072 }
6073
6074 dfsFlag = nla_get_u32(
6075 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
6076 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
6077 dfsFlag);
6078
6079 pHddCtx->disable_dfs_flag = dfsFlag;
6080
6081 sme_disable_dfs_channel(hHal, dfsFlag);
6082 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306083
6084 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05306085 return 0;
6086}
Atul Mittal115287b2014-07-08 13:26:33 +05306087
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306088static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
6089 struct wireless_dev *wdev,
6090 const void *data,
6091 int data_len)
6092{
6093 int ret = 0;
6094
6095 vos_ssr_protect(__func__);
6096 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
6097 vos_ssr_unprotect(__func__);
6098
6099 return ret;
6100
6101}
6102
Mukul Sharma2a271632014-10-13 14:59:01 +05306103const struct
6104nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
6105{
6106 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05306107 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
6108 .type = NLA_UNSPEC,
6109 .len = HDD_MAC_ADDR_LEN},
Mukul Sharma2a271632014-10-13 14:59:01 +05306110};
6111
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306112static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05306113 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05306114{
6115
6116 u8 bssid[6] = {0};
6117 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6118 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6119 eHalStatus status = eHAL_STATUS_SUCCESS;
6120 v_U32_t isFwrRoamEnabled = FALSE;
6121 int ret;
6122
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306123 ENTER();
6124
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306125 ret = wlan_hdd_validate_context(pHddCtx);
6126 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306127 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05306128 }
6129
6130 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
6131 data, data_len,
6132 qca_wlan_vendor_attr);
6133 if (ret){
6134 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6135 return -EINVAL;
6136 }
6137
6138 /* Parse and fetch Enable flag */
6139 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
6140 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
6141 return -EINVAL;
6142 }
6143
6144 isFwrRoamEnabled = nla_get_u32(
6145 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
6146
6147 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
6148
6149 /* Parse and fetch bssid */
6150 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
6151 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
6152 return -EINVAL;
6153 }
6154
6155 memcpy(bssid, nla_data(
6156 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
6157 sizeof(bssid));
6158 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
6159
6160 //Update roaming
6161 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306162 if (!HAL_STATUS_SUCCESS(status)) {
6163 hddLog(LOGE,
6164 FL("sme_ConfigFwrRoaming failed (err=%d)"), status);
6165 return -EINVAL;
6166 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306167 EXIT();
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306168 return 0;
Mukul Sharma2a271632014-10-13 14:59:01 +05306169}
6170
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306171static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
6172 struct wireless_dev *wdev, const void *data, int data_len)
6173{
6174 int ret = 0;
6175
6176 vos_ssr_protect(__func__);
6177 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
6178 vos_ssr_unprotect(__func__);
6179
6180 return ret;
6181}
6182
Sushant Kaushik847890c2015-09-28 16:05:17 +05306183static const struct
6184nla_policy
6185qca_wlan_vendor_get_wifi_info_policy[
6186 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
6187 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
6188 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
6189};
6190
6191
6192/**
6193 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6194 * @wiphy: pointer to wireless wiphy structure.
6195 * @wdev: pointer to wireless_dev structure.
6196 * @data: Pointer to the data to be passed via vendor interface
6197 * @data_len:Length of the data to be passed
6198 *
6199 * This is called when wlan driver needs to send wifi driver related info
6200 * (driver/fw version) to the user space application upon request.
6201 *
6202 * Return: Return the Success or Failure code.
6203 */
6204static int __wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6205 struct wireless_dev *wdev,
6206 const void *data, int data_len)
6207{
6208 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6209 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
6210 tSirVersionString version;
6211 uint32 version_len;
6212 uint8 attr;
6213 int status;
6214 struct sk_buff *reply_skb = NULL;
6215
6216 if (VOS_FTM_MODE == hdd_get_conparam()) {
6217 hddLog(LOGE, FL("Command not allowed in FTM mode"));
6218 return -EINVAL;
6219 }
6220
6221 status = wlan_hdd_validate_context(hdd_ctx);
6222 if (0 != status) {
6223 hddLog(LOGE, FL("HDD context is not valid"));
6224 return -EINVAL;
6225 }
6226
6227 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
6228 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
6229 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
6230 return -EINVAL;
6231 }
6232
6233 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
6234 hddLog(LOG1, FL("Rcvd req for Driver version Driver version is %s"),
6235 QWLAN_VERSIONSTR);
6236 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
6237 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
6238 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
6239 hddLog(LOG1, FL("Rcvd req for FW version FW version is %s"),
6240 hdd_ctx->fw_Version);
6241 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
6242 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
6243 } else {
6244 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
6245 return -EINVAL;
6246 }
6247
6248 version_len = strlen(version);
6249 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
6250 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
6251 if (!reply_skb) {
6252 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6253 return -ENOMEM;
6254 }
6255
6256 if (nla_put(reply_skb, attr, version_len, version)) {
6257 hddLog(LOGE, FL("nla put fail"));
6258 kfree_skb(reply_skb);
6259 return -EINVAL;
6260 }
6261
6262 return cfg80211_vendor_cmd_reply(reply_skb);
6263}
6264
6265/**
6266 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6267 * @wiphy: pointer to wireless wiphy structure.
6268 * @wdev: pointer to wireless_dev structure.
6269 * @data: Pointer to the data to be passed via vendor interface
6270 * @data_len:Length of the data to be passed
6271 * @data_len: Length of the data received
6272 *
6273 * This function is used to enable or disable the collection of packet
6274 * statistics from the firmware
6275 *
6276 * Return: 0 on success and errno on failure
6277 */
6278
6279static int
6280wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6281 struct wireless_dev *wdev,
6282 const void *data, int data_len)
6283
6284
6285{
6286 int ret = 0;
6287
6288 vos_ssr_protect(__func__);
6289 ret = __wlan_hdd_cfg80211_get_wifi_info(wiphy,
6290 wdev, data, data_len);
6291 vos_ssr_unprotect(__func__);
6292
6293 return ret;
6294}
6295
6296
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306297/*
6298 * define short names for the global vendor params
6299 * used by __wlan_hdd_cfg80211_monitor_rssi()
6300 */
6301#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX
6302#define PARAM_REQUEST_ID QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID
6303#define PARAM_CONTROL QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL
6304#define PARAM_MIN_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI
6305#define PARAM_MAX_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI
6306
6307/**---------------------------------------------------------------------------
6308
6309 \brief hdd_rssi_monitor_start_done - callback to be executed when rssi
6310 monitor start is completed successfully.
6311
6312 \return - None
6313
6314 --------------------------------------------------------------------------*/
6315void hdd_rssi_monitor_start_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6316{
6317 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6318
6319 if (NULL == pHddCtx)
6320 {
6321 hddLog(VOS_TRACE_LEVEL_ERROR,
6322 "%s: HDD context is NULL",__func__);
6323 return;
6324 }
6325
6326 if (VOS_STATUS_SUCCESS == status)
6327 {
6328 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor start successful"));
6329 }
6330 else
6331 {
6332 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor start not successful"));
6333 }
6334
6335 return;
6336}
6337
6338/**---------------------------------------------------------------------------
6339
6340 \brief hdd_rssi_monitor_stop_done - callback to be executed when rssi monitor
6341 stop is completed successfully.
6342
6343 \return - None
6344
6345 --------------------------------------------------------------------------*/
6346void hdd_rssi_monitor_stop_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6347{
6348 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6349
6350 if (NULL == pHddCtx)
6351 {
6352 hddLog(VOS_TRACE_LEVEL_ERROR,
6353 "%s: HDD context is NULL",__func__);
6354 return;
6355 }
6356
6357 if (VOS_STATUS_SUCCESS == status)
6358 {
6359 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor stop successful"));
6360 }
6361 else
6362 {
6363 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor stop not successful"));
6364 }
6365
6366 return;
6367}
6368
6369/**
6370 * __wlan_hdd_cfg80211_monitor_rssi() - monitor rssi
6371 * @wiphy: Pointer to wireless phy
6372 * @wdev: Pointer to wireless device
6373 * @data: Pointer to data
6374 * @data_len: Data length
6375 *
6376 * Return: 0 on success, negative errno on failure
6377 */
6378
6379static int
6380__wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy,
6381 struct wireless_dev *wdev,
6382 const void *data,
6383 int data_len)
6384{
6385 struct net_device *dev = wdev->netdev;
6386 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6387 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6388 hdd_station_ctx_t *pHddStaCtx;
6389 struct nlattr *tb[PARAM_MAX + 1];
6390 tpSirRssiMonitorReq pReq;
6391 eHalStatus status;
6392 int ret;
6393 uint32_t control;
6394 static const struct nla_policy policy[PARAM_MAX + 1] = {
6395 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6396 [PARAM_CONTROL] = { .type = NLA_U32 },
6397 [PARAM_MIN_RSSI] = { .type = NLA_S8 },
6398 [PARAM_MAX_RSSI] = { .type = NLA_S8 },
6399 };
6400
6401 ENTER();
6402
6403 ret = wlan_hdd_validate_context(hdd_ctx);
6404 if (0 != ret) {
6405 return -EINVAL;
6406 }
6407
6408 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6409 hddLog(LOGE, FL("Not in Connected state!"));
6410 return -ENOTSUPP;
6411 }
6412
6413 if (nla_parse(tb, PARAM_MAX, data, data_len, policy)) {
6414 hddLog(LOGE, FL("Invalid ATTR"));
6415 return -EINVAL;
6416 }
6417
6418 if (!tb[PARAM_REQUEST_ID]) {
6419 hddLog(LOGE, FL("attr request id failed"));
6420 return -EINVAL;
6421 }
6422
6423 if (!tb[PARAM_CONTROL]) {
6424 hddLog(LOGE, FL("attr control failed"));
6425 return -EINVAL;
6426 }
6427
6428 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6429
6430 pReq = vos_mem_malloc(sizeof(tSirRssiMonitorReq));
6431 if(NULL == pReq)
6432 {
6433 hddLog(LOGE,
6434 FL("vos_mem_alloc failed "));
6435 return eHAL_STATUS_FAILED_ALLOC;
6436 }
6437 vos_mem_set(pReq, sizeof(tSirRssiMonitorReq), 0);
6438
6439 pReq->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]);
6440 pReq->sessionId = pAdapter->sessionId;
6441 pReq->rssiMonitorCbContext = hdd_ctx;
6442 control = nla_get_u32(tb[PARAM_CONTROL]);
6443 vos_mem_copy( &pReq->currentBssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
6444
6445 hddLog(LOG1, FL("Request Id: %u Session_id: %d Control: %d"),
6446 pReq->requestId, pReq->sessionId, control);
6447
6448 if (control == QCA_WLAN_RSSI_MONITORING_START) {
6449 if (!tb[PARAM_MIN_RSSI]) {
6450 hddLog(LOGE, FL("attr min rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306451 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306452 }
6453
6454 if (!tb[PARAM_MAX_RSSI]) {
6455 hddLog(LOGE, FL("attr max rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306456 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306457 }
6458
6459 pReq->minRssi = nla_get_s8(tb[PARAM_MIN_RSSI]);
6460 pReq->maxRssi = nla_get_s8(tb[PARAM_MAX_RSSI]);
6461 pReq->rssiMonitorCallback = hdd_rssi_monitor_start_done;
6462
6463 if (!(pReq->minRssi < pReq->maxRssi)) {
6464 hddLog(LOGW, FL("min_rssi: %d must be less than max_rssi: %d"),
6465 pReq->minRssi, pReq->maxRssi);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306466 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306467 }
6468 hddLog(LOG1, FL("Min_rssi: %d Max_rssi: %d"),
6469 pReq->minRssi, pReq->maxRssi);
6470 status = sme_StartRssiMonitoring(hdd_ctx->hHal, pReq);
6471
6472 }
6473 else if (control == QCA_WLAN_RSSI_MONITORING_STOP) {
6474 pReq->rssiMonitorCallback = hdd_rssi_monitor_stop_done;
6475 status = sme_StopRssiMonitoring(hdd_ctx->hHal, pReq);
6476 }
6477 else {
6478 hddLog(LOGE, FL("Invalid control cmd: %d"), control);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306479 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306480 }
6481
6482 if (!HAL_STATUS_SUCCESS(status)) {
6483 hddLog(LOGE,
6484 FL("sme_set_rssi_monitoring failed(err=%d)"), status);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306485 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306486 }
6487
6488 return 0;
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306489fail:
6490 vos_mem_free(pReq);
6491 return -EINVAL;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306492}
6493
6494/*
6495 * done with short names for the global vendor params
6496 * used by __wlan_hdd_cfg80211_monitor_rssi()
6497 */
6498#undef PARAM_MAX
6499#undef PARAM_CONTROL
6500#undef PARAM_REQUEST_ID
6501#undef PARAM_MAX_RSSI
6502#undef PARAM_MIN_RSSI
6503
6504/**
6505 * wlan_hdd_cfg80211_monitor_rssi() - SSR wrapper to rssi monitoring
6506 * @wiphy: wiphy structure pointer
6507 * @wdev: Wireless device structure pointer
6508 * @data: Pointer to the data received
6509 * @data_len: Length of @data
6510 *
6511 * Return: 0 on success; errno on failure
6512 */
6513static int
6514wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, struct wireless_dev *wdev,
6515 const void *data, int data_len)
6516{
6517 int ret;
6518
6519 vos_ssr_protect(__func__);
6520 ret = __wlan_hdd_cfg80211_monitor_rssi(wiphy, wdev, data, data_len);
6521 vos_ssr_unprotect(__func__);
6522
6523 return ret;
6524}
6525
6526/**
6527 * hdd_rssi_threshold_breached_cb() - rssi breached NL event
6528 * @hddctx: HDD context
6529 * @data: rssi breached event data
6530 *
6531 * This function reads the rssi breached event %data and fill in the skb with
6532 * NL attributes and send up the NL event.
6533 * This callback execute in atomic context and must not invoke any
6534 * blocking calls.
6535 *
6536 * Return: none
6537 */
6538void hdd_rssi_threshold_breached_cb(void *hddctx,
6539 struct rssi_breach_event *data)
6540{
6541 hdd_context_t *pHddCtx = (hdd_context_t *)hddctx;
6542 int status;
6543 struct sk_buff *skb;
6544
6545 ENTER();
6546 status = wlan_hdd_validate_context(pHddCtx);
6547
6548 if (0 != status) {
6549 return;
6550 }
6551
6552 if (!data) {
6553 hddLog(LOGE, FL("data is null"));
6554 return;
6555 }
6556
6557 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
6558#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
6559 NULL,
6560#endif
6561 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
6562 QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX,
6563 GFP_KERNEL);
6564
6565 if (!skb) {
6566 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
6567 return;
6568 }
6569
6570 hddLog(LOG1, "Req Id: %u Current rssi: %d",
6571 data->request_id, data->curr_rssi);
6572 hddLog(LOG1, "Current BSSID: "MAC_ADDRESS_STR,
6573 MAC_ADDR_ARRAY(data->curr_bssid.bytes));
6574
6575 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
6576 data->request_id) ||
6577 nla_put(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID,
6578 sizeof(data->curr_bssid), data->curr_bssid.bytes) ||
6579 nla_put_s8(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI,
6580 data->curr_rssi)) {
6581 hddLog(LOGE, FL("nla put fail"));
6582 goto fail;
6583 }
6584
6585 cfg80211_vendor_event(skb, GFP_KERNEL);
6586 return;
6587
6588fail:
6589 kfree_skb(skb);
6590 return;
6591}
6592
6593
6594
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306595/**
6596 * __wlan_hdd_cfg80211_setband() - set band
6597 * @wiphy: Pointer to wireless phy
6598 * @wdev: Pointer to wireless device
6599 * @data: Pointer to data
6600 * @data_len: Data length
6601 *
6602 * Return: 0 on success, negative errno on failure
6603 */
6604static int
6605__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6606 struct wireless_dev *wdev,
6607 const void *data,
6608 int data_len)
6609{
6610 struct net_device *dev = wdev->netdev;
6611 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6612 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6613 int ret;
6614 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
6615 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
6616
6617 ENTER();
6618
6619 ret = wlan_hdd_validate_context(hdd_ctx);
6620 if (0 != ret) {
6621 hddLog(LOGE, FL("HDD context is not valid"));
6622 return ret;
6623 }
6624
6625 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
6626 policy)) {
6627 hddLog(LOGE, FL("Invalid ATTR"));
6628 return -EINVAL;
6629 }
6630
6631 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
6632 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
6633 return -EINVAL;
6634 }
6635
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306636 hdd_ctx->isSetBandByNL = TRUE;
6637 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306638 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306639 hdd_ctx->isSetBandByNL = FALSE;
6640
6641 EXIT();
6642 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306643}
6644
6645/**
6646 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
6647 * @wiphy: wiphy structure pointer
6648 * @wdev: Wireless device structure pointer
6649 * @data: Pointer to the data received
6650 * @data_len: Length of @data
6651 *
6652 * Return: 0 on success; errno on failure
6653 */
6654static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6655 struct wireless_dev *wdev,
6656 const void *data,
6657 int data_len)
6658{
6659 int ret = 0;
6660
6661 vos_ssr_protect(__func__);
6662 ret = __wlan_hdd_cfg80211_setband(wiphy,
6663 wdev, data, data_len);
6664 vos_ssr_unprotect(__func__);
6665
6666 return ret;
6667}
6668
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05306669#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
6670/**
6671 * hdd_map_req_id_to_pattern_id() - map request id to pattern id
6672 * @hdd_ctx: HDD context
6673 * @request_id: [input] request id
6674 * @pattern_id: [output] pattern id
6675 *
6676 * This function loops through request id to pattern id array
6677 * if the slot is available, store the request id and return pattern id
6678 * if entry exists, return the pattern id
6679 *
6680 * Return: 0 on success and errno on failure
6681 */
6682static int hdd_map_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
6683 uint32_t request_id,
6684 uint8_t *pattern_id)
6685{
6686 uint32_t i;
6687
6688 mutex_lock(&hdd_ctx->op_ctx.op_lock);
6689 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
6690 {
6691 if (hdd_ctx->op_ctx.op_table[i].request_id == 0)
6692 {
6693 hdd_ctx->op_ctx.op_table[i].request_id = request_id;
6694 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6695 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6696 return 0;
6697 } else if (hdd_ctx->op_ctx.op_table[i].request_id ==
6698 request_id) {
6699 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6700 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6701 return 0;
6702 }
6703 }
6704 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6705 return -EINVAL;
6706}
6707
6708/**
6709 * hdd_unmap_req_id_to_pattern_id() - unmap request id to pattern id
6710 * @hdd_ctx: HDD context
6711 * @request_id: [input] request id
6712 * @pattern_id: [output] pattern id
6713 *
6714 * This function loops through request id to pattern id array
6715 * reset request id to 0 (slot available again) and
6716 * return pattern id
6717 *
6718 * Return: 0 on success and errno on failure
6719 */
6720static int hdd_unmap_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
6721 uint32_t request_id,
6722 uint8_t *pattern_id)
6723{
6724 uint32_t i;
6725
6726 mutex_lock(&hdd_ctx->op_ctx.op_lock);
6727 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
6728 {
6729 if (hdd_ctx->op_ctx.op_table[i].request_id == request_id)
6730 {
6731 hdd_ctx->op_ctx.op_table[i].request_id = 0;
6732 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6733 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6734 return 0;
6735 }
6736 }
6737 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6738 return -EINVAL;
6739}
6740
6741
6742/*
6743 * define short names for the global vendor params
6744 * used by __wlan_hdd_cfg80211_offloaded_packets()
6745 */
6746#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX
6747#define PARAM_REQUEST_ID \
6748 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID
6749#define PARAM_CONTROL \
6750 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL
6751#define PARAM_IP_PACKET \
6752 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA
6753#define PARAM_SRC_MAC_ADDR \
6754 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR
6755#define PARAM_DST_MAC_ADDR \
6756 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR
6757#define PARAM_PERIOD QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD
6758
6759/**
6760 * wlan_hdd_add_tx_ptrn() - add tx pattern
6761 * @adapter: adapter pointer
6762 * @hdd_ctx: hdd context
6763 * @tb: nl attributes
6764 *
6765 * This function reads the NL attributes and forms a AddTxPtrn message
6766 * posts it to SME.
6767 *
6768 */
6769static int
6770wlan_hdd_add_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
6771 struct nlattr **tb)
6772{
6773 struct sSirAddPeriodicTxPtrn *add_req;
6774 eHalStatus status;
6775 uint32_t request_id, ret, len;
6776 uint8_t pattern_id = 0;
6777 v_MACADDR_t dst_addr;
6778 uint16_t eth_type = htons(ETH_P_IP);
6779
6780 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(adapter)))
6781 {
6782 hddLog(LOGE, FL("Not in Connected state!"));
6783 return -ENOTSUPP;
6784 }
6785
6786 add_req = vos_mem_malloc(sizeof(*add_req));
6787 if (!add_req)
6788 {
6789 hddLog(LOGE, FL("memory allocation failed"));
6790 return -ENOMEM;
6791 }
6792
6793 /* Parse and fetch request Id */
6794 if (!tb[PARAM_REQUEST_ID])
6795 {
6796 hddLog(LOGE, FL("attr request id failed"));
6797 goto fail;
6798 }
6799
6800 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
6801 hddLog(LOG1, FL("Request Id: %u"), request_id);
6802 if (request_id == 0)
6803 {
6804 hddLog(LOGE, FL("request_id cannot be zero"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306805 goto fail;
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05306806 }
6807
6808 if (!tb[PARAM_PERIOD])
6809 {
6810 hddLog(LOGE, FL("attr period failed"));
6811 goto fail;
6812 }
6813 add_req->usPtrnIntervalMs = nla_get_u32(tb[PARAM_PERIOD]);
6814 hddLog(LOG1, FL("Period: %u ms"), add_req->usPtrnIntervalMs);
6815 if (add_req->usPtrnIntervalMs == 0)
6816 {
6817 hddLog(LOGE, FL("Invalid interval zero, return failure"));
6818 goto fail;
6819 }
6820
6821 if (!tb[PARAM_SRC_MAC_ADDR])
6822 {
6823 hddLog(LOGE, FL("attr source mac address failed"));
6824 goto fail;
6825 }
6826 nla_memcpy(add_req->macAddress, tb[PARAM_SRC_MAC_ADDR],
6827 VOS_MAC_ADDR_SIZE);
6828 hddLog(LOG1, "input src mac address: "MAC_ADDRESS_STR,
6829 MAC_ADDR_ARRAY(add_req->macAddress));
6830
6831 if (memcmp(add_req->macAddress, adapter->macAddressCurrent.bytes,
6832 VOS_MAC_ADDR_SIZE))
6833 {
6834 hddLog(LOGE,
6835 FL("input src mac address and connected ap bssid are different"));
6836 goto fail;
6837 }
6838
6839 if (!tb[PARAM_DST_MAC_ADDR])
6840 {
6841 hddLog(LOGE, FL("attr dst mac address failed"));
6842 goto fail;
6843 }
6844 nla_memcpy(dst_addr.bytes, tb[PARAM_DST_MAC_ADDR], VOS_MAC_ADDR_SIZE);
6845 hddLog(LOG1, "input dst mac address: "MAC_ADDRESS_STR,
6846 MAC_ADDR_ARRAY(dst_addr.bytes));
6847
6848 if (!tb[PARAM_IP_PACKET])
6849 {
6850 hddLog(LOGE, FL("attr ip packet failed"));
6851 goto fail;
6852 }
6853 add_req->ucPtrnSize = nla_len(tb[PARAM_IP_PACKET]);
6854 hddLog(LOG1, FL("IP packet len: %u"), add_req->ucPtrnSize);
6855
6856 if (add_req->ucPtrnSize < 0 ||
6857 add_req->ucPtrnSize > (PERIODIC_TX_PTRN_MAX_SIZE -
6858 HDD_ETH_HEADER_LEN))
6859 {
6860 hddLog(LOGE, FL("Invalid IP packet len: %d"),
6861 add_req->ucPtrnSize);
6862 goto fail;
6863 }
6864
6865 len = 0;
6866 vos_mem_copy(&add_req->ucPattern[0], dst_addr.bytes, VOS_MAC_ADDR_SIZE);
6867 len += VOS_MAC_ADDR_SIZE;
6868 vos_mem_copy(&add_req->ucPattern[len], add_req->macAddress,
6869 VOS_MAC_ADDR_SIZE);
6870 len += VOS_MAC_ADDR_SIZE;
6871 vos_mem_copy(&add_req->ucPattern[len], &eth_type, 2);
6872 len += 2;
6873
6874 /*
6875 * This is the IP packet, add 14 bytes Ethernet (802.3) header
6876 * ------------------------------------------------------------
6877 * | 14 bytes Ethernet (802.3) header | IP header and payload |
6878 * ------------------------------------------------------------
6879 */
6880 vos_mem_copy(&add_req->ucPattern[len],
6881 nla_data(tb[PARAM_IP_PACKET]),
6882 add_req->ucPtrnSize);
6883 add_req->ucPtrnSize += len;
6884
6885 VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6886 add_req->ucPattern, add_req->ucPtrnSize);
6887
6888 ret = hdd_map_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
6889 if (ret)
6890 {
6891 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
6892 goto fail;
6893 }
6894 add_req->ucPtrnId = pattern_id;
6895 hddLog(LOG1, FL("pattern id: %d"), add_req->ucPtrnId);
6896
6897 status = sme_AddPeriodicTxPtrn(hdd_ctx->hHal, add_req);
6898 if (!HAL_STATUS_SUCCESS(status))
6899 {
6900 hddLog(LOGE,
6901 FL("sme_AddPeriodicTxPtrn failed (err=%d)"), status);
6902 goto fail;
6903 }
6904
6905 EXIT();
6906 vos_mem_free(add_req);
6907 return 0;
6908
6909fail:
6910 vos_mem_free(add_req);
6911 return -EINVAL;
6912}
6913
6914/**
6915 * wlan_hdd_del_tx_ptrn() - delete tx pattern
6916 * @adapter: adapter pointer
6917 * @hdd_ctx: hdd context
6918 * @tb: nl attributes
6919 *
6920 * This function reads the NL attributes and forms a DelTxPtrn message
6921 * posts it to SME.
6922 *
6923 */
6924static int
6925wlan_hdd_del_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
6926 struct nlattr **tb)
6927{
6928 struct sSirDelPeriodicTxPtrn *del_req;
6929 eHalStatus status;
6930 uint32_t request_id, ret;
6931 uint8_t pattern_id = 0;
6932
6933 /* Parse and fetch request Id */
6934 if (!tb[PARAM_REQUEST_ID])
6935 {
6936 hddLog(LOGE, FL("attr request id failed"));
6937 return -EINVAL;
6938 }
6939 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
6940 if (request_id == 0)
6941 {
6942 hddLog(LOGE, FL("request_id cannot be zero"));
6943 return -EINVAL;
6944 }
6945
6946 ret = hdd_unmap_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
6947 if (ret)
6948 {
6949 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
6950 return -EINVAL;
6951 }
6952
6953 del_req = vos_mem_malloc(sizeof(*del_req));
6954 if (!del_req)
6955 {
6956 hddLog(LOGE, FL("memory allocation failed"));
6957 return -ENOMEM;
6958 }
6959
6960 vos_mem_set(del_req, sizeof(*del_req), 0);
6961 vos_mem_copy(del_req->macAddress, adapter->macAddressCurrent.bytes,
6962 VOS_MAC_ADDR_SIZE);
6963 hddLog(LOG1, MAC_ADDRESS_STR, MAC_ADDR_ARRAY(del_req->macAddress));
6964 del_req->ucPatternIdBitmap |= (0x1 << pattern_id);
6965 hddLog(LOG1, FL("Request Id: %u Pattern id: %d, bitmap %04x"),
6966 request_id, pattern_id, del_req->ucPatternIdBitmap);
6967
6968 status = sme_DelPeriodicTxPtrn(hdd_ctx->hHal, del_req);
6969 if (!HAL_STATUS_SUCCESS(status))
6970 {
6971 hddLog(LOGE,
6972 FL("sme_DelPeriodicTxPtrn failed (err=%d)"), status);
6973 goto fail;
6974 }
6975
6976 EXIT();
6977 vos_mem_free(del_req);
6978 return 0;
6979
6980fail:
6981 vos_mem_free(del_req);
6982 return -EINVAL;
6983}
6984
6985
6986/**
6987 * __wlan_hdd_cfg80211_offloaded_packets() - send offloaded packets
6988 * @wiphy: Pointer to wireless phy
6989 * @wdev: Pointer to wireless device
6990 * @data: Pointer to data
6991 * @data_len: Data length
6992 *
6993 * Return: 0 on success, negative errno on failure
6994 */
6995static int
6996__wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
6997 struct wireless_dev *wdev,
6998 const void *data,
6999 int data_len)
7000{
7001 struct net_device *dev = wdev->netdev;
7002 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7003 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7004 struct nlattr *tb[PARAM_MAX + 1];
7005 uint8_t control;
7006 int ret;
7007 static const struct nla_policy policy[PARAM_MAX + 1] =
7008 {
7009 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
7010 [PARAM_CONTROL] = { .type = NLA_U32 },
7011 [PARAM_SRC_MAC_ADDR] = { .type = NLA_BINARY,
7012 .len = VOS_MAC_ADDR_SIZE },
7013 [PARAM_DST_MAC_ADDR] = { .type = NLA_BINARY,
7014 .len = VOS_MAC_ADDR_SIZE },
7015 [PARAM_PERIOD] = { .type = NLA_U32 },
7016 };
7017
7018 ENTER();
7019
7020 ret = wlan_hdd_validate_context(hdd_ctx);
7021 if (0 != ret)
7022 {
7023 hddLog(LOGE, FL("HDD context is not valid"));
7024 return ret;
7025 }
7026
7027 if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN))
7028 {
7029 hddLog(LOGE,
7030 FL("Periodic Tx Pattern Offload feature is not supported in FW!"));
7031 return -ENOTSUPP;
7032 }
7033
7034 if (nla_parse(tb, PARAM_MAX, data, data_len, policy))
7035 {
7036 hddLog(LOGE, FL("Invalid ATTR"));
7037 return -EINVAL;
7038 }
7039
7040 if (!tb[PARAM_CONTROL])
7041 {
7042 hddLog(LOGE, FL("attr control failed"));
7043 return -EINVAL;
7044 }
7045 control = nla_get_u32(tb[PARAM_CONTROL]);
7046 hddLog(LOG1, FL("Control: %d"), control);
7047
7048 if (control == WLAN_START_OFFLOADED_PACKETS)
7049 return wlan_hdd_add_tx_ptrn(adapter, hdd_ctx, tb);
7050 else if (control == WLAN_STOP_OFFLOADED_PACKETS)
7051 return wlan_hdd_del_tx_ptrn(adapter, hdd_ctx, tb);
7052 else
7053 {
7054 hddLog(LOGE, FL("Invalid control: %d"), control);
7055 return -EINVAL;
7056 }
7057}
7058
7059/*
7060 * done with short names for the global vendor params
7061 * used by __wlan_hdd_cfg80211_offloaded_packets()
7062 */
7063#undef PARAM_MAX
7064#undef PARAM_REQUEST_ID
7065#undef PARAM_CONTROL
7066#undef PARAM_IP_PACKET
7067#undef PARAM_SRC_MAC_ADDR
7068#undef PARAM_DST_MAC_ADDR
7069#undef PARAM_PERIOD
7070
7071/**
7072 * wlan_hdd_cfg80211_offloaded_packets() - Wrapper to offload packets
7073 * @wiphy: wiphy structure pointer
7074 * @wdev: Wireless device structure pointer
7075 * @data: Pointer to the data received
7076 * @data_len: Length of @data
7077 *
7078 * Return: 0 on success; errno on failure
7079 */
7080static int wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7081 struct wireless_dev *wdev,
7082 const void *data,
7083 int data_len)
7084{
7085 int ret = 0;
7086
7087 vos_ssr_protect(__func__);
7088 ret = __wlan_hdd_cfg80211_offloaded_packets(wiphy,
7089 wdev, data, data_len);
7090 vos_ssr_unprotect(__func__);
7091
7092 return ret;
7093}
7094#endif
7095
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307096static const struct
7097nla_policy
7098qca_wlan_vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05307099 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
7100 .type = NLA_BINARY,
7101 .len = HDD_MAC_ADDR_LEN},
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307102};
7103
7104/**
7105 * wlan_hdd_cfg80211_get_link_properties() - This function is used to
7106 * get link properties like nss, rate flags and operating frequency for
7107 * the connection with the given peer.
7108 * @wiphy: WIPHY structure pointer
7109 * @wdev: Wireless device structure pointer
7110 * @data: Pointer to the data received
7111 * @data_len: Length of the data received
7112 *
7113 * This function return the above link properties on success.
7114 *
7115 * Return: 0 on success and errno on failure
7116 */
7117static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
7118 struct wireless_dev *wdev,
7119 const void *data,
7120 int data_len)
7121{
7122 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7123 struct net_device *dev = wdev->netdev;
7124 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7125 hdd_station_ctx_t *hdd_sta_ctx;
7126 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX+1];
7127 uint8_t peer_mac[VOS_MAC_ADDR_SIZE];
7128 uint32_t sta_id;
7129 struct sk_buff *reply_skb;
7130 uint32_t rate_flags = 0;
7131 uint8_t nss;
7132 uint8_t final_rate_flags = 0;
7133 uint32_t freq;
7134 v_CONTEXT_t pVosContext = NULL;
7135 ptSapContext pSapCtx = NULL;
7136
7137 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
7138 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
7139 return -EINVAL;
7140 }
7141
7142 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7143 qca_wlan_vendor_attr_policy)) {
7144 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid attribute"));
7145 return -EINVAL;
7146 }
7147
7148 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
7149 hddLog(VOS_TRACE_LEVEL_ERROR,
7150 FL("Attribute peerMac not provided for mode=%d"),
7151 adapter->device_mode);
7152 return -EINVAL;
7153 }
7154
Ashish Kumar Dhanotiyaddaf0482017-06-23 15:22:42 +05307155 if (nla_len(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) < sizeof(peer_mac)) {
7156 hddLog(VOS_TRACE_LEVEL_ERROR,
7157 FL("Attribute peerMac is invalid=%d"),
7158 adapter->device_mode);
7159 return -EINVAL;
7160 }
7161
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307162 memcpy(peer_mac, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
7163 sizeof(peer_mac));
7164 hddLog(VOS_TRACE_LEVEL_INFO,
7165 FL("peerMac="MAC_ADDRESS_STR" for device_mode:%d"),
7166 MAC_ADDR_ARRAY(peer_mac), adapter->device_mode);
7167
7168 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
7169 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
7170 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
7171 if ((hdd_sta_ctx->conn_info.connState !=
7172 eConnectionState_Associated) ||
7173 !vos_mem_compare(hdd_sta_ctx->conn_info.bssId, peer_mac,
7174 VOS_MAC_ADDRESS_LEN)) {
7175 hddLog(VOS_TRACE_LEVEL_ERROR,
7176 FL("Not Associated to mac "MAC_ADDRESS_STR),
7177 MAC_ADDR_ARRAY(peer_mac));
7178 return -EINVAL;
7179 }
7180
7181 nss = 1; //pronto supports only one spatial stream
7182 freq = vos_chan_to_freq(
7183 hdd_sta_ctx->conn_info.operationChannel);
7184 rate_flags = hdd_sta_ctx->conn_info.rate_flags;
7185
7186 } else if (adapter->device_mode == WLAN_HDD_P2P_GO ||
7187 adapter->device_mode == WLAN_HDD_SOFTAP) {
7188
7189 pVosContext = ( WLAN_HDD_GET_CTX(adapter))->pvosContext;
7190 pSapCtx = VOS_GET_SAP_CB(pVosContext);
7191 if(pSapCtx == NULL){
7192 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7193 FL("psapCtx is NULL"));
7194 return -ENOENT;
7195 }
7196
7197
7198 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
7199 if (pSapCtx->aStaInfo[sta_id].isUsed &&
7200 !vos_is_macaddr_broadcast(
7201 &pSapCtx->aStaInfo[sta_id].macAddrSTA) &&
7202 vos_mem_compare(
7203 &pSapCtx->aStaInfo[sta_id].macAddrSTA,
7204 peer_mac, VOS_MAC_ADDRESS_LEN))
7205 break;
7206 }
7207
7208 if (WLAN_MAX_STA_COUNT == sta_id) {
7209 hddLog(VOS_TRACE_LEVEL_ERROR,
7210 FL("No active peer with mac="MAC_ADDRESS_STR),
7211 MAC_ADDR_ARRAY(peer_mac));
7212 return -EINVAL;
7213 }
7214
7215 nss = 1; //pronto supports only one spatial stream
7216 freq = vos_chan_to_freq(
7217 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operatingChannel);
7218 rate_flags = pSapCtx->aStaInfo[sta_id].rate_flags;
7219 } else {
7220 hddLog(VOS_TRACE_LEVEL_ERROR,
7221 FL("Not Associated! with mac"MAC_ADDRESS_STR),
7222 MAC_ADDR_ARRAY(peer_mac));
7223 return -EINVAL;
7224 }
7225
7226 if (!(rate_flags & eHAL_TX_RATE_LEGACY)) {
7227 if (rate_flags & eHAL_TX_RATE_VHT80) {
7228 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7229 final_rate_flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
7230 } else if (rate_flags & eHAL_TX_RATE_VHT40) {
7231 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7232 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7233 } else if (rate_flags & eHAL_TX_RATE_VHT20) {
7234 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7235 } else if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40)) {
7236 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7237 if (rate_flags & eHAL_TX_RATE_HT40)
7238 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7239 }
7240
7241 if (rate_flags & eHAL_TX_RATE_SGI) {
7242 if (!(final_rate_flags & RATE_INFO_FLAGS_VHT_MCS))
7243 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7244 final_rate_flags |= RATE_INFO_FLAGS_SHORT_GI;
7245 }
7246 }
7247
7248 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7249 sizeof(u8) + sizeof(u8) + sizeof(u32) + NLMSG_HDRLEN);
7250
7251 if (NULL == reply_skb) {
7252 hddLog(VOS_TRACE_LEVEL_ERROR,
7253 FL("getLinkProperties: skb alloc failed"));
7254 return -EINVAL;
7255 }
7256
7257 if (nla_put_u8(reply_skb,
7258 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS,
7259 nss) ||
7260 nla_put_u8(reply_skb,
7261 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS,
7262 final_rate_flags) ||
7263 nla_put_u32(reply_skb,
7264 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ,
7265 freq)) {
7266 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_put failed"));
7267 kfree_skb(reply_skb);
7268 return -EINVAL;
7269 }
7270
7271 return cfg80211_vendor_cmd_reply(reply_skb);
7272}
7273
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307274#define BEACON_MISS_THRESH_2_4 \
7275 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24
7276#define BEACON_MISS_THRESH_5_0 \
7277 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307278#define PARAM_WIFICONFIG_MAX QCA_WLAN_VENDOR_ATTR_CONFIG_MAX
7279#define PARAM_MODULATED_DTIM QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM
7280#define PARAM_STATS_AVG_FACTOR QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR
7281#define PARAM_GUARD_TIME QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307282#define PARAM_BCNMISS_PENALTY_PARAM_COUNT \
7283 QCA_WLAN_VENDOR_ATTR_CONFIG_PENALIZE_AFTER_NCONS_BEACON_MISS
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307284
7285/**
7286 * __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7287 * vendor command
7288 *
7289 * @wiphy: wiphy device pointer
7290 * @wdev: wireless device pointer
7291 * @data: Vendor command data buffer
7292 * @data_len: Buffer length
7293 *
7294 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7295 *
7296 * Return: EOK or other error codes.
7297 */
7298
7299static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7300 struct wireless_dev *wdev,
7301 const void *data,
7302 int data_len)
7303{
7304 struct net_device *dev = wdev->netdev;
7305 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7306 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7307 hdd_station_ctx_t *pHddStaCtx;
7308 struct nlattr *tb[PARAM_WIFICONFIG_MAX + 1];
7309 tpSetWifiConfigParams pReq;
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307310 tModifyRoamParamsReqParams modifyRoamParamsReq;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307311 eHalStatus status;
7312 int ret_val;
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307313 uint8_t hb_thresh_val;
7314
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307315 static const struct nla_policy policy[PARAM_WIFICONFIG_MAX + 1] = {
7316 [PARAM_STATS_AVG_FACTOR] = { .type = NLA_U16 },
7317 [PARAM_MODULATED_DTIM] = { .type = NLA_U32 },
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307318 [PARAM_GUARD_TIME] = { .type = NLA_U32},
7319 [PARAM_BCNMISS_PENALTY_PARAM_COUNT] =
7320 { .type = NLA_U32},
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307321 [BEACON_MISS_THRESH_2_4] = { .type = NLA_U8 },
7322 [BEACON_MISS_THRESH_5_0] = { .type = NLA_U8 },
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307323 };
7324
7325 ENTER();
7326
7327 if (VOS_FTM_MODE == hdd_get_conparam()) {
7328 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7329 return -EINVAL;
7330 }
7331
7332 ret_val = wlan_hdd_validate_context(pHddCtx);
7333 if (ret_val) {
7334 return ret_val;
7335 }
7336
7337 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7338
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307339 if (nla_parse(tb, PARAM_WIFICONFIG_MAX, data, data_len, policy)) {
7340 hddLog(LOGE, FL("Invalid ATTR"));
7341 return -EINVAL;
7342 }
7343
7344 /* check the Wifi Capability */
7345 if ( (TRUE != pHddCtx->cfg_ini->fEnableWifiConfig) &&
7346 (TRUE != sme_IsFeatureSupportedByFW(WIFI_CONFIG)))
7347 {
7348 hddLog(VOS_TRACE_LEVEL_ERROR,
7349 FL("WIFICONFIG not supported by Firmware"));
7350 return -EINVAL;
7351 }
7352
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307353 if (tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]) {
7354 modifyRoamParamsReq.param = WIFI_CONFIG_SET_BCNMISS_PENALTY_COUNT;
7355 modifyRoamParamsReq.value =
7356 nla_get_u32(tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]);
7357
7358 if (eHAL_STATUS_SUCCESS !=
7359 sme_setBcnMissPenaltyCount(pHddCtx->hHal,&modifyRoamParamsReq))
7360 {
7361 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed", __func__);
7362 ret_val = -EINVAL;
7363 }
7364 return ret_val;
7365 }
7366
7367 /* Moved this down in order to provide provision to set beacon
7368 * miss penalty count irrespective of connection state.
7369 */
7370 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
7371 hddLog(LOGE, FL("Not in Connected state!"));
7372 return -ENOTSUPP;
7373 }
7374
7375 pReq = vos_mem_malloc(sizeof(tSetWifiConfigParams));
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307376
7377 if (!pReq) {
7378 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7379 "%s: Not able to allocate memory for tSetWifiConfigParams",
7380 __func__);
7381 return eHAL_STATUS_E_MALLOC_FAILED;
7382 }
7383
7384 vos_mem_set(pReq, sizeof(tSetWifiConfigParams), 0);
7385
7386 pReq->sessionId = pAdapter->sessionId;
7387 vos_mem_copy( &pReq->bssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
7388
7389 if (tb[PARAM_MODULATED_DTIM]) {
7390 pReq->paramValue = nla_get_u32(
7391 tb[PARAM_MODULATED_DTIM]);
7392 hddLog(LOG1, FL("Modulated DTIM: pReq->paramValue:%d "),
7393 pReq->paramValue);
Arun Khandavalli876886f2015-11-23 11:42:27 +05307394 pHddCtx->cfg_ini->enableDynamicDTIM = pReq->paramValue;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307395 hdd_set_pwrparams(pHddCtx);
7396 if (BMPS == pmcGetPmcState(pHddCtx->hHal)) {
7397 hddLog( LOG1, FL("WifiConfig: Requesting FullPower!"));
7398
7399 sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
7400 iw_full_power_cbfn, pAdapter,
7401 eSME_FULL_PWR_NEEDED_BY_HDD);
7402 }
7403 else
7404 {
7405 hddLog( LOG1, FL("WifiConfig Not in BMPS state"));
7406 }
7407 }
7408
7409 if (tb[PARAM_STATS_AVG_FACTOR]) {
7410 pReq->paramType = WIFI_CONFIG_SET_AVG_STATS_FACTOR;
7411 pReq->paramValue = nla_get_u16(
7412 tb[PARAM_STATS_AVG_FACTOR]);
7413 hddLog(LOG1, FL("AVG_STATS_FACTOR pReq->paramType:%d,pReq->paramValue:%d "),
7414 pReq->paramType, pReq->paramValue);
7415 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7416
7417 if (eHAL_STATUS_SUCCESS != status)
7418 {
7419 vos_mem_free(pReq);
7420 pReq = NULL;
7421 ret_val = -EPERM;
7422 return ret_val;
7423 }
7424 }
7425
7426
7427 if (tb[PARAM_GUARD_TIME]) {
7428 pReq->paramType = WIFI_CONFIG_SET_GUARD_TIME;
7429 pReq->paramValue = nla_get_u32(
7430 tb[PARAM_GUARD_TIME]);
7431 hddLog(LOG1, FL("GUARD_TIME pReq->paramType:%d,pReq->paramValue:%d "),
7432 pReq->paramType, pReq->paramValue);
7433 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7434
7435 if (eHAL_STATUS_SUCCESS != status)
7436 {
7437 vos_mem_free(pReq);
7438 pReq = NULL;
7439 ret_val = -EPERM;
7440 return ret_val;
7441 }
7442
7443 }
7444
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307445 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]) {
7446 hb_thresh_val = nla_get_u8(
7447 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]);
7448
7449 hddLog(LOG1, "WLAN set heartbeat threshold for 2.4Ghz %d",
7450 hb_thresh_val);
7451 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7452 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
7453 NULL, eANI_BOOLEAN_FALSE);
7454
7455 status = sme_update_hb_threshold(
7456 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
7457 WNI_CFG_HEART_BEAT_THRESHOLD,
7458 hb_thresh_val, eCSR_BAND_24);
7459 if (eHAL_STATUS_SUCCESS != status) {
7460 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
7461 vos_mem_free(pReq);
7462 pReq = NULL;
7463 return -EPERM;
7464 }
7465 }
7466
7467 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]) {
7468 hb_thresh_val = nla_get_u8(
7469 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]);
7470
7471 hddLog(LOG1, "WLAN set heartbeat threshold for 5Ghz %d",
7472 hb_thresh_val);
7473 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7474 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
7475 NULL, eANI_BOOLEAN_FALSE);
7476
7477 status = sme_update_hb_threshold(
7478 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
7479 WNI_CFG_HEART_BEAT_THRESHOLD,
7480 hb_thresh_val, eCSR_BAND_5G);
7481 if (eHAL_STATUS_SUCCESS != status) {
7482 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
7483 vos_mem_free(pReq);
7484 pReq = NULL;
7485 return -EPERM;
7486 }
7487 }
7488
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307489 EXIT();
7490 return ret_val;
7491}
7492
7493/**
7494 * wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7495 * vendor command
7496 *
7497 * @wiphy: wiphy device pointer
7498 * @wdev: wireless device pointer
7499 * @data: Vendor command data buffer
7500 * @data_len: Buffer length
7501 *
7502 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7503 *
7504 * Return: EOK or other error codes.
7505 */
7506static int wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7507 struct wireless_dev *wdev,
7508 const void *data,
7509 int data_len)
7510{
7511 int ret;
7512
7513 vos_ssr_protect(__func__);
7514 ret = __wlan_hdd_cfg80211_wifi_configuration_set(wiphy, wdev,
7515 data, data_len);
7516 vos_ssr_unprotect(__func__);
7517
7518 return ret;
7519}
Anurag Chouhan6ee81542017-02-09 18:09:27 +05307520
7521/*
7522 * define short names for the global vendor params
7523 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
7524 */
7525#define STATS_SET_INVALID \
7526 QCA_ATTR_NUD_STATS_SET_INVALID
7527#define STATS_SET_START \
7528 QCA_ATTR_NUD_STATS_SET_START
7529#define STATS_GW_IPV4 \
7530 QCA_ATTR_NUD_STATS_GW_IPV4
7531#define STATS_SET_MAX \
7532 QCA_ATTR_NUD_STATS_SET_MAX
7533
7534const struct nla_policy
7535qca_wlan_vendor_set_nud_stats[STATS_SET_MAX +1] =
7536{
7537 [STATS_SET_START] = {.type = NLA_FLAG },
7538 [STATS_GW_IPV4] = {.type = NLA_U32 },
7539};
7540
7541/**
7542 * hdd_set_nud_stats_cb() - hdd callback api to get status
7543 * @data: pointer to adapter
7544 * @rsp: status
7545 *
7546 * Return: None
7547 */
7548static void hdd_set_nud_stats_cb(void *data, VOS_STATUS rsp)
7549{
7550
7551 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
7552
7553 if (NULL == adapter)
7554 return;
7555
7556 if (VOS_STATUS_SUCCESS == rsp) {
7557 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7558 "%s success received STATS_SET_START", __func__);
7559 } else {
7560 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7561 "%s STATS_SET_START Failed!!", __func__);
7562 }
7563 return;
7564}
7565
7566/**
7567 * __wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
7568 * @wiphy: pointer to wireless wiphy structure.
7569 * @wdev: pointer to wireless_dev structure.
7570 * @data: pointer to apfind configuration data.
7571 * @data_len: the length in byte of apfind data.
7572 *
7573 * This is called when wlan driver needs to send arp stats to
7574 * firmware.
7575 *
7576 * Return: An error code or 0 on success.
7577 */
7578static int __wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
7579 struct wireless_dev *wdev,
7580 const void *data, int data_len)
7581{
7582 struct nlattr *tb[STATS_SET_MAX + 1];
7583 struct net_device *dev = wdev->netdev;
7584 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7585 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05307586 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
Anurag Chouhan6ee81542017-02-09 18:09:27 +05307587 setArpStatsParams arp_stats_params;
7588 int err = 0;
7589
7590 ENTER();
7591
7592 err = wlan_hdd_validate_context(hdd_ctx);
7593 if (0 != err)
7594 return err;
7595
7596 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
7597 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7598 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
7599 return -EINVAL;
7600 }
7601
7602 err = nla_parse(tb, STATS_SET_MAX, data, data_len,
7603 qca_wlan_vendor_set_nud_stats);
7604 if (err)
7605 {
7606 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7607 "%s STATS_SET_START ATTR", __func__);
7608 return err;
7609 }
7610
7611 if (tb[STATS_SET_START])
7612 {
7613 if (!tb[STATS_GW_IPV4]) {
7614 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7615 "%s STATS_SET_START CMD", __func__);
7616 return -EINVAL;
7617 }
7618 arp_stats_params.flag = true;
7619 arp_stats_params.ip_addr = nla_get_u32(tb[STATS_GW_IPV4]);
7620 } else {
7621 arp_stats_params.flag = false;
7622 }
Anurag Chouhan630c5562017-03-23 14:51:47 +05307623 if (arp_stats_params.flag)
Anurag Chouhan6ee81542017-02-09 18:09:27 +05307624 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7625 "%s STATS_SET_START Cleared!!", __func__);
Anurag Chouhan630c5562017-03-23 14:51:47 +05307626 vos_mem_zero(&adapter->hdd_stats.hddArpStats,
7627 sizeof(adapter->hdd_stats.hddArpStats));
Anurag Chouhan6ee81542017-02-09 18:09:27 +05307628
7629 arp_stats_params.pkt_type = 1; // ARP packet type
7630
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05307631 if (arp_stats_params.flag) {
7632 hdd_ctx->track_arp_ip = arp_stats_params.ip_addr;
7633 WLANTL_SetARPFWDatapath(pVosContext, true);
7634 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7635 "%s Set FW in data path for ARP with tgt IP :%d",
7636 __func__, hdd_ctx->track_arp_ip);
7637 }
7638 else {
7639 WLANTL_SetARPFWDatapath(pVosContext, false);
7640 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7641 "%s Remove FW from data path", __func__);
7642 }
7643
Anurag Chouhan6ee81542017-02-09 18:09:27 +05307644 arp_stats_params.rsp_cb_fn = hdd_set_nud_stats_cb;
7645 arp_stats_params.data_ctx = adapter;
7646
7647 if (eHAL_STATUS_SUCCESS !=
7648 sme_set_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
7649 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7650 "%s STATS_SET_START CMD Failed!!", __func__);
7651 return -EINVAL;
7652 }
7653
7654 EXIT();
7655
7656 return err;
7657}
7658
7659/**
7660 * wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
7661 * @wiphy: pointer to wireless wiphy structure.
7662 * @wdev: pointer to wireless_dev structure.
7663 * @data: pointer to apfind configuration data.
7664 * @data_len: the length in byte of apfind data.
7665 *
7666 * This is called when wlan driver needs to send arp stats to
7667 * firmware.
7668 *
7669 * Return: An error code or 0 on success.
7670 */
7671static int wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
7672 struct wireless_dev *wdev,
7673 const void *data, int data_len)
7674{
7675 int ret;
7676
7677 vos_ssr_protect(__func__);
7678 ret = __wlan_hdd_cfg80211_set_nud_stats(wiphy, wdev, data, data_len);
7679 vos_ssr_unprotect(__func__);
7680
7681 return ret;
7682}
7683#undef STATS_SET_INVALID
7684#undef STATS_SET_START
7685#undef STATS_GW_IPV4
7686#undef STATS_SET_MAX
7687
7688/*
7689 * define short names for the global vendor params
7690 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
7691 */
7692#define STATS_GET_INVALID \
7693 QCA_ATTR_NUD_STATS_SET_INVALID
7694#define COUNT_FROM_NETDEV \
7695 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
7696#define COUNT_TO_LOWER_MAC \
7697 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
7698#define RX_COUNT_BY_LOWER_MAC \
7699 QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
7700#define COUNT_TX_SUCCESS \
7701 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
7702#define RSP_RX_COUNT_BY_LOWER_MAC \
7703 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
7704#define RSP_RX_COUNT_BY_UPPER_MAC \
7705 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
7706#define RSP_COUNT_TO_NETDEV \
7707 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
7708#define RSP_COUNT_OUT_OF_ORDER_DROP \
7709 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
7710#define AP_LINK_ACTIVE \
7711 QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
7712#define AP_LINK_DAD \
7713 QCA_ATTR_NUD_STATS_AP_LINK_DAD
7714#define STATS_GET_MAX \
7715 QCA_ATTR_NUD_STATS_GET_MAX
7716
7717const struct nla_policy
7718qca_wlan_vendor_get_nud_stats[STATS_GET_MAX +1] =
7719{
7720 [COUNT_FROM_NETDEV] = {.type = NLA_U16 },
7721 [COUNT_TO_LOWER_MAC] = {.type = NLA_U16 },
7722 [RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
7723 [COUNT_TX_SUCCESS] = {.type = NLA_U16 },
7724 [RSP_RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
7725 [RSP_RX_COUNT_BY_UPPER_MAC] = {.type = NLA_U16 },
7726 [RSP_COUNT_TO_NETDEV] = {.type = NLA_U16 },
7727 [RSP_COUNT_OUT_OF_ORDER_DROP] = {.type = NLA_U16 },
7728 [AP_LINK_ACTIVE] = {.type = NLA_FLAG },
7729 [AP_LINK_DAD] = {.type = NLA_FLAG },
7730};
7731
7732static void hdd_get_nud_stats_cb(void *data, rsp_stats *rsp)
7733{
7734
7735 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
7736 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
7737 struct hdd_nud_stats_context *context;
7738 int status;
7739
7740 ENTER();
7741
7742 if (NULL == adapter)
7743 return;
7744
7745 status = wlan_hdd_validate_context(hdd_ctx);
7746 if (0 != status) {
7747 return;
7748 }
7749
7750 if (!rsp) {
7751 hddLog(LOGE, FL("data is null"));
7752 return;
7753 }
7754
7755 adapter->hdd_stats.hddArpStats.tx_fw_cnt = rsp->tx_fw_cnt;
7756 adapter->hdd_stats.hddArpStats.rx_fw_cnt = rsp->rx_fw_cnt;
7757 adapter->hdd_stats.hddArpStats.tx_ack_cnt = rsp->tx_ack_cnt;
7758 adapter->dad |= rsp->dad;
7759
7760 spin_lock(&hdd_context_lock);
7761 context = &hdd_ctx->nud_stats_context;
7762 complete(&context->response_event);
7763 spin_unlock(&hdd_context_lock);
7764
7765 return;
7766}
7767static int __wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
7768 struct wireless_dev *wdev,
7769 const void *data, int data_len)
7770{
7771 int err = 0;
7772 unsigned long rc;
7773 struct hdd_nud_stats_context *context;
7774 struct net_device *dev = wdev->netdev;
7775 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7776 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7777 getArpStatsParams arp_stats_params;
7778 struct sk_buff *skb;
7779
7780 ENTER();
7781
7782 err = wlan_hdd_validate_context(hdd_ctx);
7783 if (0 != err)
7784 return err;
7785
7786 arp_stats_params.pkt_type = WLAN_NUD_STATS_ARP_PKT_TYPE;
7787 arp_stats_params.get_rsp_cb_fn = hdd_get_nud_stats_cb;
7788 arp_stats_params.data_ctx = adapter;
7789
7790 spin_lock(&hdd_context_lock);
7791 context = &hdd_ctx->nud_stats_context;
7792 INIT_COMPLETION(context->response_event);
7793 spin_unlock(&hdd_context_lock);
7794
7795 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
7796 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7797 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
7798 return -EINVAL;
7799 }
7800
7801 if (eHAL_STATUS_SUCCESS !=
7802 sme_get_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
7803 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7804 "%s STATS_SET_START CMD Failed!!", __func__);
7805 return -EINVAL;
7806 }
7807
7808 rc = wait_for_completion_timeout(&context->response_event,
7809 msecs_to_jiffies(WLAN_WAIT_TIME_NUD_STATS));
7810 if (!rc)
7811 {
7812 hddLog(LOGE,
7813 FL("Target response timed out request "));
7814 return -ETIMEDOUT;
7815 }
7816
7817 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7818 WLAN_NUD_STATS_LEN);
7819 if (!skb)
7820 {
7821 hddLog(VOS_TRACE_LEVEL_ERROR,
7822 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
7823 __func__);
7824 return -ENOMEM;
7825 }
7826
7827 if (nla_put_u16(skb, COUNT_FROM_NETDEV,
7828 adapter->hdd_stats.hddArpStats.txCount) ||
7829 nla_put_u16(skb, COUNT_TO_LOWER_MAC,
7830 adapter->hdd_stats.hddArpStats.tx_host_fw_sent) ||
7831 nla_put_u16(skb, RX_COUNT_BY_LOWER_MAC,
7832 adapter->hdd_stats.hddArpStats.tx_fw_cnt) ||
7833 nla_put_u16(skb, COUNT_TX_SUCCESS,
7834 adapter->hdd_stats.hddArpStats.tx_ack_cnt) ||
7835 nla_put_u16(skb, RSP_RX_COUNT_BY_LOWER_MAC,
7836 adapter->hdd_stats.hddArpStats.rx_fw_cnt) ||
7837 nla_put_u16(skb, RSP_RX_COUNT_BY_UPPER_MAC,
7838 adapter->hdd_stats.hddArpStats.rxCount) ||
7839 nla_put_u16(skb, RSP_COUNT_TO_NETDEV,
7840 adapter->hdd_stats.hddArpStats.rxDelivered) ||
7841 nla_put_u16(skb, RSP_COUNT_OUT_OF_ORDER_DROP,
7842 adapter->hdd_stats.hddArpStats.rx_host_drop_reorder)) {
7843 hddLog(LOGE, FL("nla put fail"));
7844 kfree_skb(skb);
7845 return -EINVAL;
7846 }
7847 if (adapter->con_status)
7848 nla_put_flag(skb, AP_LINK_ACTIVE);
7849 if (adapter->dad)
7850 nla_put_flag(skb, AP_LINK_DAD);
7851
7852 cfg80211_vendor_cmd_reply(skb);
7853 return err;
7854}
7855
7856static int wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
7857 struct wireless_dev *wdev,
7858 const void *data, int data_len)
7859{
7860 int ret;
7861
7862 vos_ssr_protect(__func__);
7863 ret = __wlan_hdd_cfg80211_get_nud_stats(wiphy, wdev, data, data_len);
7864 vos_ssr_unprotect(__func__);
7865
7866 return ret;
7867}
7868
7869#undef QCA_ATTR_NUD_STATS_SET_INVALID
7870#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
7871#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
7872#undef QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
7873#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
7874#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
7875#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
7876#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
7877#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
7878#undef QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
7879#undef QCA_ATTR_NUD_STATS_GET_MAX
7880
7881
7882
Kapil Guptaee33bf12016-12-20 18:27:37 +05307883#ifdef WLAN_FEATURE_APFIND
7884/**
7885 * __wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
7886 * @wiphy: pointer to wireless wiphy structure.
7887 * @wdev: pointer to wireless_dev structure.
7888 * @data: pointer to apfind configuration data.
7889 * @data_len: the length in byte of apfind data.
7890 *
7891 * This is called when wlan driver needs to send APFIND configurations to
7892 * firmware.
7893 *
7894 * Return: An error code or 0 on success.
7895 */
7896static int __wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
7897 struct wireless_dev *wdev,
7898 const void *data, int data_len)
7899{
7900 struct sme_ap_find_request_req apfind_req;
7901 VOS_STATUS status;
7902 int ret_val;
7903 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7904
7905 ENTER();
7906
7907 ret_val = wlan_hdd_validate_context(hdd_ctx);
7908 if (ret_val)
7909 return ret_val;
7910
7911 if (VOS_FTM_MODE == hdd_get_conparam()) {
7912 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7913 return -EPERM;
7914 }
7915
7916 apfind_req.request_data_len = data_len;
7917 apfind_req.request_data = data;
7918
7919 status = sme_apfind_set_cmd(&apfind_req);
7920 if (VOS_STATUS_SUCCESS != status) {
7921 ret_val = -EIO;
7922 }
7923 return ret_val;
7924}
7925
7926/**
7927 * wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
7928 * @wiphy: pointer to wireless wiphy structure.
7929 * @wdev: pointer to wireless_dev structure.
7930 * @data: pointer to apfind configuration data.
7931 * @data_len: the length in byte of apfind data.
7932 *
7933 * This is called when wlan driver needs to send APFIND configurations to
7934 * firmware.
7935 *
7936 * Return: An error code or 0 on success.
7937 */
7938static int wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
7939 struct wireless_dev *wdev,
7940 const void *data, int data_len)
7941{
7942 int ret;
7943
7944 vos_ssr_protect(__func__);
7945 ret = __wlan_hdd_cfg80211_apfind_cmd(wiphy, wdev, data, data_len);
7946 vos_ssr_unprotect(__func__);
7947
7948 return ret;
7949}
7950#endif /* WLAN_FEATURE_APFIND */
Sunil Duttc69bccb2014-05-26 21:30:20 +05307951const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
7952{
Mukul Sharma2a271632014-10-13 14:59:01 +05307953 {
7954 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7955 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
7956 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7957 WIPHY_VENDOR_CMD_NEED_NETDEV |
7958 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307959 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05307960 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05307961
7962 {
7963 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7964 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
7965 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7966 WIPHY_VENDOR_CMD_NEED_NETDEV |
7967 WIPHY_VENDOR_CMD_NEED_RUNNING,
7968 .doit = wlan_hdd_cfg80211_nan_request
7969 },
7970
Sunil Duttc69bccb2014-05-26 21:30:20 +05307971#ifdef WLAN_FEATURE_LINK_LAYER_STATS
7972 {
7973 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7974 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
7975 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7976 WIPHY_VENDOR_CMD_NEED_NETDEV |
7977 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307978 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05307979 },
7980
7981 {
7982 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7983 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
7984 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7985 WIPHY_VENDOR_CMD_NEED_NETDEV |
7986 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307987 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05307988 },
7989
7990 {
7991 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7992 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
7993 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7994 WIPHY_VENDOR_CMD_NEED_NETDEV |
7995 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307996 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05307997 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05307998#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05307999#ifdef WLAN_FEATURE_EXTSCAN
8000 {
8001 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8002 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
8003 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8004 WIPHY_VENDOR_CMD_NEED_NETDEV |
8005 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308006 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05308007 },
8008 {
8009 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8010 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
8011 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8012 WIPHY_VENDOR_CMD_NEED_NETDEV |
8013 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308014 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05308015 },
8016 {
8017 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8018 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
8019 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8020 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308021 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05308022 },
8023 {
8024 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8025 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
8026 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8027 WIPHY_VENDOR_CMD_NEED_NETDEV |
8028 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308029 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05308030 },
8031 {
8032 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8033 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
8034 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8035 WIPHY_VENDOR_CMD_NEED_NETDEV |
8036 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308037 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05308038 },
8039 {
8040 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8041 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
8042 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8043 WIPHY_VENDOR_CMD_NEED_NETDEV |
8044 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308045 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308046 },
8047 {
8048 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8049 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
8050 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8051 WIPHY_VENDOR_CMD_NEED_NETDEV |
8052 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308053 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308054 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308055#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308056/*EXT TDLS*/
8057 {
8058 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8059 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
8060 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8061 WIPHY_VENDOR_CMD_NEED_NETDEV |
8062 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308063 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05308064 },
8065 {
8066 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8067 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
8068 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8069 WIPHY_VENDOR_CMD_NEED_NETDEV |
8070 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308071 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05308072 },
8073 {
8074 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8075 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
8076 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8077 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308078 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05308079 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05308080 {
8081 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8082 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
8083 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8084 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308085 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05308086 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05308087 {
8088 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8089 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
8090 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8091 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308092 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05308093 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308094 {
8095 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8096 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
8097 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8098 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308099 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308100 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308101 {
8102 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8103 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
8104 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8105 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308106 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308107 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308108 {
8109 .info.vendor_id = QCA_NL80211_VENDOR_ID,
c_manjeecfd1efb2015-09-25 19:32:34 +05308110 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
8111 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8112 WIPHY_VENDOR_CMD_NEED_NETDEV |
8113 WIPHY_VENDOR_CMD_NEED_RUNNING,
8114 .doit = wlan_hdd_cfg80211_get_fw_mem_dump
8115 },
8116 {
8117 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308118 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
8119 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8120 WIPHY_VENDOR_CMD_NEED_NETDEV |
8121 WIPHY_VENDOR_CMD_NEED_RUNNING,
8122 .doit = wlan_hdd_cfg80211_setband
Sushant Kaushik8e644982015-09-23 12:18:54 +05308123 },
8124 {
8125 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8126 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
8127 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8128 WIPHY_VENDOR_CMD_NEED_NETDEV,
8129 .doit = wlan_hdd_cfg80211_wifi_logger_start
8130 },
Sushant Kaushik847890c2015-09-28 16:05:17 +05308131 {
8132 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8133 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
8134 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8135 WIPHY_VENDOR_CMD_NEED_NETDEV|
8136 WIPHY_VENDOR_CMD_NEED_RUNNING,
8137 .doit = wlan_hdd_cfg80211_get_wifi_info
Sachin Ahujac08f72a2015-09-22 15:25:47 +05308138 },
8139 {
8140 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8141 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
8142 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8143 WIPHY_VENDOR_CMD_NEED_NETDEV |
8144 WIPHY_VENDOR_CMD_NEED_RUNNING,
8145 .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308146 },
8147 {
8148 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8149 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,
8150 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8151 WIPHY_VENDOR_CMD_NEED_NETDEV |
8152 WIPHY_VENDOR_CMD_NEED_RUNNING,
8153 .doit = wlan_hdd_cfg80211_monitor_rssi
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308154 },
8155#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
8156 {
8157 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8158 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS,
8159 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8160 WIPHY_VENDOR_CMD_NEED_NETDEV |
8161 WIPHY_VENDOR_CMD_NEED_RUNNING,
8162 .doit = wlan_hdd_cfg80211_offloaded_packets
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308163 },
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308164#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308165 {
8166 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8167 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
8168 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8169 WIPHY_VENDOR_CMD_NEED_NETDEV |
8170 WIPHY_VENDOR_CMD_NEED_RUNNING,
8171 .doit = wlan_hdd_cfg80211_get_link_properties
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05308172 },
8173 {
8174 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8175 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION,
8176 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8177 WIPHY_VENDOR_CMD_NEED_NETDEV |
8178 WIPHY_VENDOR_CMD_NEED_RUNNING,
8179 .doit = wlan_hdd_cfg80211_wifi_configuration_set
Kapil Guptaee33bf12016-12-20 18:27:37 +05308180 },
8181#ifdef WLAN_FEATURE_APFIND
8182 {
8183 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8184 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_APFIND,
8185 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8186 WIPHY_VENDOR_CMD_NEED_NETDEV,
8187 .doit = wlan_hdd_cfg80211_apfind_cmd
8188 },
8189#endif /* WLAN_FEATURE_APFIND */
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308190 {
8191 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8192 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET,
8193 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8194 WIPHY_VENDOR_CMD_NEED_NETDEV |
8195 WIPHY_VENDOR_CMD_NEED_RUNNING,
8196 .doit = wlan_hdd_cfg80211_set_nud_stats
8197 },
8198 {
8199 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8200 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8201 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8202 WIPHY_VENDOR_CMD_NEED_NETDEV |
8203 WIPHY_VENDOR_CMD_NEED_RUNNING,
8204 .doit = wlan_hdd_cfg80211_get_nud_stats
8205 },
Anurag Chouhanfcd20172017-07-19 17:25:19 +05308206 {
8207 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8208 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_STATION,
8209 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8210 WIPHY_VENDOR_CMD_NEED_NETDEV |
8211 WIPHY_VENDOR_CMD_NEED_RUNNING,
8212 .doit = hdd_cfg80211_get_station_cmd
8213 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308214};
8215
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008216/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05308217static const
8218struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008219{
8220#ifdef FEATURE_WLAN_CH_AVOID
8221 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05308222 .vendor_id = QCA_NL80211_VENDOR_ID,
8223 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008224 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308225#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
8226#ifdef WLAN_FEATURE_LINK_LAYER_STATS
8227 {
8228 /* Index = 1*/
8229 .vendor_id = QCA_NL80211_VENDOR_ID,
8230 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
8231 },
8232 {
8233 /* Index = 2*/
8234 .vendor_id = QCA_NL80211_VENDOR_ID,
8235 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
8236 },
8237 {
8238 /* Index = 3*/
8239 .vendor_id = QCA_NL80211_VENDOR_ID,
8240 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
8241 },
8242 {
8243 /* Index = 4*/
8244 .vendor_id = QCA_NL80211_VENDOR_ID,
8245 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
8246 },
8247 {
8248 /* Index = 5*/
8249 .vendor_id = QCA_NL80211_VENDOR_ID,
8250 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
8251 },
8252 {
8253 /* Index = 6*/
8254 .vendor_id = QCA_NL80211_VENDOR_ID,
8255 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
8256 },
8257#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308258#ifdef WLAN_FEATURE_EXTSCAN
8259 {
8260 .vendor_id = QCA_NL80211_VENDOR_ID,
8261 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
8262 },
8263 {
8264 .vendor_id = QCA_NL80211_VENDOR_ID,
8265 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
8266 },
8267 {
8268 .vendor_id = QCA_NL80211_VENDOR_ID,
8269 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
8270 },
8271 {
8272 .vendor_id = QCA_NL80211_VENDOR_ID,
8273 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
8274 },
8275 {
8276 .vendor_id = QCA_NL80211_VENDOR_ID,
8277 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
8278 },
8279 {
8280 .vendor_id = QCA_NL80211_VENDOR_ID,
8281 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
8282 },
8283 {
8284 .vendor_id = QCA_NL80211_VENDOR_ID,
8285 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
8286 },
8287 {
8288 .vendor_id = QCA_NL80211_VENDOR_ID,
8289 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
8290 },
8291 {
8292 .vendor_id = QCA_NL80211_VENDOR_ID,
8293 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
8294 },
8295 {
8296 .vendor_id = QCA_NL80211_VENDOR_ID,
8297 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
8298 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308299#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308300/*EXT TDLS*/
8301 {
8302 .vendor_id = QCA_NL80211_VENDOR_ID,
8303 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
8304 },
c_manjeecfd1efb2015-09-25 19:32:34 +05308305 [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
8306 .vendor_id = QCA_NL80211_VENDOR_ID,
8307 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
8308 },
8309
Srinivas Dasari030bad32015-02-18 23:23:54 +05308310
Srinivas Dasaribd1cf642017-01-23 14:54:41 +05308311 [QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX] = {
Srinivas Dasari030bad32015-02-18 23:23:54 +05308312 .vendor_id = QCA_NL80211_VENDOR_ID,
8313 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
8314 },
8315
Sushant Kaushik084f6592015-09-10 13:11:56 +05308316 {
8317 .vendor_id = QCA_NL80211_VENDOR_ID,
8318 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308319 },
8320 [QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = {
8321 .vendor_id = QCA_NL80211_VENDOR_ID,
8322 .subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI
8323 },
Padma, Santhosh Kumar7bbc7d92015-12-08 20:23:19 +05308324 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX] = {
8325 .vendor_id = QCA_NL80211_VENDOR_ID,
8326 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST
8327 },
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308328 [QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET_INDEX] = {
8329 .vendor_id = QCA_NL80211_VENDOR_ID,
8330 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8331 },
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008332};
8333
Jeff Johnson295189b2012-06-20 16:38:30 -07008334/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308335 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308336 * This function is called by hdd_wlan_startup()
8337 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308338 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07008339 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308340struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07008341{
8342 struct wiphy *wiphy;
8343 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308344 /*
8345 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07008346 */
8347 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
8348
8349 if (!wiphy)
8350 {
8351 /* Print error and jump into err label and free the memory */
8352 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
8353 return NULL;
8354 }
8355
Sunil Duttc69bccb2014-05-26 21:30:20 +05308356
Jeff Johnson295189b2012-06-20 16:38:30 -07008357 return wiphy;
8358}
8359
Anurag Chouhan343af7e2016-12-16 13:11:19 +05308360#if (LINUX_VERSION_CODE > KERNEL_VERSION(4,4,0)) || \
8361 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
8362/**
8363 * hdd_config_sched_scan_plans_to_wiphy() - configure sched scan plans to wiphy
8364 * @wiphy: pointer to wiphy
8365 * @config: pointer to config
8366 *
8367 * Return: None
8368 */
8369static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
8370 hdd_config_t *config)
8371{
8372 wiphy->max_sched_scan_plans = MAX_SCHED_SCAN_PLANS;
8373 if (config->max_sched_scan_plan_interval)
8374 wiphy->max_sched_scan_plan_interval =
8375 config->max_sched_scan_plan_interval;
8376 if (config->max_sched_scan_plan_iterations)
8377 wiphy->max_sched_scan_plan_iterations =
8378 config->max_sched_scan_plan_iterations;
8379}
8380#else
8381static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
8382 hdd_config_t *config)
8383{
8384}
8385#endif
8386
Jeff Johnson295189b2012-06-20 16:38:30 -07008387/*
8388 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308389 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07008390 * private ioctl to change the band value
8391 */
8392int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
8393{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308394 int i, j;
8395 eNVChannelEnabledType channelEnabledState;
8396
Jeff Johnsone7245742012-09-05 17:12:55 -07008397 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308398
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308399 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07008400 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308401
8402 if (NULL == wiphy->bands[i])
8403 {
8404 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
8405 __func__, i);
8406 continue;
8407 }
8408
8409 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
8410 {
8411 struct ieee80211_supported_band *band = wiphy->bands[i];
8412
8413 channelEnabledState = vos_nv_getChannelEnabledState(
8414 band->channels[j].hw_value);
8415
8416 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
8417 {
Abhishek Singh678227a2014-11-04 10:52:38 +05308418 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308419 continue;
8420 }
8421 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
8422 {
8423 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8424 continue;
8425 }
8426
8427 if (NV_CHANNEL_DISABLE == channelEnabledState ||
8428 NV_CHANNEL_INVALID == channelEnabledState)
8429 {
8430 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8431 }
8432 else if (NV_CHANNEL_DFS == channelEnabledState)
8433 {
8434 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
8435 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
8436 }
8437 else
8438 {
8439 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
8440 |IEEE80211_CHAN_RADAR);
8441 }
8442 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008443 }
8444 return 0;
8445}
8446/*
8447 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308448 * This function is called by hdd_wlan_startup()
8449 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07008450 * This function is used to initialize and register wiphy structure.
8451 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308452int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07008453 struct wiphy *wiphy,
8454 hdd_config_t *pCfg
8455 )
8456{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308457 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05308458 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
8459
Jeff Johnsone7245742012-09-05 17:12:55 -07008460 ENTER();
8461
Jeff Johnson295189b2012-06-20 16:38:30 -07008462 /* Now bind the underlying wlan device with wiphy */
8463 set_wiphy_dev(wiphy, dev);
8464
8465 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07008466
Kiet Lam6c583332013-10-14 05:37:09 +05308467#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07008468 /* the flag for the other case would be initialzed in
8469 vos_init_wiphy_from_nv_bin */
Manjeet Singh9e19de62016-08-18 18:26:41 +05308470#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
8471 wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
8472#else
Amar Singhal0a402232013-10-11 20:57:16 -07008473 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05308474#endif
Manjeet Singh9e19de62016-08-18 18:26:41 +05308475#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07008476
Amar Singhalfddc28c2013-09-05 13:03:40 -07008477 /* This will disable updating of NL channels from passive to
8478 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308479#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
8480 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
8481#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07008482 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308483#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07008484
Amar Singhala49cbc52013-10-08 18:37:44 -07008485
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008486#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07008487 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
8488 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
8489 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07008490 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308491#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Rajeev Kumar Sirasanagandla0d6dd752016-08-17 15:01:39 +05308492 wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308493#else
8494 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
8495#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008496#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07008497
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08008498#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07008499 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08008500#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07008501 || pCfg->isFastRoamIniFeatureEnabled
8502#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08008503#ifdef FEATURE_WLAN_ESE
8504 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07008505#endif
8506 )
8507 {
8508 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
8509 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08008510#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008511#ifdef FEATURE_WLAN_TDLS
8512 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
8513 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
8514#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308515#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05308516 if (pCfg->configPNOScanSupport)
8517 {
8518 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
8519 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
8520 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
8521 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
8522 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308523#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008524
Abhishek Singh10d85972015-04-17 10:27:23 +05308525#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
8526 wiphy->features |= NL80211_FEATURE_HT_IBSS;
8527#endif
8528
Amar Singhalfddc28c2013-09-05 13:03:40 -07008529#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07008530 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
8531 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07008532 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07008533 driver need to determine what to do with both
8534 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07008535
8536 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07008537#else
8538 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07008539#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008540
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308541 wiphy->max_scan_ssids = MAX_SCAN_SSID;
8542
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05308543 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07008544
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308545 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
8546
Jeff Johnson295189b2012-06-20 16:38:30 -07008547 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05308548 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
8549 | BIT(NL80211_IFTYPE_ADHOC)
8550 | BIT(NL80211_IFTYPE_P2P_CLIENT)
8551 | BIT(NL80211_IFTYPE_P2P_GO)
8552 | BIT(NL80211_IFTYPE_AP);
8553
8554 if (VOS_MONITOR_MODE == hdd_get_conparam())
8555 {
8556 wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
8557 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008558
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308559 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008560 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308561#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
8562 if( pCfg->enableMCC )
8563 {
8564 /* Currently, supports up to two channels */
8565 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008566
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308567 if( !pCfg->allowMCCGODiffBI )
8568 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008569
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308570 }
8571 wiphy->iface_combinations = &wlan_hdd_iface_combination;
8572 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008573#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308574 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008575
Jeff Johnson295189b2012-06-20 16:38:30 -07008576 /* Before registering we need to update the ht capabilitied based
8577 * on ini values*/
8578 if( !pCfg->ShortGI20MhzEnable )
8579 {
8580 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
8581 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
Jeff Johnson295189b2012-06-20 16:38:30 -07008582 }
8583
8584 if( !pCfg->ShortGI40MhzEnable )
8585 {
8586 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
8587 }
8588
8589 if( !pCfg->nChannelBondingMode5GHz )
8590 {
8591 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
8592 }
Agrawal Ashish97dec502015-11-26 20:20:58 +05308593 /*
8594 * In case of static linked driver at the time of driver unload,
8595 * module exit doesn't happens. Module cleanup helps in cleaning
8596 * of static memory.
8597 * If driver load happens statically, at the time of driver unload,
8598 * wiphy flags don't get reset because of static memory.
8599 * It's better not to store channel in static memory.
8600 */
8601 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
8602 wiphy->bands[IEEE80211_BAND_2GHZ]->channels =
8603 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_2_4_GHZ));
8604 if (wiphy->bands[IEEE80211_BAND_2GHZ]->channels == NULL)
8605 {
8606 hddLog(VOS_TRACE_LEVEL_ERROR,
8607 FL("Not enough memory to allocate channels"));
8608 return -ENOMEM;
8609 }
8610 vos_mem_copy(wiphy->bands[IEEE80211_BAND_2GHZ]->channels,
8611 &hdd_channels_2_4_GHZ[0],
8612 sizeof(hdd_channels_2_4_GHZ));
Jeff Johnson295189b2012-06-20 16:38:30 -07008613
Agrawal Ashish97dec502015-11-26 20:20:58 +05308614 if (true == hdd_is_5g_supported(pHddCtx))
8615 {
8616 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
8617 wiphy->bands[IEEE80211_BAND_5GHZ]->channels =
8618 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_5_GHZ));
8619 if (wiphy->bands[IEEE80211_BAND_5GHZ]->channels == NULL)
8620 {
8621 hddLog(VOS_TRACE_LEVEL_ERROR,
8622 FL("Not enough memory to allocate channels"));
8623 vos_mem_free(wiphy->bands[IEEE80211_BAND_2GHZ]->channels);
8624 wiphy->bands[IEEE80211_BAND_2GHZ]->channels = NULL;
8625 return -ENOMEM;
8626 }
8627 vos_mem_copy(wiphy->bands[IEEE80211_BAND_5GHZ]->channels,
8628 &hdd_channels_5_GHZ[0],
8629 sizeof(hdd_channels_5_GHZ));
8630 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308631
8632 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
8633 {
8634
8635 if (NULL == wiphy->bands[i])
8636 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05308637 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308638 __func__, i);
8639 continue;
8640 }
8641
8642 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
8643 {
8644 struct ieee80211_supported_band *band = wiphy->bands[i];
8645
8646 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
8647 {
8648 // Enable social channels for P2P
8649 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
8650 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
8651 else
8652 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8653 continue;
8654 }
8655 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
8656 {
8657 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8658 continue;
8659 }
8660 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008661 }
8662 /*Initialise the supported cipher suite details*/
8663 wiphy->cipher_suites = hdd_cipher_suites;
8664 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
8665
8666 /*signal strength in mBm (100*dBm) */
8667 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
8668
8669#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05308670 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07008671#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008672
Sunil Duttc69bccb2014-05-26 21:30:20 +05308673 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
8674 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008675 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
8676 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
8677
Anurag Chouhan343af7e2016-12-16 13:11:19 +05308678 hdd_config_sched_scan_plans_to_wiphy(wiphy, pCfg);
8679
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308680 EXIT();
8681 return 0;
8682}
8683
8684/* In this function we are registering wiphy. */
8685int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
8686{
8687 ENTER();
8688 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008689 if (0 > wiphy_register(wiphy))
8690 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308691 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07008692 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8693 return -EIO;
8694 }
8695
8696 EXIT();
8697 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308698}
Jeff Johnson295189b2012-06-20 16:38:30 -07008699
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308700/* In this function we are updating channel list when,
8701 regulatory domain is FCC and country code is US.
8702 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
8703 As per FCC smart phone is not a indoor device.
8704 GO should not opeate on indoor channels */
8705void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
8706{
8707 int j;
8708 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
8709 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
8710 //Default counrtycode from NV at the time of wiphy initialization.
8711 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
8712 &defaultCountryCode[0]))
8713 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008714 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308715 }
8716 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
8717 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308718 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
8719 {
8720 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
8721 return;
8722 }
8723 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
8724 {
8725 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
8726 // Mark UNII -1 band channel as passive
8727 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
8728 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
8729 }
8730 }
8731}
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05308732/* This function registers for all frame which supplicant is interested in */
8733void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008734{
Jeff Johnson295189b2012-06-20 16:38:30 -07008735 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8736 /* Register for all P2P action, public action etc frames */
8737 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
Jeff Johnsone7245742012-09-05 17:12:55 -07008738 ENTER();
Abhishek Singh16e05762015-11-30 14:29:27 +05308739 /* Register frame indication call back */
8740 sme_register_mgmt_frame_ind_callback(hHal, hdd_indicate_mgmt_frame);
Jeff Johnson295189b2012-06-20 16:38:30 -07008741 /* Right now we are registering these frame when driver is getting
8742 initialized. Once we will move to 2.6.37 kernel, in which we have
8743 frame register ops, we will move this code as a part of that */
8744 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308745 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07008746 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
8747
8748 /* GAS Initial Response */
8749 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8750 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308751
Jeff Johnson295189b2012-06-20 16:38:30 -07008752 /* GAS Comeback Request */
8753 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8754 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
8755
8756 /* GAS Comeback Response */
8757 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8758 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
8759
8760 /* P2P Public Action */
8761 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308762 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07008763 P2P_PUBLIC_ACTION_FRAME_SIZE );
8764
8765 /* P2P Action */
8766 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8767 (v_U8_t*)P2P_ACTION_FRAME,
8768 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07008769
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05308770 /* WNM BSS Transition Request frame */
8771 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8772 (v_U8_t*)WNM_BSS_ACTION_FRAME,
8773 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07008774
8775 /* WNM-Notification */
8776 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8777 (v_U8_t*)WNM_NOTIFICATION_FRAME,
8778 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008779}
8780
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05308781void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008782{
Jeff Johnson295189b2012-06-20 16:38:30 -07008783 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8784 /* Register for all P2P action, public action etc frames */
8785 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
8786
Jeff Johnsone7245742012-09-05 17:12:55 -07008787 ENTER();
8788
Jeff Johnson295189b2012-06-20 16:38:30 -07008789 /* Right now we are registering these frame when driver is getting
8790 initialized. Once we will move to 2.6.37 kernel, in which we have
8791 frame register ops, we will move this code as a part of that */
8792 /* GAS Initial Request */
8793
8794 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8795 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
8796
8797 /* GAS Initial Response */
8798 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8799 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308800
Jeff Johnson295189b2012-06-20 16:38:30 -07008801 /* GAS Comeback Request */
8802 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8803 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
8804
8805 /* GAS Comeback Response */
8806 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8807 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
8808
8809 /* P2P Public Action */
8810 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308811 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07008812 P2P_PUBLIC_ACTION_FRAME_SIZE );
8813
8814 /* P2P Action */
8815 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8816 (v_U8_t*)P2P_ACTION_FRAME,
8817 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07008818 /* WNM-Notification */
8819 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8820 (v_U8_t*)WNM_NOTIFICATION_FRAME,
8821 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008822}
8823
8824#ifdef FEATURE_WLAN_WAPI
8825void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05308826 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07008827{
8828 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8829 tCsrRoamSetKey setKey;
8830 v_BOOL_t isConnected = TRUE;
8831 int status = 0;
8832 v_U32_t roamId= 0xFF;
8833 tANI_U8 *pKeyPtr = NULL;
8834 int n = 0;
8835
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308836 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
8837 __func__, hdd_device_modetoString(pAdapter->device_mode),
8838 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008839
Gopichand Nakkalae7480202013-02-11 15:24:22 +05308840 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07008841 setKey.keyId = key_index; // Store Key ID
8842 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
8843 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
8844 setKey.paeRole = 0 ; // the PAE role
8845 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
8846 {
8847 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
8848 }
8849 else
8850 {
8851 isConnected = hdd_connIsConnected(pHddStaCtx);
8852 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
8853 }
8854 setKey.keyLength = key_Len;
8855 pKeyPtr = setKey.Key;
8856 memcpy( pKeyPtr, key, key_Len);
8857
Arif Hussain6d2a3322013-11-17 19:50:10 -08008858 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07008859 __func__, key_Len);
8860 for (n = 0 ; n < key_Len; n++)
8861 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
8862 __func__,n,setKey.Key[n]);
8863
8864 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8865 if ( isConnected )
8866 {
8867 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8868 pAdapter->sessionId, &setKey, &roamId );
8869 }
8870 if ( status != 0 )
8871 {
8872 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8873 "[%4d] sme_RoamSetKey returned ERROR status= %d",
8874 __LINE__, status );
8875 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8876 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308877 /* Need to clear any trace of key value in the memory.
8878 * Thus zero out the memory even though it is local
8879 * variable.
8880 */
8881 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07008882}
8883#endif /* FEATURE_WLAN_WAPI*/
8884
8885#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308886int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07008887 beacon_data_t **ppBeacon,
8888 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008889#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308890int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008891 beacon_data_t **ppBeacon,
8892 struct cfg80211_beacon_data *params,
8893 int dtim_period)
8894#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308895{
Jeff Johnson295189b2012-06-20 16:38:30 -07008896 int size;
8897 beacon_data_t *beacon = NULL;
8898 beacon_data_t *old = NULL;
Kapil Gupta137ef892016-12-13 19:38:00 +05308899 int head_len, tail_len, proberesp_ies_len, assocresp_ies_len;
8900 const u8 *head, *tail, *proberesp_ies, *assocresp_ies;
Jeff Johnson295189b2012-06-20 16:38:30 -07008901
Jeff Johnsone7245742012-09-05 17:12:55 -07008902 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008903 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308904 {
8905 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8906 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008907 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308908 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008909
8910 old = pAdapter->sessionCtx.ap.beacon;
8911
8912 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308913 {
8914 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8915 FL("session(%d) old and new heads points to NULL"),
8916 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008917 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308918 }
8919
8920 if (params->tail && !params->tail_len)
8921 {
8922 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8923 FL("tail_len is zero but tail is not NULL"));
8924 return -EINVAL;
8925 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008926
Jeff Johnson295189b2012-06-20 16:38:30 -07008927#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
8928 /* Kernel 3.0 is not updating dtim_period for set beacon */
8929 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308930 {
8931 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8932 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008933 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308934 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008935#endif
8936
Kapil Gupta137ef892016-12-13 19:38:00 +05308937 if (params->head)
8938 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008939 head_len = params->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05308940 head = params->head;
8941 } else
8942 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008943 head_len = old->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05308944 head = old->head;
8945 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008946
Kapil Gupta137ef892016-12-13 19:38:00 +05308947 if (params->tail || !old)
8948 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008949 tail_len = params->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05308950 tail = params->tail;
8951 } else
8952 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008953 tail_len = old->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05308954 tail = old->tail;
8955 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008956
Kapil Gupta137ef892016-12-13 19:38:00 +05308957 if (params->proberesp_ies || !old)
8958 {
8959 proberesp_ies_len = params->proberesp_ies_len;
8960 proberesp_ies = params->proberesp_ies;
8961 } else
8962 {
8963 proberesp_ies_len = old->proberesp_ies_len;
8964 proberesp_ies = old->proberesp_ies;
8965 }
8966
8967 if (params->assocresp_ies || !old)
8968 {
8969 assocresp_ies_len = params->assocresp_ies_len;
8970 assocresp_ies = params->assocresp_ies;
8971 } else
8972 {
8973 assocresp_ies_len = old->assocresp_ies_len;
8974 assocresp_ies = old->assocresp_ies;
8975 }
8976
8977 size = sizeof(beacon_data_t) + head_len + tail_len +
8978 proberesp_ies_len + assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07008979
8980 beacon = kzalloc(size, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07008981 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308982 {
8983 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8984 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008985 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308986 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008987
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008988#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Kapil Gupta137ef892016-12-13 19:38:00 +05308989 if (params->dtim_period)
Jeff Johnson295189b2012-06-20 16:38:30 -07008990 beacon->dtim_period = params->dtim_period;
8991 else
8992 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008993#else
Kapil Gupta137ef892016-12-13 19:38:00 +05308994 if (dtim_period)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008995 beacon->dtim_period = dtim_period;
8996 else
8997 beacon->dtim_period = old->dtim_period;
8998#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308999
Jeff Johnson295189b2012-06-20 16:38:30 -07009000 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
9001 beacon->tail = beacon->head + head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309002 beacon->proberesp_ies = beacon->tail + tail_len;
9003 beacon->assocresp_ies = beacon->proberesp_ies + proberesp_ies_len;
9004
Jeff Johnson295189b2012-06-20 16:38:30 -07009005 beacon->head_len = head_len;
9006 beacon->tail_len = tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309007 beacon->proberesp_ies_len = proberesp_ies_len;
9008 beacon->assocresp_ies_len= assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009009
c_manjee527ecac2017-01-25 12:25:27 +05309010 if (head && head_len)
9011 memcpy(beacon->head, head, head_len);
9012 if (tail && tail_len)
9013 memcpy(beacon->tail, tail, tail_len);
9014 if (proberesp_ies && proberesp_ies_len)
9015 memcpy(beacon->proberesp_ies, proberesp_ies, proberesp_ies_len);
9016 if (assocresp_ies && assocresp_ies_len)
9017 memcpy(beacon->assocresp_ies, assocresp_ies, assocresp_ies_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009018
9019 *ppBeacon = beacon;
9020
9021 kfree(old);
9022
9023 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009024}
Jeff Johnson295189b2012-06-20 16:38:30 -07009025
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309026v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
9027#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
9028 const v_U8_t *pIes,
9029#else
9030 v_U8_t *pIes,
9031#endif
9032 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009033{
9034 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309035 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07009036 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309037
Jeff Johnson295189b2012-06-20 16:38:30 -07009038 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309039 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009040 elem_id = ptr[0];
9041 elem_len = ptr[1];
9042 left -= 2;
9043 if(elem_len > left)
9044 {
9045 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07009046 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009047 eid,elem_len,left);
9048 return NULL;
9049 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309050 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009051 {
9052 return ptr;
9053 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309054
Jeff Johnson295189b2012-06-20 16:38:30 -07009055 left -= elem_len;
9056 ptr += (elem_len + 2);
9057 }
9058 return NULL;
9059}
9060
Jeff Johnson295189b2012-06-20 16:38:30 -07009061/* Check if rate is 11g rate or not */
9062static int wlan_hdd_rate_is_11g(u8 rate)
9063{
Sanjay Devnani28322e22013-06-21 16:13:40 -07009064 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009065 u8 i;
9066 for (i = 0; i < 8; i++)
9067 {
9068 if(rate == gRateArray[i])
9069 return TRUE;
9070 }
9071 return FALSE;
9072}
9073
9074/* Check for 11g rate and set proper 11g only mode */
9075static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
9076 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
9077{
9078 u8 i, num_rates = pIe[0];
9079
9080 pIe += 1;
9081 for ( i = 0; i < num_rates; i++)
9082 {
9083 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
9084 {
9085 /* If rate set have 11g rate than change the mode to 11G */
9086 *pSapHw_mode = eSAP_DOT11_MODE_11g;
9087 if (pIe[i] & BASIC_RATE_MASK)
9088 {
9089 /* If we have 11g rate as basic rate, it means mode
9090 is 11g only mode.
9091 */
9092 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
9093 *pCheckRatesfor11g = FALSE;
9094 }
9095 }
9096 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
9097 {
9098 *require_ht = TRUE;
9099 }
9100 }
9101 return;
9102}
9103
9104static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
9105{
9106 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9107 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9108 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9109 u8 checkRatesfor11g = TRUE;
9110 u8 require_ht = FALSE;
9111 u8 *pIe=NULL;
9112
9113 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
9114
9115 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
9116 pBeacon->head_len, WLAN_EID_SUPP_RATES);
9117 if (pIe != NULL)
9118 {
9119 pIe += 1;
9120 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9121 &pConfig->SapHw_mode);
9122 }
9123
9124 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9125 WLAN_EID_EXT_SUPP_RATES);
9126 if (pIe != NULL)
9127 {
9128
9129 pIe += 1;
9130 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9131 &pConfig->SapHw_mode);
9132 }
9133
9134 if( pConfig->channel > 14 )
9135 {
9136 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
9137 }
9138
9139 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9140 WLAN_EID_HT_CAPABILITY);
9141
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309142 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009143 {
9144 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
9145 if(require_ht)
9146 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
9147 }
9148}
9149
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309150static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
9151 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
9152{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009153 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309154 v_U8_t *pIe = NULL;
9155 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9156
9157 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
9158 pBeacon->tail, pBeacon->tail_len);
9159
9160 if (pIe)
9161 {
9162 ielen = pIe[1] + 2;
9163 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9164 {
9165 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
9166 }
9167 else
9168 {
9169 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
9170 return -EINVAL;
9171 }
9172 *total_ielen += ielen;
9173 }
9174 return 0;
9175}
9176
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009177static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
9178 v_U8_t *genie, v_U8_t *total_ielen)
9179{
9180 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9181 int left = pBeacon->tail_len;
9182 v_U8_t *ptr = pBeacon->tail;
9183 v_U8_t elem_id, elem_len;
9184 v_U16_t ielen = 0;
9185
9186 if ( NULL == ptr || 0 == left )
9187 return;
9188
9189 while (left >= 2)
9190 {
9191 elem_id = ptr[0];
9192 elem_len = ptr[1];
9193 left -= 2;
9194 if (elem_len > left)
9195 {
9196 hddLog( VOS_TRACE_LEVEL_ERROR,
9197 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
9198 elem_id, elem_len, left);
9199 return;
9200 }
Ashish Kumar Dhanotiya6af276b2017-08-22 16:53:48 +05309201 if ((IE_EID_VENDOR == elem_id) && (elem_len >= WPS_OUI_TYPE_SIZE))
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009202 {
9203 /* skipping the VSIE's which we don't want to include or
9204 * it will be included by existing code
9205 */
9206 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
9207#ifdef WLAN_FEATURE_WFD
9208 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
9209#endif
9210 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9211 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9212 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
9213 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9214 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
9215 {
9216 ielen = ptr[1] + 2;
9217 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9218 {
9219 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
9220 *total_ielen += ielen;
9221 }
9222 else
9223 {
9224 hddLog( VOS_TRACE_LEVEL_ERROR,
9225 "IE Length is too big "
9226 "IEs eid=%d elem_len=%d total_ie_lent=%d",
9227 elem_id, elem_len, *total_ielen);
9228 }
9229 }
9230 }
9231
9232 left -= elem_len;
9233 ptr += (elem_len + 2);
9234 }
9235 return;
9236}
9237
Kapil Gupta137ef892016-12-13 19:38:00 +05309238int wlan_hdd_cfg80211_update_apies(hdd_adapter_t *pHostapdAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009239{
9240 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309241 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009242 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07009243 int ret = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +05309244 beacon_data_t *pBeacon = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009245
9246 genie = vos_mem_malloc(MAX_GENIE_LEN);
9247
9248 if(genie == NULL) {
9249
9250 return -ENOMEM;
9251 }
9252
Kapil Gupta137ef892016-12-13 19:38:00 +05309253 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309254 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9255 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009256 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309257 hddLog(LOGE,
9258 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309259 ret = -EINVAL;
9260 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009261 }
9262
9263#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309264 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9265 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
9266 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309267 hddLog(LOGE,
9268 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309269 ret = -EINVAL;
9270 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009271 }
9272#endif
9273
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309274 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9275 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009276 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309277 hddLog(LOGE,
9278 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309279 ret = -EINVAL;
9280 goto done;
9281 }
9282
9283 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
9284 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009285 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07009286 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009287
9288 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9289 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
9290 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
9291 {
9292 hddLog(LOGE,
9293 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009294 ret = -EINVAL;
9295 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009296 }
9297
9298 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9299 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
9300 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9301 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9302 ==eHAL_STATUS_FAILURE)
9303 {
9304 hddLog(LOGE,
9305 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009306 ret = -EINVAL;
9307 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009308 }
9309
9310 // Added for ProResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +05309311 if ((pBeacon->proberesp_ies != NULL) && (pBeacon->proberesp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009312 {
Kapil Gupta137ef892016-12-13 19:38:00 +05309313 u16 rem_probe_resp_ie_len = pBeacon->proberesp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009314 u8 probe_rsp_ie_len[3] = {0};
9315 u8 counter = 0;
9316 /* Check Probe Resp Length if it is greater then 255 then Store
9317 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
9318 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
9319 Store More then 255 bytes into One Variable.
9320 */
9321 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
9322 {
9323 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
9324 {
9325 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
9326 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
9327 }
9328 else
9329 {
9330 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
9331 rem_probe_resp_ie_len = 0;
9332 }
9333 }
9334
9335 rem_probe_resp_ie_len = 0;
9336
9337 if (probe_rsp_ie_len[0] > 0)
9338 {
9339 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9340 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
Kapil Gupta137ef892016-12-13 19:38:00 +05309341 (tANI_U8*)&pBeacon->
9342 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07009343 probe_rsp_ie_len[0], NULL,
9344 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9345 {
9346 hddLog(LOGE,
9347 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009348 ret = -EINVAL;
9349 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009350 }
9351 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
9352 }
9353
9354 if (probe_rsp_ie_len[1] > 0)
9355 {
9356 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9357 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
Kapil Gupta137ef892016-12-13 19:38:00 +05309358 (tANI_U8*)&pBeacon->
9359 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07009360 probe_rsp_ie_len[1], NULL,
9361 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9362 {
9363 hddLog(LOGE,
9364 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009365 ret = -EINVAL;
9366 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009367 }
9368 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
9369 }
9370
9371 if (probe_rsp_ie_len[2] > 0)
9372 {
9373 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9374 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
Kapil Gupta137ef892016-12-13 19:38:00 +05309375 (tANI_U8*)&pBeacon->
9376 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07009377 probe_rsp_ie_len[2], NULL,
9378 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9379 {
9380 hddLog(LOGE,
9381 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009382 ret = -EINVAL;
9383 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009384 }
9385 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
9386 }
9387
9388 if (probe_rsp_ie_len[1] == 0 )
9389 {
9390 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9391 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
9392 eANI_BOOLEAN_FALSE) )
9393 {
9394 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009395 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009396 }
9397 }
9398
9399 if (probe_rsp_ie_len[2] == 0 )
9400 {
9401 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9402 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
9403 eANI_BOOLEAN_FALSE) )
9404 {
9405 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009406 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009407 }
9408 }
9409
9410 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9411 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
9412 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9413 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9414 == eHAL_STATUS_FAILURE)
9415 {
9416 hddLog(LOGE,
9417 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009418 ret = -EINVAL;
9419 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009420 }
9421 }
9422 else
9423 {
9424 // Reset WNI_CFG_PROBE_RSP Flags
9425 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
9426
9427 hddLog(VOS_TRACE_LEVEL_INFO,
9428 "%s: No Probe Response IE received in set beacon",
9429 __func__);
9430 }
9431
9432 // Added for AssocResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +05309433 if ((pBeacon->assocresp_ies != NULL) && (pBeacon->assocresp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009434 {
9435 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
Kapil Gupta137ef892016-12-13 19:38:00 +05309436 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)pBeacon->assocresp_ies,
9437 pBeacon->assocresp_ies_len, NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -07009438 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9439 {
9440 hddLog(LOGE,
9441 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009442 ret = -EINVAL;
9443 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009444 }
9445
9446 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9447 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
9448 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9449 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9450 == eHAL_STATUS_FAILURE)
9451 {
9452 hddLog(LOGE,
9453 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009454 ret = -EINVAL;
9455 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009456 }
9457 }
9458 else
9459 {
9460 hddLog(VOS_TRACE_LEVEL_INFO,
9461 "%s: No Assoc Response IE received in set beacon",
9462 __func__);
9463
9464 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9465 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
9466 eANI_BOOLEAN_FALSE) )
9467 {
9468 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009469 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009470 }
9471 }
9472
Jeff Johnsone7245742012-09-05 17:12:55 -07009473done:
Jeff Johnson295189b2012-06-20 16:38:30 -07009474 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309475 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009476}
Jeff Johnson295189b2012-06-20 16:38:30 -07009477
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309478/*
Jeff Johnson295189b2012-06-20 16:38:30 -07009479 * FUNCTION: wlan_hdd_validate_operation_channel
9480 * called by wlan_hdd_cfg80211_start_bss() and
9481 * wlan_hdd_cfg80211_set_channel()
9482 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309483 * channel list.
9484 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07009485VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07009486{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309487
Jeff Johnson295189b2012-06-20 16:38:30 -07009488 v_U32_t num_ch = 0;
9489 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
9490 u32 indx = 0;
9491 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309492 v_U8_t fValidChannel = FALSE, count = 0;
9493 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309494
Jeff Johnson295189b2012-06-20 16:38:30 -07009495 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
9496
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309497 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07009498 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309499 /* Validate the channel */
9500 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07009501 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309502 if ( channel == rfChannels[count].channelNum )
9503 {
9504 fValidChannel = TRUE;
9505 break;
9506 }
9507 }
9508 if (fValidChannel != TRUE)
9509 {
9510 hddLog(VOS_TRACE_LEVEL_ERROR,
9511 "%s: Invalid Channel [%d]", __func__, channel);
9512 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009513 }
9514 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309515 else
Jeff Johnson295189b2012-06-20 16:38:30 -07009516 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309517 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
9518 valid_ch, &num_ch))
9519 {
9520 hddLog(VOS_TRACE_LEVEL_ERROR,
9521 "%s: failed to get valid channel list", __func__);
9522 return VOS_STATUS_E_FAILURE;
9523 }
9524 for (indx = 0; indx < num_ch; indx++)
9525 {
9526 if (channel == valid_ch[indx])
9527 {
9528 break;
9529 }
9530 }
9531
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05309532 if (indx >= num_ch)
9533 {
9534 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
9535 {
9536 eCsrBand band;
9537 unsigned int freq;
9538
9539 sme_GetFreqBand(hHal, &band);
9540
9541 if (eCSR_BAND_5G == band)
9542 {
9543#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
9544 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
9545 {
9546 freq = ieee80211_channel_to_frequency(channel,
9547 IEEE80211_BAND_2GHZ);
9548 }
9549 else
9550 {
9551 freq = ieee80211_channel_to_frequency(channel,
9552 IEEE80211_BAND_5GHZ);
9553 }
9554#else
9555 freq = ieee80211_channel_to_frequency(channel);
9556#endif
9557 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
9558 return VOS_STATUS_SUCCESS;
9559 }
9560 }
9561
9562 hddLog(VOS_TRACE_LEVEL_ERROR,
9563 "%s: Invalid Channel [%d]", __func__, channel);
9564 return VOS_STATUS_E_FAILURE;
9565 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009566 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05309567
Jeff Johnson295189b2012-06-20 16:38:30 -07009568 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309569
Jeff Johnson295189b2012-06-20 16:38:30 -07009570}
9571
Viral Modi3a32cc52013-02-08 11:14:52 -08009572/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309573 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08009574 * This function is used to set the channel number
9575 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309576static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08009577 struct ieee80211_channel *chan,
9578 enum nl80211_channel_type channel_type
9579 )
9580{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309581 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08009582 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07009583 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08009584 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309585 hdd_context_t *pHddCtx;
9586 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009587
9588 ENTER();
9589
9590 if( NULL == dev )
9591 {
9592 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009593 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08009594 return -ENODEV;
9595 }
9596 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309597
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309598 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9599 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
9600 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08009601 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309602 "%s: device_mode = %s (%d) freq = %d", __func__,
9603 hdd_device_modetoString(pAdapter->device_mode),
9604 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309605
9606 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9607 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309608 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08009609 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309610 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009611 }
9612
9613 /*
9614 * Do freq to chan conversion
9615 * TODO: for 11a
9616 */
9617
9618 channel = ieee80211_frequency_to_channel(freq);
9619
9620 /* Check freq range */
9621 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
9622 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
9623 {
9624 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009625 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08009626 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
9627 WNI_CFG_CURRENT_CHANNEL_STAMAX);
9628 return -EINVAL;
9629 }
9630
9631 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
9632
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05309633 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
9634 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08009635 {
9636 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
9637 {
9638 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009639 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08009640 return -EINVAL;
9641 }
9642 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
9643 "%s: set channel to [%d] for device mode =%d",
9644 __func__, channel,pAdapter->device_mode);
9645 }
9646 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08009647 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08009648 )
9649 {
9650 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9651 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
9652 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9653
9654 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
9655 {
9656 /* Link is up then return cant set channel*/
9657 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009658 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08009659 return -EINVAL;
9660 }
9661
9662 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
9663 pHddStaCtx->conn_info.operationChannel = channel;
9664 pRoamProfile->ChannelInfo.ChannelList =
9665 &pHddStaCtx->conn_info.operationChannel;
9666 }
9667 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08009668 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08009669 )
9670 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309671 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
9672 {
9673 if(VOS_STATUS_SUCCESS !=
9674 wlan_hdd_validate_operation_channel(pAdapter,channel))
9675 {
9676 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009677 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309678 return -EINVAL;
9679 }
9680 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
9681 }
9682 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08009683 {
9684 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
9685
9686 /* If auto channel selection is configured as enable/ 1 then ignore
9687 channel set by supplicant
9688 */
9689 if ( cfg_param->apAutoChannelSelection )
9690 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309691 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
9692 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08009693 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309694 "%s: set channel to auto channel (0) for device mode =%s (%d)",
9695 __func__, hdd_device_modetoString(pAdapter->device_mode),
9696 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08009697 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309698 else
9699 {
9700 if(VOS_STATUS_SUCCESS !=
9701 wlan_hdd_validate_operation_channel(pAdapter,channel))
9702 {
9703 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009704 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309705 return -EINVAL;
9706 }
9707 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
9708 }
Viral Modi3a32cc52013-02-08 11:14:52 -08009709 }
9710 }
9711 else
9712 {
9713 hddLog(VOS_TRACE_LEVEL_FATAL,
9714 "%s: Invalid device mode failed to set valid channel", __func__);
9715 return -EINVAL;
9716 }
9717 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309718 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009719}
9720
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309721static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
9722 struct net_device *dev,
9723 struct ieee80211_channel *chan,
9724 enum nl80211_channel_type channel_type
9725 )
9726{
9727 int ret;
9728
9729 vos_ssr_protect(__func__);
9730 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
9731 vos_ssr_unprotect(__func__);
9732
9733 return ret;
9734}
9735
Anurag Chouhan83026002016-12-13 22:46:21 +05309736#ifdef DHCP_SERVER_OFFLOAD
9737void hdd_dhcp_server_offload_done(void *fw_dhcp_srv_offload_cb_context,
9738 VOS_STATUS status)
9739{
9740 hdd_adapter_t* adapter = (hdd_adapter_t*)fw_dhcp_srv_offload_cb_context;
9741
9742 ENTER();
9743
9744 if (NULL == adapter)
9745 {
9746 hddLog(VOS_TRACE_LEVEL_ERROR,
9747 "%s: adapter is NULL",__func__);
9748 return;
9749 }
9750
9751 adapter->dhcp_status.dhcp_offload_status = status;
9752 vos_event_set(&adapter->dhcp_status.vos_event);
9753 return;
9754}
9755
9756/**
9757 * wlan_hdd_set_dhcp_server_offload() - set dhcp server offload
9758 * @hostapd_adapter: pointer to hostapd adapter.
Anurag Chouhan638f5e22017-03-06 12:28:43 +05309759 * @re_init: flag set if api called post ssr
Anurag Chouhan83026002016-12-13 22:46:21 +05309760 *
9761 * Return: None
9762 */
Anurag Chouhan638f5e22017-03-06 12:28:43 +05309763VOS_STATUS wlan_hdd_set_dhcp_server_offload(hdd_adapter_t *hostapd_adapter,
9764 bool re_init)
Anurag Chouhan83026002016-12-13 22:46:21 +05309765{
9766 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter);
9767 sir_dhcp_srv_offload_info dhcp_srv_info;
9768 tANI_U8 num_entries = 0;
9769 tANI_U8 srv_ip[IPADDR_NUM_ENTRIES];
9770 tANI_U8 num;
9771 tANI_U32 temp;
9772 VOS_STATUS ret;
9773
9774 ENTER();
9775
Anurag Chouhan638f5e22017-03-06 12:28:43 +05309776 if (!re_init) {
9777 ret = wlan_hdd_validate_context(hdd_ctx);
9778 if (0 != ret)
9779 return VOS_STATUS_E_INVAL;
9780 }
Anurag Chouhan83026002016-12-13 22:46:21 +05309781
9782 /* Prepare the request to send to SME */
9783 dhcp_srv_info = vos_mem_malloc(sizeof(*dhcp_srv_info));
9784 if (NULL == dhcp_srv_info) {
9785 hddLog(VOS_TRACE_LEVEL_ERROR,
9786 "%s: could not allocate tDhcpSrvOffloadInfo!", __func__);
9787 return VOS_STATUS_E_NOMEM;
9788 }
9789
9790 vos_mem_zero(dhcp_srv_info, sizeof(*dhcp_srv_info));
9791
9792 dhcp_srv_info->bssidx = hostapd_adapter->sessionId;
9793 dhcp_srv_info->dhcp_srv_offload_enabled = TRUE;
9794 dhcp_srv_info->dhcp_client_num = hdd_ctx->cfg_ini->dhcp_max_num_clients;
9795 dhcp_srv_info->start_lsb = hdd_ctx->cfg_ini->dhcp_start_lsb;
9796 dhcp_srv_info->dhcp_offload_callback = hdd_dhcp_server_offload_done;
9797 dhcp_srv_info->dhcp_server_offload_cb_context = hostapd_adapter;
9798
9799 hdd_string_to_u8_array(hdd_ctx->cfg_ini->dhcp_srv_ip,
9800 srv_ip,
9801 &num_entries,
Anurag Chouhanac145c22016-11-22 16:51:47 +05309802 IPADDR_NUM_ENTRIES, ".");
Anurag Chouhan83026002016-12-13 22:46:21 +05309803 if (num_entries != IPADDR_NUM_ENTRIES) {
9804 hddLog(VOS_TRACE_LEVEL_ERROR,
9805 "%s: incorrect IP address (%s) assigned for DHCP server!",
9806 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
9807 vos_mem_free(dhcp_srv_info);
9808 return VOS_STATUS_E_FAILURE;
9809 }
9810
9811 if ((srv_ip[0] >= 224) && (srv_ip[0] <= 239)) {
9812 hddLog(VOS_TRACE_LEVEL_ERROR,
9813 "%s: invalid IP address (%s)! It could NOT be multicast IP address!",
9814 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
9815 vos_mem_free(dhcp_srv_info);
9816 return VOS_STATUS_E_FAILURE;
9817 }
9818
9819 if (srv_ip[IPADDR_NUM_ENTRIES-1] >= DHCP_START_POOL_ADDRESS) {
9820 hddLog(VOS_TRACE_LEVEL_ERROR,
9821 "%s: invalid IP address (%s)! The last field must be less than 100!",
9822 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
9823 vos_mem_free(dhcp_srv_info);
9824 return VOS_STATUS_E_FAILURE;
9825 }
9826
9827 for (num = 0; num < num_entries; num++) {
9828 temp = srv_ip[num];
9829 dhcp_srv_info->dhcp_srv_ip |= (temp << (8 * num));
9830 }
9831
9832 if (eHAL_STATUS_SUCCESS !=
9833 sme_set_dhcp_srv_offload(hdd_ctx->hHal, dhcp_srv_info)) {
9834 hddLog(VOS_TRACE_LEVEL_ERROR,
9835 "%s: sme_set_dhcp_srv_offload fail!", __func__);
9836 vos_mem_free(dhcp_srv_info);
9837 return VOS_STATUS_E_FAILURE;
9838 }
9839
9840 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
9841 "%s: enable DHCP Server offload successfully!", __func__);
9842
9843 vos_mem_free(dhcp_srv_info);
9844 return 0;
9845}
9846#endif /* DHCP_SERVER_OFFLOAD */
9847
Jeff Johnson295189b2012-06-20 16:38:30 -07009848#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9849static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
9850 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009851#else
9852static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
9853 struct cfg80211_beacon_data *params,
9854 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309855 enum nl80211_hidden_ssid hidden_ssid,
9856 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009857#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009858{
9859 tsap_Config_t *pConfig;
9860 beacon_data_t *pBeacon = NULL;
9861 struct ieee80211_mgmt *pMgmt_frame;
9862 v_U8_t *pIe=NULL;
9863 v_U16_t capab_info;
9864 eCsrAuthType RSNAuthType;
9865 eCsrEncryptionType RSNEncryptType;
9866 eCsrEncryptionType mcRSNEncryptType;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +05309867 int status = VOS_STATUS_SUCCESS, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009868 tpWLAN_SAPEventCB pSapEventCallback;
9869 hdd_hostapd_state_t *pHostapdState;
Jeff Johnson295189b2012-06-20 16:38:30 -07009870 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309871 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009872 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309873 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07009874 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08009875 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05309876 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07009877 v_BOOL_t MFPCapable = VOS_FALSE;
9878 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309879 v_BOOL_t sapEnable11AC =
9880 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Kapil Gupta137ef892016-12-13 19:38:00 +05309881 u_int16_t prev_rsn_length = 0;
9882
Jeff Johnson295189b2012-06-20 16:38:30 -07009883 ENTER();
9884
Nitesh Shah9b066282017-06-06 18:05:52 +05309885 wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309886 iniConfig = pHddCtx->cfg_ini;
9887
Jeff Johnson295189b2012-06-20 16:38:30 -07009888 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
9889
9890 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9891
9892 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9893
9894 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9895
9896 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
9897
9898 //channel is already set in the set_channel Call back
9899 //pConfig->channel = pCommitConfig->channel;
9900
9901 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309902 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07009903 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
9904
9905 pConfig->dtim_period = pBeacon->dtim_period;
9906
Arif Hussain6d2a3322013-11-17 19:50:10 -08009907 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07009908 pConfig->dtim_period);
9909
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08009910 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07009911 {
9912 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07009913 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05309914 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
9915 {
9916 tANI_BOOLEAN restartNeeded;
9917 pConfig->ieee80211d = 1;
9918 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
9919 sme_setRegInfo(hHal, pConfig->countryCode);
9920 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
9921 }
9922 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009923 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07009924 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07009925 pConfig->ieee80211d = 1;
9926 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
9927 sme_setRegInfo(hHal, pConfig->countryCode);
9928 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07009929 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07009930 else
9931 {
9932 pConfig->ieee80211d = 0;
9933 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309934 /*
9935 * If auto channel is configured i.e. channel is 0,
9936 * so skip channel validation.
9937 */
9938 if( AUTO_CHANNEL_SELECT != pConfig->channel )
9939 {
9940 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
9941 {
9942 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009943 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309944 return -EINVAL;
9945 }
9946 }
9947 else
9948 {
9949 if(1 != pHddCtx->is_dynamic_channel_range_set)
9950 {
9951 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
9952 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
9953 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
9954 }
9955 pHddCtx->is_dynamic_channel_range_set = 0;
9956 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009957 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07009958 else
Jeff Johnson295189b2012-06-20 16:38:30 -07009959 {
9960 pConfig->ieee80211d = 0;
9961 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309962
9963#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9964 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
9965 pConfig->authType = eSAP_OPEN_SYSTEM;
9966 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
9967 pConfig->authType = eSAP_SHARED_KEY;
9968 else
9969 pConfig->authType = eSAP_AUTO_SWITCH;
9970#else
9971 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
9972 pConfig->authType = eSAP_OPEN_SYSTEM;
9973 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
9974 pConfig->authType = eSAP_SHARED_KEY;
9975 else
9976 pConfig->authType = eSAP_AUTO_SWITCH;
9977#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009978
9979 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309980
9981 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07009982 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
Agrawal Ashisha8e8a722016-10-18 19:07:45 +05309983#ifdef SAP_AUTH_OFFLOAD
9984 /* In case of sap offload, hostapd.conf is configuted with open mode and
9985 * security is configured from ini file. Due to open mode in hostapd.conf
9986 * privacy bit is set to false which will result in not sending,
9987 * data packets as encrypted.
9988 * If enable_sap_auth_offload is enabled in ini and
9989 * sap_auth_offload_sec_type is type of WPA2-PSK,
9990 * driver will set privacy bit to 1.
9991 */
9992 if (pHddCtx->cfg_ini->enable_sap_auth_offload &&
9993 pHddCtx->cfg_ini->sap_auth_offload_sec_type)
9994 pConfig->privacy = VOS_TRUE;
9995#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009996
9997 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
9998
9999 /*Set wps station to configured*/
10000 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
10001
10002 if(pIe)
10003 {
10004 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
10005 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010006 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -070010007 return -EINVAL;
10008 }
10009 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
10010 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -070010011 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -070010012 /* Check 15 bit of WPS IE as it contain information for wps state
10013 * WPS state
10014 */
10015 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
10016 {
10017 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
10018 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
10019 {
10020 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
10021 }
10022 }
10023 }
10024 else
10025 {
10026 pConfig->wps_state = SAP_WPS_DISABLED;
10027 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010028 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -070010029
c_hpothufe599e92014-06-16 11:38:55 +053010030 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
10031 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
10032 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
10033 eCSR_ENCRYPT_TYPE_NONE;
10034
Jeff Johnson295189b2012-06-20 16:38:30 -070010035 pConfig->RSNWPAReqIELength = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +053010036 memset(&pConfig->RSNWPAReqIE[0], 0, sizeof(pConfig->RSNWPAReqIE));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010037 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070010038 WLAN_EID_RSN);
10039 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010040 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010041 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053010042 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
10043 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
10044 pConfig->RSNWPAReqIELength);
10045 else
10046 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
10047 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010048 /* The actual processing may eventually be more extensive than
10049 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -070010050 * by the app.
10051 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010052 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070010053 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
10054 &RSNEncryptType,
10055 &mcRSNEncryptType,
10056 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080010057 &MFPCapable,
10058 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053010059 pConfig->RSNWPAReqIE[1]+2,
10060 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010061
10062 if( VOS_STATUS_SUCCESS == status )
10063 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010064 /* Now copy over all the security attributes you have
10065 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070010066 * */
10067 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
10068 pConfig->mcRSNEncryptType = mcRSNEncryptType;
10069 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
10070 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010071 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080010072 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070010073 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
10074 }
10075 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010076
Jeff Johnson295189b2012-06-20 16:38:30 -070010077 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
10078 pBeacon->tail, pBeacon->tail_len);
10079
10080 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
10081 {
Kapil Gupta137ef892016-12-13 19:38:00 +053010082 if (pConfig->RSNWPAReqIE[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070010083 {
10084 /*Mixed mode WPA/WPA2*/
Kapil Gupta137ef892016-12-13 19:38:00 +053010085 prev_rsn_length = pConfig->RSNWPAReqIELength;
Jeff Johnson295189b2012-06-20 16:38:30 -070010086 pConfig->RSNWPAReqIELength += pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053010087 if (pConfig->RSNWPAReqIELength <=
10088 (sizeof(pConfig->RSNWPAReqIE) - prev_rsn_length))
10089 memcpy(&pConfig->RSNWPAReqIE[0] + prev_rsn_length, pIe,
10090 pIe[1] + 2);
10091 else
10092 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
10093 pConfig->RSNWPAReqIELength);
10094
Jeff Johnson295189b2012-06-20 16:38:30 -070010095 }
10096 else
10097 {
10098 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053010099 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
10100 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
10101 pConfig->RSNWPAReqIELength);
10102 else
10103 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
10104 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010105 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070010106 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
10107 &RSNEncryptType,
10108 &mcRSNEncryptType,
10109 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080010110 &MFPCapable,
10111 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053010112 pConfig->RSNWPAReqIE[1]+2,
10113 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010114
10115 if( VOS_STATUS_SUCCESS == status )
10116 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010117 /* Now copy over all the security attributes you have
10118 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070010119 * */
10120 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
10121 pConfig->mcRSNEncryptType = mcRSNEncryptType;
10122 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
10123 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010124 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080010125 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070010126 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
10127 }
10128 }
10129 }
10130
Kapil Gupta137ef892016-12-13 19:38:00 +053010131 if (pConfig->RSNWPAReqIELength > sizeof(pConfig->RSNWPAReqIE)) {
Jeff Johnson4416a782013-03-25 14:17:50 -070010132 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
10133 return -EINVAL;
10134 }
10135
Jeff Johnson295189b2012-06-20 16:38:30 -070010136 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
10137
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010138#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010139 if (params->ssid != NULL)
10140 {
10141 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
10142 pConfig->SSIDinfo.ssid.length = params->ssid_len;
10143 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
10144 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
10145 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010146#else
10147 if (ssid != NULL)
10148 {
10149 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
10150 pConfig->SSIDinfo.ssid.length = ssid_len;
10151 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
10152 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
10153 }
10154#endif
10155
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010156 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -070010157 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010158
Jeff Johnson295189b2012-06-20 16:38:30 -070010159 /* default value */
10160 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
10161 pConfig->num_accept_mac = 0;
10162 pConfig->num_deny_mac = 0;
10163
10164 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
10165 pBeacon->tail, pBeacon->tail_len);
10166
10167 /* pIe for black list is following form:
10168 type : 1 byte
10169 length : 1 byte
10170 OUI : 4 bytes
10171 acl type : 1 byte
10172 no of mac addr in black list: 1 byte
10173 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010174 */
10175 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010176 {
10177 pConfig->SapMacaddr_acl = pIe[6];
10178 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080010179 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010180 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053010181 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
10182 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010183 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
10184 for (i = 0; i < pConfig->num_deny_mac; i++)
10185 {
10186 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
10187 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010188 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010189 }
10190 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
10191 pBeacon->tail, pBeacon->tail_len);
10192
10193 /* pIe for white list is following form:
10194 type : 1 byte
10195 length : 1 byte
10196 OUI : 4 bytes
10197 acl type : 1 byte
10198 no of mac addr in white list: 1 byte
10199 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010200 */
10201 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010202 {
10203 pConfig->SapMacaddr_acl = pIe[6];
10204 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080010205 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010206 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053010207 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
10208 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010209 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
10210 for (i = 0; i < pConfig->num_accept_mac; i++)
10211 {
10212 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
10213 acl_entry++;
10214 }
10215 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053010216
Jeff Johnson295189b2012-06-20 16:38:30 -070010217 wlan_hdd_set_sapHwmode(pHostapdAdapter);
10218
Jeff Johnsone7245742012-09-05 17:12:55 -070010219#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080010220 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +053010221 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
10222 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +053010223 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
10224 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080010225 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
10226 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +053010227 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
10228 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -070010229 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053010230 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -070010231 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +053010232 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070010233
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010234 /* If ACS disable and selected channel <= 14
10235 * OR
10236 * ACS enabled and ACS operating band is choosen as 2.4
10237 * AND
10238 * VHT in 2.4G Disabled
10239 * THEN
10240 * Fallback to 11N mode
10241 */
10242 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
10243 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +053010244 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010245 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -070010246 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053010247 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
10248 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070010249 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
10250 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010251 }
10252#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010253
Jeff Johnson295189b2012-06-20 16:38:30 -070010254 // ht_capab is not what the name conveys,this is used for protection bitmap
10255 pConfig->ht_capab =
10256 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
10257
Kapil Gupta137ef892016-12-13 19:38:00 +053010258 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -070010259 {
10260 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
10261 return -EINVAL;
10262 }
10263
10264 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010265 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -070010266 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
10267 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010268 pConfig->obssProtEnabled =
10269 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -070010270
Chet Lanctot8cecea22014-02-11 19:09:36 -080010271#ifdef WLAN_FEATURE_11W
10272 pConfig->mfpCapable = MFPCapable;
10273 pConfig->mfpRequired = MFPRequired;
10274 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
10275 pConfig->mfpCapable, pConfig->mfpRequired);
10276#endif
10277
Arif Hussain6d2a3322013-11-17 19:50:10 -080010278 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -070010279 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -080010280 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
10281 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
10282 (int)pConfig->channel);
10283 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
10284 pConfig->SapHw_mode, pConfig->privacy,
10285 pConfig->authType);
10286 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
10287 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
10288 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
10289 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -070010290
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010291 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -070010292 {
10293 //Bss already started. just return.
10294 //TODO Probably it should update some beacon params.
10295 hddLog( LOGE, "Bss Already started...Ignore the request");
10296 EXIT();
10297 return 0;
10298 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010299
Agarwal Ashish51325b52014-06-16 16:50:49 +053010300 if (vos_max_concurrent_connections_reached()) {
10301 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10302 return -EINVAL;
10303 }
10304
Jeff Johnson295189b2012-06-20 16:38:30 -070010305 pConfig->persona = pHostapdAdapter->device_mode;
10306
Peng Xu2446a892014-09-05 17:21:18 +053010307 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
10308 if ( NULL != psmeConfig)
10309 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053010310 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +053010311 sme_GetConfigParam(hHal, psmeConfig);
10312 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053010313#ifdef WLAN_FEATURE_AP_HT40_24G
10314 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
10315 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
10316 && pHddCtx->cfg_ini->apHT40_24GEnabled)
10317 {
10318 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
10319 sme_UpdateConfig (hHal, psmeConfig);
10320 }
10321#endif
Peng Xu2446a892014-09-05 17:21:18 +053010322 vos_mem_free(psmeConfig);
10323 }
Peng Xuafc34e32014-09-25 13:23:55 +053010324 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +053010325
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010326 set_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
10327
Jeff Johnson295189b2012-06-20 16:38:30 -070010328 pSapEventCallback = hdd_hostapd_SAPEventCB;
10329 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
10330 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
10331 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010332 hddLog(LOGE,FL("SAP Start Bss fail"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010333 ret = -EINVAL;
10334 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070010335 }
10336
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010337 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -070010338 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
10339
10340 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010341
Jeff Johnson295189b2012-06-20 16:38:30 -070010342 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010343 {
10344 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010345 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -070010346 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070010347 VOS_ASSERT(0);
10348 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010349
Jeff Johnson295189b2012-06-20 16:38:30 -070010350 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053010351 if (WLANSAP_get_sessionId(pVosContext, &pHostapdAdapter->sessionId) !=
10352 VOS_STATUS_SUCCESS)
10353 {
10354 hddLog(LOGE,FL("Fail to get Softap sessionID"));
10355 VOS_ASSERT(0);
10356 }
Kaushik, Sushantf6070802014-10-15 15:09:23 +053010357 /* Initialize WMM configuation */
10358 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010359 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010360
Anurag Chouhan83026002016-12-13 22:46:21 +053010361#ifdef DHCP_SERVER_OFFLOAD
10362 /* set dhcp server offload */
10363 if (iniConfig->enable_dhcp_srv_offload &&
10364 sme_IsFeatureSupportedByFW(SAP_OFFLOADS)) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010365 vos_event_reset(&pHostapdAdapter->dhcp_status.vos_event);
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010366 status = wlan_hdd_set_dhcp_server_offload(pHostapdAdapter, false);
Anurag Chouhan83026002016-12-13 22:46:21 +053010367 if (!VOS_IS_STATUS_SUCCESS(status))
10368 {
10369 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10370 ("HDD DHCP Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010371 vos_event_reset(&pHostapdState->vosEvent);
10372 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
10373 status = vos_wait_single_event(&pHostapdState->vosEvent,
10374 10000);
10375 if (!VOS_IS_STATUS_SUCCESS(status)) {
10376 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010377 ret = -EINVAL;
10378 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010379 }
10380 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010381 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010382 status = vos_wait_single_event(&pHostapdAdapter->dhcp_status.vos_event, 2000);
10383 if (!VOS_IS_STATUS_SUCCESS(status) || pHostapdAdapter->dhcp_status.dhcp_offload_status)
10384 {
10385 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10386 ("ERROR: DHCP HDD vos wait for single_event failed!! %d"),
10387 pHostapdAdapter->dhcp_status.dhcp_offload_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010388 vos_event_reset(&pHostapdState->vosEvent);
10389 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
10390 status = vos_wait_single_event(&pHostapdState->vosEvent,
10391 10000);
10392 if (!VOS_IS_STATUS_SUCCESS(status)) {
10393 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010394 ret = -EINVAL;
10395 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010396 }
10397 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010398 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010399#ifdef MDNS_OFFLOAD
10400 if (iniConfig->enable_mdns_offload) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010401 vos_event_reset(&pHostapdAdapter->mdns_status.vos_event);
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010402 status = wlan_hdd_set_mdns_offload(pHostapdAdapter);
10403 if (VOS_IS_STATUS_SUCCESS(status))
10404 {
10405 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10406 ("HDD MDNS Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010407 vos_event_reset(&pHostapdState->vosEvent);
10408 if (VOS_STATUS_SUCCESS ==
10409 WLANSAP_StopBss(pHddCtx->pvosContext)) {
10410 status = vos_wait_single_event(&pHostapdState->vosEvent,
10411 10000);
10412 if (!VOS_IS_STATUS_SUCCESS(status)) {
10413 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010414 ret = -EINVAL;
10415 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010416 }
10417 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010418 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010419 status = vos_wait_single_event(&pHostapdAdapter->
10420 mdns_status.vos_event, 2000);
10421 if (!VOS_IS_STATUS_SUCCESS(status) ||
10422 pHostapdAdapter->mdns_status.mdns_enable_status ||
10423 pHostapdAdapter->mdns_status.mdns_fqdn_status ||
10424 pHostapdAdapter->mdns_status.mdns_resp_status)
10425 {
10426 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10427 ("MDNS HDD vos wait for single_event failed!! enable %d fqdn %d resp %d"),
10428 pHostapdAdapter->mdns_status.mdns_enable_status,
10429 pHostapdAdapter->mdns_status.mdns_fqdn_status,
10430 pHostapdAdapter->mdns_status.mdns_resp_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010431 vos_event_reset(&pHostapdState->vosEvent);
10432 if (VOS_STATUS_SUCCESS ==
10433 WLANSAP_StopBss(pHddCtx->pvosContext)) {
10434 status = vos_wait_single_event(&pHostapdState->vosEvent,
10435 10000);
10436 if (!VOS_IS_STATUS_SUCCESS(status)) {
10437 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010438 ret = -EINVAL;
10439 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010440 }
10441 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010442 }
10443 }
10444#endif /* MDNS_OFFLOAD */
10445 } else {
10446 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10447 ("DHCP Disabled ini %d, FW %d"),
10448 iniConfig->enable_dhcp_srv_offload,
10449 sme_IsFeatureSupportedByFW(SAP_OFFLOADS));
Anurag Chouhan83026002016-12-13 22:46:21 +053010450 }
10451#endif /* DHCP_SERVER_OFFLOAD */
10452
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010453#ifdef WLAN_FEATURE_P2P_DEBUG
10454 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
10455 {
10456 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
10457 {
10458 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
10459 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -080010460 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010461 }
10462 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
10463 {
10464 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
10465 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -080010466 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010467 }
10468 }
10469#endif
Ashish Kumar Dhanotiya42aa5152017-01-03 20:25:57 +053010470 /* Check and restart SAP if it is on Unsafe channel */
10471 hdd_check_for_unsafe_ch(pHostapdAdapter, pHddCtx);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010472
Jeff Johnson295189b2012-06-20 16:38:30 -070010473 pHostapdState->bCommit = TRUE;
10474 EXIT();
10475
10476 return 0;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010477error:
10478 clear_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
10479 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010480}
10481
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010482#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010483static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010484 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070010485 struct beacon_parameters *params)
10486{
10487 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010488 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010489 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010490
10491 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010492
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010493 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10494 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
10495 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010496 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
10497 hdd_device_modetoString(pAdapter->device_mode),
10498 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010499
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010500 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10501 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010502 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010503 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010504 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010505 }
10506
Agarwal Ashish51325b52014-06-16 16:50:49 +053010507 if (vos_max_concurrent_connections_reached()) {
10508 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10509 return -EINVAL;
10510 }
10511
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010512 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010513 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070010514 )
10515 {
10516 beacon_data_t *old,*new;
10517
10518 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010519
Jeff Johnson295189b2012-06-20 16:38:30 -070010520 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010521 {
10522 hddLog(VOS_TRACE_LEVEL_WARN,
10523 FL("already beacon info added to session(%d)"),
10524 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070010525 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010526 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010527
10528 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
10529
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010530 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -070010531 {
10532 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010533 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010534 return -EINVAL;
10535 }
10536
10537 pAdapter->sessionCtx.ap.beacon = new;
10538
10539 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
10540 }
10541
10542 EXIT();
10543 return status;
10544}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010545
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010546static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
10547 struct net_device *dev,
10548 struct beacon_parameters *params)
10549{
10550 int ret;
10551
10552 vos_ssr_protect(__func__);
10553 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
10554 vos_ssr_unprotect(__func__);
10555
10556 return ret;
10557}
10558
10559static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010560 struct net_device *dev,
10561 struct beacon_parameters *params)
10562{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010563 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010564 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10565 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010566 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010567
10568 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010569
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010570 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10571 TRACE_CODE_HDD_CFG80211_SET_BEACON,
10572 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
10573 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10574 __func__, hdd_device_modetoString(pAdapter->device_mode),
10575 pAdapter->device_mode);
10576
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010577 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10578 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010579 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010580 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010581 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010582 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010583
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010584 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010585 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010586 )
Jeff Johnson295189b2012-06-20 16:38:30 -070010587 {
10588 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010589
Jeff Johnson295189b2012-06-20 16:38:30 -070010590 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010591
Jeff Johnson295189b2012-06-20 16:38:30 -070010592 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010593 {
10594 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10595 FL("session(%d) old and new heads points to NULL"),
10596 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070010597 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010598 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010599
10600 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
10601
10602 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010603 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010604 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010605 return -EINVAL;
10606 }
10607
10608 pAdapter->sessionCtx.ap.beacon = new;
10609
10610 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
10611 }
10612
10613 EXIT();
10614 return status;
10615}
10616
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010617static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
10618 struct net_device *dev,
10619 struct beacon_parameters *params)
10620{
10621 int ret;
10622
10623 vos_ssr_protect(__func__);
10624 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
10625 vos_ssr_unprotect(__func__);
10626
10627 return ret;
10628}
10629
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010630#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10631
10632#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010633static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010634 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010635#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010636static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010637 struct net_device *dev)
10638#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010639{
10640 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -070010641 hdd_context_t *pHddCtx = NULL;
10642 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010643 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010644 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010645
10646 ENTER();
10647
10648 if (NULL == pAdapter)
10649 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010650 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010651 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010652 return -ENODEV;
10653 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010654
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010655 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10656 TRACE_CODE_HDD_CFG80211_STOP_AP,
10657 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010658 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10659 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010660 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010661 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010662 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -070010663 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010664
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010665 pScanInfo = &pHddCtx->scan_info;
10666
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010667 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10668 __func__, hdd_device_modetoString(pAdapter->device_mode),
10669 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010670
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010671 ret = wlan_hdd_scan_abort(pAdapter);
10672
Girish Gowli4bf7a632014-06-12 13:42:11 +053010673 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -070010674 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010675 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10676 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010677
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010678 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -070010679 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010680 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10681 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -080010682
Jeff Johnsone7245742012-09-05 17:12:55 -070010683 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010684 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -070010685 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010686 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070010687 }
10688
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010689 /* Delete all associated STAs before stopping AP/P2P GO */
10690 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +053010691 hdd_hostapd_stop(dev);
10692
Jeff Johnson295189b2012-06-20 16:38:30 -070010693 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010694 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070010695 )
10696 {
10697 beacon_data_t *old;
10698
10699 old = pAdapter->sessionCtx.ap.beacon;
10700
10701 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010702 {
10703 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10704 FL("session(%d) beacon data points to NULL"),
10705 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070010706 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010707 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010708
Jeff Johnson295189b2012-06-20 16:38:30 -070010709 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010710
10711 mutex_lock(&pHddCtx->sap_lock);
10712 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
10713 {
Jeff Johnson4416a782013-03-25 14:17:50 -070010714 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -070010715 {
10716 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
10717
10718 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
10719
10720 if (!VOS_IS_STATUS_SUCCESS(status))
10721 {
10722 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010723 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -070010724 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010725 }
10726 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010727 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010728 /* BSS stopped, clear the active sessions for this device mode */
10729 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010730 }
10731 mutex_unlock(&pHddCtx->sap_lock);
10732
10733 if(status != VOS_STATUS_SUCCESS)
10734 {
10735 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010736 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010737 return -EINVAL;
10738 }
10739
Jeff Johnson4416a782013-03-25 14:17:50 -070010740 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070010741 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
10742 ==eHAL_STATUS_FAILURE)
10743 {
10744 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010745 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010746 }
10747
Jeff Johnson4416a782013-03-25 14:17:50 -070010748 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070010749 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
10750 eANI_BOOLEAN_FALSE) )
10751 {
10752 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010753 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010754 }
10755
10756 // Reset WNI_CFG_PROBE_RSP Flags
10757 wlan_hdd_reset_prob_rspies(pAdapter);
10758
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010759 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
10760
Jeff Johnson295189b2012-06-20 16:38:30 -070010761 pAdapter->sessionCtx.ap.beacon = NULL;
10762 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010763#ifdef WLAN_FEATURE_P2P_DEBUG
10764 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
10765 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
10766 {
10767 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
10768 "GO got removed");
10769 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
10770 }
10771#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010772 }
10773 EXIT();
10774 return status;
10775}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010776
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010777#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10778static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
10779 struct net_device *dev)
10780{
10781 int ret;
10782
10783 vos_ssr_protect(__func__);
10784 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
10785 vos_ssr_unprotect(__func__);
10786
10787 return ret;
10788}
10789#else
10790static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
10791 struct net_device *dev)
10792{
10793 int ret;
10794
10795 vos_ssr_protect(__func__);
10796 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
10797 vos_ssr_unprotect(__func__);
10798
10799 return ret;
10800}
10801#endif
10802
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010803#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
10804
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010805static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010806 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010807 struct cfg80211_ap_settings *params)
10808{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010809 hdd_adapter_t *pAdapter;
10810 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010811 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010812
10813 ENTER();
10814
Girish Gowlib143d7a2015-02-18 19:39:55 +053010815 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010816 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010817 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +053010818 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010819 return -ENODEV;
10820 }
10821
10822 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
10823 if (NULL == pAdapter)
10824 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010825 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010826 "%s: HDD adapter is Null", __func__);
10827 return -ENODEV;
10828 }
10829
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010830 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10831 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
10832 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010833 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
10834 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010835 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010836 "%s: HDD adapter magic is invalid", __func__);
10837 return -ENODEV;
10838 }
10839
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010840 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
10841
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010842 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010843 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010844 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010845 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010846 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010847 }
10848
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010849 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
10850 __func__, hdd_device_modetoString(pAdapter->device_mode),
10851 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010852
10853 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010854 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010855 )
10856 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010857 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010858
10859 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010860
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010861 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010862 {
10863 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
10864 FL("already beacon info added to session(%d)"),
10865 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010866 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010867 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010868
Girish Gowlib143d7a2015-02-18 19:39:55 +053010869#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10870 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
10871 &new,
10872 &params->beacon);
10873#else
10874 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
10875 &new,
10876 &params->beacon,
10877 params->dtim_period);
10878#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010879
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010880 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010881 {
10882 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010883 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010884 return -EINVAL;
10885 }
10886 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -080010887#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -070010888 wlan_hdd_cfg80211_set_channel(wiphy, dev,
10889#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
10890 params->channel, params->channel_type);
10891#else
10892 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
10893#endif
Viral Modi3a32cc52013-02-08 11:14:52 -080010894#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010895 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010896 params->ssid_len, params->hidden_ssid,
10897 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010898 }
10899
10900 EXIT();
10901 return status;
10902}
10903
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010904static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
10905 struct net_device *dev,
10906 struct cfg80211_ap_settings *params)
10907{
10908 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010909
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010910 vos_ssr_protect(__func__);
10911 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
10912 vos_ssr_unprotect(__func__);
10913
10914 return ret;
10915}
10916
10917static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010918 struct net_device *dev,
10919 struct cfg80211_beacon_data *params)
10920{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010921 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010922 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010923 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010924
10925 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010926
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010927 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10928 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
10929 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -080010930 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010931 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010932
10933 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10934 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010935 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010936 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010937 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010938 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010939
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010940 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010941 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010942 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010943 {
10944 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010945
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010946 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010947
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010948 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010949 {
10950 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10951 FL("session(%d) beacon data points to NULL"),
10952 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010953 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010954 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010955
10956 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
10957
10958 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010959 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010960 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010961 return -EINVAL;
10962 }
10963
10964 pAdapter->sessionCtx.ap.beacon = new;
10965
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010966 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
10967 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010968 }
10969
10970 EXIT();
10971 return status;
10972}
10973
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010974static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
10975 struct net_device *dev,
10976 struct cfg80211_beacon_data *params)
10977{
10978 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010979
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010980 vos_ssr_protect(__func__);
10981 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
10982 vos_ssr_unprotect(__func__);
10983
10984 return ret;
10985}
10986
10987#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010988
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010989static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010990 struct net_device *dev,
10991 struct bss_parameters *params)
10992{
10993 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010994 hdd_context_t *pHddCtx;
10995 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010996
10997 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010998
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010999 if (NULL == pAdapter)
11000 {
11001 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11002 "%s: HDD adapter is Null", __func__);
11003 return -ENODEV;
11004 }
11005 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011006 ret = wlan_hdd_validate_context(pHddCtx);
11007 if (0 != ret)
11008 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011009 return ret;
11010 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011011 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11012 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
11013 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011014 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11015 __func__, hdd_device_modetoString(pAdapter->device_mode),
11016 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011017
11018 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011019 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011020 )
Jeff Johnson295189b2012-06-20 16:38:30 -070011021 {
11022 /* ap_isolate == -1 means that in change bss, upper layer doesn't
11023 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011024 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -070011025 {
11026 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011027 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011028 }
11029
11030 EXIT();
11031 return 0;
11032}
11033
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011034static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
11035 struct net_device *dev,
11036 struct bss_parameters *params)
11037{
11038 int ret;
11039
11040 vos_ssr_protect(__func__);
11041 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
11042 vos_ssr_unprotect(__func__);
11043
11044 return ret;
11045}
Kiet Lam10841362013-11-01 11:36:50 +053011046/* FUNCTION: wlan_hdd_change_country_code_cd
11047* to wait for contry code completion
11048*/
11049void* wlan_hdd_change_country_code_cb(void *pAdapter)
11050{
11051 hdd_adapter_t *call_back_pAdapter = pAdapter;
11052 complete(&call_back_pAdapter->change_country_code);
11053 return NULL;
11054}
11055
Jeff Johnson295189b2012-06-20 16:38:30 -070011056/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053011057 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -070011058 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
11059 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053011060int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011061 struct net_device *ndev,
11062 enum nl80211_iftype type,
11063 u32 *flags,
11064 struct vif_params *params
11065 )
11066{
11067 struct wireless_dev *wdev;
11068 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011069 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -070011070 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011071 tCsrRoamProfile *pRoamProfile = NULL;
11072 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011073 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011074 eMib_dot11DesiredBssType connectedBssType;
11075 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011076 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011077
11078 ENTER();
11079
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011080 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011081 {
11082 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11083 "%s: Adapter context is null", __func__);
11084 return VOS_STATUS_E_FAILURE;
11085 }
11086
11087 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11088 if (!pHddCtx)
11089 {
11090 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11091 "%s: HDD context is null", __func__);
11092 return VOS_STATUS_E_FAILURE;
11093 }
11094
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011095 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11096 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
11097 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011098 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011099 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011100 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011101 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011102 }
11103
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011104 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11105 __func__, hdd_device_modetoString(pAdapter->device_mode),
11106 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011107
Agarwal Ashish51325b52014-06-16 16:50:49 +053011108 if (vos_max_concurrent_connections_reached()) {
11109 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11110 return -EINVAL;
11111 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011112 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070011113 wdev = ndev->ieee80211_ptr;
11114
11115#ifdef WLAN_BTAMP_FEATURE
11116 if((NL80211_IFTYPE_P2P_CLIENT == type)||
11117 (NL80211_IFTYPE_ADHOC == type)||
11118 (NL80211_IFTYPE_AP == type)||
11119 (NL80211_IFTYPE_P2P_GO == type))
11120 {
11121 pHddCtx->isAmpAllowed = VOS_FALSE;
11122 // stop AMP traffic
11123 status = WLANBAP_StopAmp();
11124 if(VOS_STATUS_SUCCESS != status )
11125 {
11126 pHddCtx->isAmpAllowed = VOS_TRUE;
11127 hddLog(VOS_TRACE_LEVEL_FATAL,
11128 "%s: Failed to stop AMP", __func__);
11129 return -EINVAL;
11130 }
11131 }
11132#endif //WLAN_BTAMP_FEATURE
11133 /* Reset the current device mode bit mask*/
11134 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
11135
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +053011136 if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
11137 ((type == NL80211_IFTYPE_P2P_CLIENT) ||
11138 (type == NL80211_IFTYPE_P2P_GO)))
11139 {
11140 /* Notify Mode change in case of concurrency.
11141 * Below function invokes TDLS teardown Functionality Since TDLS is
11142 * not Supported in case of concurrency i.e Once P2P session
11143 * is detected disable offchannel and teardown TDLS links
11144 */
11145 hddLog(LOG1,
11146 FL("Device mode = %d Interface type = %d"),
11147 pAdapter->device_mode, type);
11148 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
11149 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +053011150
Jeff Johnson295189b2012-06-20 16:38:30 -070011151 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070011152 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -070011153 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -070011154 )
11155 {
11156 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011157 if (!pWextState)
11158 {
11159 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11160 "%s: pWextState is null", __func__);
11161 return VOS_STATUS_E_FAILURE;
11162 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011163 pRoamProfile = &pWextState->roamProfile;
11164 LastBSSType = pRoamProfile->BSSType;
11165
11166 switch (type)
11167 {
11168 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070011169 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070011170 hddLog(VOS_TRACE_LEVEL_INFO,
11171 "%s: setting interface Type to INFRASTRUCTURE", __func__);
11172 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -070011173#ifdef WLAN_FEATURE_11AC
11174 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
11175 {
11176 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
11177 }
11178#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011179 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -070011180 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011181 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080011182 //Check for sub-string p2p to confirm its a p2p interface
11183 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011184 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +053011185#ifdef FEATURE_WLAN_TDLS
11186 mutex_lock(&pHddCtx->tdls_lock);
11187 wlan_hdd_tdls_exit(pAdapter, TRUE);
11188 mutex_unlock(&pHddCtx->tdls_lock);
11189#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -080011190 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
11191 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
11192 }
11193 else
11194 {
11195 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070011196 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080011197 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011198 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +053011199
Jeff Johnson295189b2012-06-20 16:38:30 -070011200 case NL80211_IFTYPE_ADHOC:
11201 hddLog(VOS_TRACE_LEVEL_INFO,
11202 "%s: setting interface Type to ADHOC", __func__);
11203 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
11204 pRoamProfile->phyMode =
11205 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -070011206 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011207 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +053011208 hdd_set_ibss_ops( pAdapter );
11209 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +053011210
11211 status = hdd_sta_id_hash_attach(pAdapter);
11212 if (VOS_STATUS_SUCCESS != status) {
11213 hddLog(VOS_TRACE_LEVEL_ERROR,
11214 FL("Failed to initialize hash for IBSS"));
11215 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011216 break;
11217
11218 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070011219 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070011220 {
11221 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
11222 "%s: setting interface Type to %s", __func__,
11223 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
11224
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080011225 //Cancel any remain on channel for GO mode
11226 if (NL80211_IFTYPE_P2P_GO == type)
11227 {
11228 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
11229 }
Mohit Khanna0f232092012-09-11 14:46:08 -070011230 if (NL80211_IFTYPE_AP == type)
11231 {
11232 /* As Loading WLAN Driver one interface being created for p2p device
11233 * address. This will take one HW STA and the max number of clients
11234 * that can connect to softAP will be reduced by one. so while changing
11235 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
11236 * interface as it is not required in SoftAP mode.
11237 */
11238
11239 // Get P2P Adapter
11240 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
11241
11242 if (pP2pAdapter)
11243 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053011244 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +053011245 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -070011246 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
11247 }
11248 }
Swaroop Goltia2e32212014-04-09 23:37:33 +053011249 //Disable IMPS & BMPS for SAP/GO
11250 if(VOS_STATUS_E_FAILURE ==
11251 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
11252 {
11253 //Fail to Exit BMPS
11254 VOS_ASSERT(0);
11255 }
Deepthi Gowri500fc472014-08-11 19:53:10 +053011256
11257 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
11258
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011259#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -070011260
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011261 /* A Mutex Lock is introduced while changing the mode to
11262 * protect the concurrent access for the Adapters by TDLS
11263 * module.
11264 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011265 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011266#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011267 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +053011268 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011269 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -070011270 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
11271 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011272#ifdef FEATURE_WLAN_TDLS
11273 mutex_unlock(&pHddCtx->tdls_lock);
11274#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070011275 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
11276 (pConfig->apRandomBssidEnabled))
11277 {
11278 /* To meet Android requirements create a randomized
11279 MAC address of the form 02:1A:11:Fx:xx:xx */
11280 get_random_bytes(&ndev->dev_addr[3], 3);
11281 ndev->dev_addr[0] = 0x02;
11282 ndev->dev_addr[1] = 0x1A;
11283 ndev->dev_addr[2] = 0x11;
11284 ndev->dev_addr[3] |= 0xF0;
11285 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
11286 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -080011287 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
11288 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070011289 }
11290
Jeff Johnson295189b2012-06-20 16:38:30 -070011291 hdd_set_ap_ops( pAdapter->dev );
11292
Kiet Lam10841362013-11-01 11:36:50 +053011293 /* This is for only SAP mode where users can
11294 * control country through ini.
11295 * P2P GO follows station country code
11296 * acquired during the STA scanning. */
11297 if((NL80211_IFTYPE_AP == type) &&
11298 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
11299 {
11300 int status = 0;
11301 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
11302 "%s: setting country code from INI ", __func__);
11303 init_completion(&pAdapter->change_country_code);
11304 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
11305 (void *)(tSmeChangeCountryCallback)
11306 wlan_hdd_change_country_code_cb,
11307 pConfig->apCntryCode, pAdapter,
11308 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053011309 eSIR_FALSE,
11310 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +053011311 if (eHAL_STATUS_SUCCESS == status)
11312 {
11313 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011314 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +053011315 &pAdapter->change_country_code,
11316 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011317 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +053011318 {
11319 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011320 FL("SME Timed out while setting country code %ld"),
11321 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -080011322
11323 if (pHddCtx->isLogpInProgress)
11324 {
11325 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11326 "%s: LOGP in Progress. Ignore!!!", __func__);
11327 return -EAGAIN;
11328 }
Kiet Lam10841362013-11-01 11:36:50 +053011329 }
11330 }
11331 else
11332 {
11333 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011334 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +053011335 return -EINVAL;
11336 }
11337 }
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +053011338 status = hdd_init_ap_mode(pAdapter, false);
Jeff Johnson295189b2012-06-20 16:38:30 -070011339 if(status != VOS_STATUS_SUCCESS)
11340 {
11341 hddLog(VOS_TRACE_LEVEL_FATAL,
11342 "%s: Error initializing the ap mode", __func__);
11343 return -EINVAL;
11344 }
11345 hdd_set_conparam(1);
11346
Nirav Shah7e3c8132015-06-22 23:51:42 +053011347 status = hdd_sta_id_hash_attach(pAdapter);
11348 if (VOS_STATUS_SUCCESS != status)
11349 {
11350 hddLog(VOS_TRACE_LEVEL_ERROR,
11351 FL("Failed to initialize hash for AP"));
11352 return -EINVAL;
11353 }
11354
Jeff Johnson295189b2012-06-20 16:38:30 -070011355 /*interface type changed update in wiphy structure*/
11356 if(wdev)
11357 {
11358 wdev->iftype = type;
11359 pHddCtx->change_iface = type;
11360 }
11361 else
11362 {
11363 hddLog(VOS_TRACE_LEVEL_ERROR,
11364 "%s: ERROR !!!! Wireless dev is NULL", __func__);
11365 return -EINVAL;
11366 }
11367 goto done;
11368 }
11369
11370 default:
11371 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
11372 __func__);
11373 return -EOPNOTSUPP;
11374 }
11375 }
11376 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011377 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011378 )
11379 {
11380 switch(type)
11381 {
11382 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070011383 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070011384 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +053011385
11386 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011387#ifdef FEATURE_WLAN_TDLS
11388
11389 /* A Mutex Lock is introduced while changing the mode to
11390 * protect the concurrent access for the Adapters by TDLS
11391 * module.
11392 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011393 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011394#endif
c_hpothu002231a2015-02-05 14:58:51 +053011395 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011396 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080011397 //Check for sub-string p2p to confirm its a p2p interface
11398 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -080011399 {
11400 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
11401 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
11402 }
11403 else
11404 {
11405 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070011406 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080011407 }
Agrawal Ashishcfe83282016-09-29 13:03:45 +053011408
11409 /* set con_mode to STA only when no SAP concurrency mode */
11410 if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO)))
11411 hdd_set_conparam(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070011412 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070011413 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
11414 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011415#ifdef FEATURE_WLAN_TDLS
11416 mutex_unlock(&pHddCtx->tdls_lock);
11417#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +053011418 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -070011419 if( VOS_STATUS_SUCCESS != status )
11420 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -070011421 /* In case of JB, for P2P-GO, only change interface will be called,
11422 * This is the right place to enable back bmps_imps()
11423 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053011424 if (pHddCtx->hdd_wlan_suspended)
11425 {
11426 hdd_set_pwrparams(pHddCtx);
11427 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011428 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070011429 goto done;
11430 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070011431 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070011432 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070011433 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
11434 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -070011435 goto done;
11436 default:
11437 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
11438 __func__);
11439 return -EOPNOTSUPP;
11440
11441 }
11442
11443 }
11444 else
11445 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011446 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
11447 __func__, hdd_device_modetoString(pAdapter->device_mode),
11448 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011449 return -EOPNOTSUPP;
11450 }
11451
11452
11453 if(pRoamProfile)
11454 {
11455 if ( LastBSSType != pRoamProfile->BSSType )
11456 {
11457 /*interface type changed update in wiphy structure*/
11458 wdev->iftype = type;
11459
11460 /*the BSS mode changed, We need to issue disconnect
11461 if connected or in IBSS disconnect state*/
11462 if ( hdd_connGetConnectedBssType(
11463 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
11464 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
11465 {
11466 /*need to issue a disconnect to CSR.*/
11467 INIT_COMPLETION(pAdapter->disconnect_comp_var);
11468 if( eHAL_STATUS_SUCCESS ==
11469 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
11470 pAdapter->sessionId,
11471 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
11472 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011473 ret = wait_for_completion_interruptible_timeout(
11474 &pAdapter->disconnect_comp_var,
11475 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
11476 if (ret <= 0)
11477 {
11478 hddLog(VOS_TRACE_LEVEL_ERROR,
11479 FL("wait on disconnect_comp_var failed %ld"), ret);
11480 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011481 }
11482 }
11483 }
11484 }
11485
11486done:
11487 /*set bitmask based on updated value*/
11488 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -070011489
11490 /* Only STA mode support TM now
11491 * all other mode, TM feature should be disabled */
11492 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
11493 (~VOS_STA & pHddCtx->concurrency_mode) )
11494 {
11495 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
11496 }
11497
Jeff Johnson295189b2012-06-20 16:38:30 -070011498#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011499 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053011500 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -070011501 {
11502 //we are ok to do AMP
11503 pHddCtx->isAmpAllowed = VOS_TRUE;
11504 }
11505#endif //WLAN_BTAMP_FEATURE
11506 EXIT();
11507 return 0;
11508}
11509
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053011510/*
11511 * FUNCTION: wlan_hdd_cfg80211_change_iface
11512 * wrapper function to protect the actual implementation from SSR.
11513 */
11514int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
11515 struct net_device *ndev,
11516 enum nl80211_iftype type,
11517 u32 *flags,
11518 struct vif_params *params
11519 )
11520{
11521 int ret;
11522
11523 vos_ssr_protect(__func__);
11524 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
11525 vos_ssr_unprotect(__func__);
11526
11527 return ret;
11528}
11529
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011530#ifdef FEATURE_WLAN_TDLS
11531static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011532 struct net_device *dev,
11533#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
11534 const u8 *mac,
11535#else
11536 u8 *mac,
11537#endif
11538 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011539{
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011540 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011541 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011542 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011543 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053011544 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053011545 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011546
11547 ENTER();
11548
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053011549 if (!dev) {
11550 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
11551 return -EINVAL;
11552 }
11553
11554 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
11555 if (!pAdapter) {
11556 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
11557 return -EINVAL;
11558 }
11559
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053011560 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011561 {
11562 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11563 "Invalid arguments");
11564 return -EINVAL;
11565 }
Hoonki Lee27511902013-03-14 18:19:06 -070011566
11567 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
11568 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
11569 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011570 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070011571 "%s: TDLS mode is disabled OR not enabled in FW."
11572 MAC_ADDRESS_STR " Request declined.",
11573 __func__, MAC_ADDR_ARRAY(mac));
11574 return -ENOTSUPP;
11575 }
11576
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011577 if (pHddCtx->isLogpInProgress)
11578 {
11579 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11580 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053011581 wlan_hdd_tdls_set_link_status(pAdapter,
11582 mac,
11583 eTDLS_LINK_IDLE,
11584 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011585 return -EBUSY;
11586 }
11587
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053011588 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +053011589 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011590
11591 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011592 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011593 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
11594 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053011595 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011596 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070011597 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011598
11599 /* in add station, we accept existing valid staId if there is */
11600 if ((0 == update) &&
11601 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
11602 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011603 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011604 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011605 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011606 " link_status %d. staId %d. add station ignored.",
11607 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011608 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011609 return 0;
11610 }
11611 /* in change station, we accept only when staId is valid */
11612 if ((1 == update) &&
11613 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
11614 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
11615 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011616 tANI_U16 staId = pTdlsPeer->staId;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011617 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011618 "%s: " MAC_ADDRESS_STR
11619 " link status %d. staId %d. change station %s.",
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011620 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, staId,
11621 (TDLS_STA_INDEX_VALID(staId)) ? "ignored" : "declined");
11622 mutex_unlock(&pHddCtx->tdls_lock);
11623 return (TDLS_STA_INDEX_VALID(staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011624 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011625 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070011626
11627 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053011628 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011629 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011630 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11631 "%s: " MAC_ADDRESS_STR
11632 " TDLS setup is ongoing. Request declined.",
11633 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -070011634 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011635 }
11636
11637 /* first to check if we reached to maximum supported TDLS peer.
11638 TODO: for now, return -EPERM looks working fine,
11639 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011640 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
11641 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011642 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011643 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11644 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011645 " TDLS Max peer already connected. Request declined."
11646 " Num of peers (%d), Max allowed (%d).",
11647 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
11648 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070011649 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011650 }
11651 else
11652 {
11653 hddTdlsPeer_t *pTdlsPeer;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011654 mutex_lock(&pHddCtx->tdls_lock);
11655 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011656 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011657 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011658 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011659 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11660 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
11661 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011662 return -EPERM;
11663 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011664 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011665 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011666 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +053011667 wlan_hdd_tdls_set_link_status(pAdapter,
11668 mac,
11669 eTDLS_LINK_CONNECTING,
11670 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011671
Jeff Johnsond75fe012013-04-06 10:53:06 -070011672 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053011673 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011674 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011675 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011676 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -070011677 if(StaParams->htcap_present)
11678 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011679 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070011680 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011681 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070011682 "ht_capa->extended_capabilities: %0x",
11683 StaParams->HTCap.extendedHtCapInfo);
11684 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011685 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011686 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011687 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011688 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -070011689 if(StaParams->vhtcap_present)
11690 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011691 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070011692 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
11693 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
11694 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
11695 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011696 {
11697 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011698 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011699 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011700 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011701 "[%d]: %x ", i, StaParams->supported_rates[i]);
11702 }
Jeff Johnsond75fe012013-04-06 10:53:06 -070011703 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053011704 else if ((1 == update) && (NULL == StaParams))
11705 {
11706 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11707 "%s : update is true, but staParams is NULL. Error!", __func__);
11708 return -EPERM;
11709 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011710
11711 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
11712
11713 if (!update)
11714 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053011715 /*Before adding sta make sure that device exited from BMPS*/
11716 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
11717 {
11718 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11719 "%s: Adding tdls peer sta. Disable BMPS", __func__);
11720 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
11721 if (status != VOS_STATUS_SUCCESS) {
11722 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
11723 }
11724 }
11725
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011726 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011727 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011728 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053011729 hddLog(VOS_TRACE_LEVEL_ERROR,
11730 FL("Failed to add TDLS peer STA. Enable Bmps"));
11731 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011732 return -EPERM;
11733 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011734 }
11735 else
11736 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011737 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011738 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011739 if (ret != eHAL_STATUS_SUCCESS) {
11740 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
11741 return -EPERM;
11742 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011743 }
11744
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011745 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011746 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
11747
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053011748 mutex_lock(&pHddCtx->tdls_lock);
11749 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
11750
Masti, Narayanraddi07262462016-01-19 12:40:06 +053011751 if ((pTdlsPeer != NULL) &&
11752 (pTdlsPeer->link_status == eTDLS_LINK_TEARING))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011753 {
Masti, Narayanraddi07262462016-01-19 12:40:06 +053011754 hddLog(VOS_TRACE_LEVEL_ERROR,
11755 FL("peer link status %u"), pTdlsPeer->link_status);
11756 mutex_unlock(&pHddCtx->tdls_lock);
11757 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011758 }
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053011759 mutex_unlock(&pHddCtx->tdls_lock);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011760
Masti, Narayanraddi07262462016-01-19 12:40:06 +053011761 if (ret <= 0)
11762 {
11763 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11764 "%s: timeout waiting for tdls add station indication %ld",
11765 __func__, ret);
11766 goto error;
11767 }
11768
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011769 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
11770 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011771 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011772 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070011773 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011774 }
11775
11776 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -070011777
11778error:
Atul Mittal115287b2014-07-08 13:26:33 +053011779 wlan_hdd_tdls_set_link_status(pAdapter,
11780 mac,
11781 eTDLS_LINK_IDLE,
11782 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -070011783 return -EPERM;
11784
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011785}
11786#endif
11787
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011788static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011789 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011790#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
11791 const u8 *mac,
11792#else
Jeff Johnson295189b2012-06-20 16:38:30 -070011793 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011794#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011795 struct station_parameters *params)
11796{
11797 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011798 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +053011799 hdd_context_t *pHddCtx;
11800 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011801 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011802 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070011803#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011804 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011805 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011806 tANI_U8 isOffChannelSupported = 0;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011807 tANI_U8 isQosWmmSta = FALSE;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070011808#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070011809
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011810 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011811
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011812 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +053011813 if ((NULL == pAdapter))
11814 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011815 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053011816 "invalid adapter ");
11817 return -EINVAL;
11818 }
11819
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011820 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11821 TRACE_CODE_HDD_CHANGE_STATION,
11822 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +053011823 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +053011824
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011825 ret = wlan_hdd_validate_context(pHddCtx);
11826 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +053011827 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011828 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +053011829 }
11830
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011831 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11832
11833 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011834 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011835 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11836 "invalid HDD station context");
11837 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011838 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011839 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
11840
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011841 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
11842 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -070011843 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011844 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -070011845 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011846 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -070011847 WLANTL_STA_AUTHENTICATED);
11848
Gopichand Nakkala29149562013-05-10 21:43:41 +053011849 if (status != VOS_STATUS_SUCCESS)
11850 {
11851 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11852 "%s: Not able to change TL state to AUTHENTICATED", __func__);
11853 return -EINVAL;
11854 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011855 }
11856 }
Hoonki Leea6d49be2013-04-05 09:43:25 -070011857 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
11858 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +053011859#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011860 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
11861 StaParams.capability = params->capability;
11862 StaParams.uapsd_queues = params->uapsd_queues;
11863 StaParams.max_sp = params->max_sp;
11864
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011865 /* Convert (first channel , number of channels) tuple to
11866 * the total list of channels. This goes with the assumption
11867 * that if the first channel is < 14, then the next channels
11868 * are an incremental of 1 else an incremental of 4 till the number
11869 * of channels.
11870 */
11871 if (0 != params->supported_channels_len) {
11872 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
11873 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
11874 {
11875 int wifi_chan_index;
11876 StaParams.supported_channels[j] = params->supported_channels[i];
11877 wifi_chan_index =
11878 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
11879 no_of_channels = params->supported_channels[i+1];
11880 for(k=1; k <= no_of_channels; k++)
11881 {
11882 StaParams.supported_channels[j+1] =
11883 StaParams.supported_channels[j] + wifi_chan_index;
11884 j+=1;
11885 }
11886 }
11887 StaParams.supported_channels_len = j;
11888 }
SaidiReddy Yenuga0f1a1592017-04-05 13:18:26 +053011889 if (params->supported_oper_classes_len >
11890 SIR_MAC_MAX_SUPP_OPER_CLASSES) {
11891 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11892 "received oper classes:%d, resetting it to max supported %d",
11893 params->supported_oper_classes_len,
11894 SIR_MAC_MAX_SUPP_OPER_CLASSES);
11895 params->supported_oper_classes_len =
11896 SIR_MAC_MAX_SUPP_OPER_CLASSES;
11897 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011898 vos_mem_copy(StaParams.supported_oper_classes,
11899 params->supported_oper_classes,
11900 params->supported_oper_classes_len);
11901 StaParams.supported_oper_classes_len =
11902 params->supported_oper_classes_len;
11903
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053011904 if (params->ext_capab_len > sizeof(StaParams.extn_capability)) {
11905 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11906 "received extn capabilities:%d, resetting it to max supported",
11907 params->ext_capab_len);
11908 params->ext_capab_len = sizeof(StaParams.extn_capability);
11909 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011910 if (0 != params->ext_capab_len)
11911 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053011912 params->ext_capab_len);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011913
11914 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070011915 {
11916 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011917 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070011918 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011919
11920 StaParams.supported_rates_len = params->supported_rates_len;
11921
11922 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
11923 * The supported_rates array , for all the structures propogating till Add Sta
11924 * to the firmware has to be modified , if the supplicant (ieee80211) is
11925 * modified to send more rates.
11926 */
11927
11928 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
11929 */
11930 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
11931 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
11932
11933 if (0 != StaParams.supported_rates_len) {
11934 int i = 0;
11935 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
11936 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011937 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011938 "Supported Rates with Length %d", StaParams.supported_rates_len);
11939 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011940 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011941 "[%d]: %0x", i, StaParams.supported_rates[i]);
11942 }
11943
11944 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070011945 {
11946 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011947 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070011948 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011949
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011950 if (0 != params->ext_capab_len ) {
11951 /*Define A Macro : TODO Sunil*/
11952 if ((1<<4) & StaParams.extn_capability[3]) {
11953 isBufSta = 1;
11954 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011955 /* TDLS Channel Switching Support */
11956 if ((1<<6) & StaParams.extn_capability[3]) {
11957 isOffChannelSupported = 1;
11958 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011959 }
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011960
11961 if (pHddCtx->cfg_ini->fEnableTDLSWmmMode &&
Nitesh Shah48df4c02016-08-12 16:27:33 +053011962 (params->ht_capa || params->vht_capa ||
11963 (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME))))
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011964 /* TDLS Peer is WME/QoS capable */
11965 isQosWmmSta = TRUE;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011966
11967 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11968 "%s: TDLS Peer is QOS capable isQosWmmSta= %d HTcapPresent= %d",
11969 __func__, isQosWmmSta, StaParams.htcap_present);
11970
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011971 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
11972 &StaParams, isBufSta,
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011973 isOffChannelSupported,
11974 isQosWmmSta);
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011975
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053011976 if (VOS_STATUS_SUCCESS != status) {
11977 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11978 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
11979 return -EINVAL;
11980 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011981 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
11982
11983 if (VOS_STATUS_SUCCESS != status) {
11984 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11985 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
11986 return -EINVAL;
11987 }
11988 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -070011989#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +053011990 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011991 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011992 return status;
11993}
11994
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011995#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
11996static int wlan_hdd_change_station(struct wiphy *wiphy,
11997 struct net_device *dev,
11998 const u8 *mac,
11999 struct station_parameters *params)
12000#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012001static int wlan_hdd_change_station(struct wiphy *wiphy,
12002 struct net_device *dev,
12003 u8 *mac,
12004 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012005#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012006{
12007 int ret;
12008
12009 vos_ssr_protect(__func__);
12010 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
12011 vos_ssr_unprotect(__func__);
12012
12013 return ret;
12014}
12015
Jeff Johnson295189b2012-06-20 16:38:30 -070012016/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012017 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -070012018 * This function is used to initialize the key information
12019 */
12020#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012021static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012022 struct net_device *ndev,
12023 u8 key_index, bool pairwise,
12024 const u8 *mac_addr,
12025 struct key_params *params
12026 )
12027#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012028static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012029 struct net_device *ndev,
12030 u8 key_index, const u8 *mac_addr,
12031 struct key_params *params
12032 )
12033#endif
12034{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012035 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070012036 tCsrRoamSetKey setKey;
12037 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012038 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012039 v_U32_t roamId= 0xFF;
12040 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070012041 hdd_hostapd_state_t *pHostapdState;
12042 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012043 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012044 hdd_context_t *pHddCtx;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053012045 uint8_t i;
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053012046 v_MACADDR_t *peerMacAddr;
12047 u64 rsc_counter = 0;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053012048 uint8_t staid = HDD_MAX_STA_COUNT;
12049 bool pairwise_set_key = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070012050
12051 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012052
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012053 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12054 TRACE_CODE_HDD_CFG80211_ADD_KEY,
12055 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012056 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12057 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012058 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012059 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012060 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012061 }
12062
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012063 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12064 __func__, hdd_device_modetoString(pAdapter->device_mode),
12065 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012066
12067 if (CSR_MAX_NUM_KEY <= key_index)
12068 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012069 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012070 key_index);
12071
12072 return -EINVAL;
12073 }
12074
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012075 if (CSR_MAX_KEY_LEN < params->key_len)
12076 {
12077 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
12078 params->key_len);
12079
12080 return -EINVAL;
12081 }
12082
Jingxiang Gec438aea2017-10-26 16:44:00 +080012083 if (CSR_MAX_RSC_LEN < params->seq_len)
12084 {
12085 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Invalid seq length %d", __func__,
12086 params->seq_len);
12087 }
12088
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012089 hddLog(VOS_TRACE_LEVEL_INFO,
Jingxiang Gec438aea2017-10-26 16:44:00 +080012090 "%s: called with key index = %d & key length %d & seq length %d",
12091 __func__, key_index, params->key_len, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070012092
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053012093 peerMacAddr = (v_MACADDR_t *)mac_addr;
12094
Jeff Johnson295189b2012-06-20 16:38:30 -070012095 /*extract key idx, key len and key*/
12096 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
12097 setKey.keyId = key_index;
12098 setKey.keyLength = params->key_len;
12099 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
Jingxiang Gec438aea2017-10-26 16:44:00 +080012100 vos_mem_copy(&setKey.keyRsc[0], params->seq, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070012101
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012102 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070012103 {
12104 case WLAN_CIPHER_SUITE_WEP40:
12105 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
12106 break;
12107
12108 case WLAN_CIPHER_SUITE_WEP104:
12109 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
12110 break;
12111
12112 case WLAN_CIPHER_SUITE_TKIP:
12113 {
12114 u8 *pKey = &setKey.Key[0];
12115 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
12116
12117 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
12118
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012119 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -070012120
12121 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012122 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070012123 |--------------|----------|----------|
12124 <---16bytes---><--8bytes--><--8bytes-->
12125
12126 */
12127 /*Sme expects the 32 bytes key to be in the below order
12128
12129 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012130 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070012131 |--------------|----------|----------|
12132 <---16bytes---><--8bytes--><--8bytes-->
12133 */
12134 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012135 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -070012136
12137 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012138 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070012139
12140 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012141 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070012142
12143
12144 break;
12145 }
12146
12147 case WLAN_CIPHER_SUITE_CCMP:
12148 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
12149 break;
12150
12151#ifdef FEATURE_WLAN_WAPI
12152 case WLAN_CIPHER_SUITE_SMS4:
12153 {
12154 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
12155 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
12156 params->key, params->key_len);
12157 return 0;
12158 }
12159#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070012160
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080012161#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070012162 case WLAN_CIPHER_SUITE_KRK:
12163 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
12164 break;
12165#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070012166
12167#ifdef WLAN_FEATURE_11W
12168 case WLAN_CIPHER_SUITE_AES_CMAC:
12169 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -070012170 break;
Chet Lanctot186b5732013-03-18 10:26:30 -070012171#endif
12172
Jeff Johnson295189b2012-06-20 16:38:30 -070012173 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012174 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070012175 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012176 status = -EOPNOTSUPP;
12177 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012178 }
12179
12180 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
12181 __func__, setKey.encType);
12182
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012183 if (
Jeff Johnson295189b2012-06-20 16:38:30 -070012184#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12185 (!pairwise)
12186#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012187 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -070012188#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012189 )
12190 {
12191 /* set group key*/
12192 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12193 "%s- %d: setting Broadcast key",
12194 __func__, __LINE__);
12195 setKey.keyDirection = eSIR_RX_ONLY;
12196 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
12197 }
12198 else
12199 {
12200 /* set pairwise key*/
12201 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12202 "%s- %d: setting pairwise key",
12203 __func__, __LINE__);
12204 setKey.keyDirection = eSIR_TX_RX;
12205 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053012206 pairwise_set_key = true;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012207 }
12208 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
12209 {
12210 setKey.keyDirection = eSIR_TX_RX;
12211 /*Set the group key*/
12212 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
12213 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -070012214
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012215 if ( 0 != status )
12216 {
12217 hddLog(VOS_TRACE_LEVEL_ERROR,
12218 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012219 status = -EINVAL;
12220 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012221 }
12222 /*Save the keys here and call sme_RoamSetKey for setting
12223 the PTK after peer joins the IBSS network*/
12224 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
12225 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012226 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012227 }
Gopichand Nakkala29149562013-05-10 21:43:41 +053012228 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
12229 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
12230 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012231 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012232 if( pHostapdState->bssState == BSS_START )
12233 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012234 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12235 vos_status = wlan_hdd_check_ula_done(pAdapter);
12236
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053012237 if (peerMacAddr && (pairwise_set_key == true))
12238 staid = hdd_sta_id_find_from_mac_addr(pAdapter, peerMacAddr);
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053012239
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012240 if ( vos_status != VOS_STATUS_SUCCESS )
12241 {
12242 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12243 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
12244 __LINE__, vos_status );
12245
12246 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
12247
12248 status = -EINVAL;
12249 goto end;
12250 }
12251
Jeff Johnson295189b2012-06-20 16:38:30 -070012252 status = WLANSAP_SetKeySta( pVosContext, &setKey);
12253
12254 if ( status != eHAL_STATUS_SUCCESS )
12255 {
12256 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12257 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
12258 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012259 status = -EINVAL;
12260 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012261 }
12262 }
12263
12264 /* Saving WEP keys */
12265 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
12266 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
12267 {
12268 //Save the wep key in ap context. Issue setkey after the BSS is started.
12269 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
12270 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
12271 }
12272 else
12273 {
12274 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012275 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012276 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
12277 }
12278 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012279 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
12280 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012281 {
12282 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12283 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12284
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012285#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12286 if (!pairwise)
12287#else
12288 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
12289#endif
12290 {
12291 /* set group key*/
12292 if (pHddStaCtx->roam_info.deferKeyComplete)
12293 {
12294 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12295 "%s- %d: Perform Set key Complete",
12296 __func__, __LINE__);
12297 hdd_PerformRoamSetKeyComplete(pAdapter);
12298 }
12299 }
12300
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053012301 if (pairwise_set_key == true)
12302 staid = pHddStaCtx->conn_info.staId[0];
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053012303
Jeff Johnson295189b2012-06-20 16:38:30 -070012304 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
12305
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -080012306 pWextState->roamProfile.Keys.defaultIndex = key_index;
12307
12308
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012309 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070012310 params->key, params->key_len);
12311
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012312
Jeff Johnson295189b2012-06-20 16:38:30 -070012313 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
12314
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012315 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070012316 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012317 __func__, setKey.peerMac[0], setKey.peerMac[1],
12318 setKey.peerMac[2], setKey.peerMac[3],
12319 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070012320 setKey.keyDirection);
12321
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012322 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +053012323
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012324 if ( vos_status != VOS_STATUS_SUCCESS )
12325 {
12326 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012327 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
12328 __LINE__, vos_status );
12329
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012330 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012331
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012332 status = -EINVAL;
12333 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012334
12335 }
12336
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012337#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012338 /* The supplicant may attempt to set the PTK once pre-authentication
12339 is done. Save the key in the UMAC and include it in the ADD BSS
12340 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012341 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012342 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012343 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012344 hddLog(VOS_TRACE_LEVEL_INFO_MED,
12345 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012346 status = 0;
12347 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012348 }
12349 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
12350 {
12351 hddLog(VOS_TRACE_LEVEL_ERROR,
12352 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012353 status = -EINVAL;
12354 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012355 }
12356#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070012357
12358 /* issue set key request to SME*/
12359 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
12360 pAdapter->sessionId, &setKey, &roamId );
12361
12362 if ( 0 != status )
12363 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012364 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012365 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
12366 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012367 status = -EINVAL;
12368 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012369 }
12370
12371
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012372 /* in case of IBSS as there was no information available about WEP keys during
12373 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070012374 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012375 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
12376 !( ( IW_AUTH_KEY_MGMT_802_1X
12377 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070012378 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
12379 )
12380 &&
12381 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
12382 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
12383 )
12384 )
12385 {
12386 setKey.keyDirection = eSIR_RX_ONLY;
12387 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
12388
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012389 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070012390 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012391 __func__, setKey.peerMac[0], setKey.peerMac[1],
12392 setKey.peerMac[2], setKey.peerMac[3],
12393 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070012394 setKey.keyDirection);
12395
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012396 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070012397 pAdapter->sessionId, &setKey, &roamId );
12398
12399 if ( 0 != status )
12400 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012401 hddLog(VOS_TRACE_LEVEL_ERROR,
12402 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012403 __func__, status);
12404 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012405 status = -EINVAL;
12406 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012407 }
12408 }
12409 }
12410
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053012411 if (pairwise_set_key == true) {
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053012412 for (i = 0; i < params->seq_len; i++) {
12413 rsc_counter |= (params->seq[i] << i*8);
12414 }
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053012415 WLANTL_SetKeySeqCounter(pVosContext, rsc_counter, staid);
12416 }
12417
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012418end:
12419 /* Need to clear any trace of key value in the memory.
12420 * Thus zero out the memory even though it is local
12421 * variable.
12422 */
12423 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012424 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012425 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012426}
12427
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012428#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12429static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
12430 struct net_device *ndev,
12431 u8 key_index, bool pairwise,
12432 const u8 *mac_addr,
12433 struct key_params *params
12434 )
12435#else
12436static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
12437 struct net_device *ndev,
12438 u8 key_index, const u8 *mac_addr,
12439 struct key_params *params
12440 )
12441#endif
12442{
12443 int ret;
12444 vos_ssr_protect(__func__);
12445#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12446 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
12447 mac_addr, params);
12448#else
12449 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
12450 params);
12451#endif
12452 vos_ssr_unprotect(__func__);
12453
12454 return ret;
12455}
12456
Jeff Johnson295189b2012-06-20 16:38:30 -070012457/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012458 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070012459 * This function is used to get the key information
12460 */
12461#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012462static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012463 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012464 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012465 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070012466 const u8 *mac_addr, void *cookie,
12467 void (*callback)(void *cookie, struct key_params*)
12468 )
12469#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012470static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012471 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012472 struct net_device *ndev,
12473 u8 key_index, const u8 *mac_addr, void *cookie,
12474 void (*callback)(void *cookie, struct key_params*)
12475 )
12476#endif
12477{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012478 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012479 hdd_wext_state_t *pWextState = NULL;
12480 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012481 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012482 hdd_context_t *pHddCtx;
12483 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012484
12485 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012486
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012487 if (NULL == pAdapter)
12488 {
12489 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12490 "%s: HDD adapter is Null", __func__);
12491 return -ENODEV;
12492 }
12493
12494 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12495 ret = wlan_hdd_validate_context(pHddCtx);
12496 if (0 != ret)
12497 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012498 return ret;
12499 }
12500
12501 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12502 pRoamProfile = &(pWextState->roamProfile);
12503
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012504 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12505 __func__, hdd_device_modetoString(pAdapter->device_mode),
12506 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012507
Jeff Johnson295189b2012-06-20 16:38:30 -070012508 memset(&params, 0, sizeof(params));
12509
12510 if (CSR_MAX_NUM_KEY <= key_index)
12511 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012512 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070012513 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012514 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012515
12516 switch(pRoamProfile->EncryptionType.encryptionType[0])
12517 {
12518 case eCSR_ENCRYPT_TYPE_NONE:
12519 params.cipher = IW_AUTH_CIPHER_NONE;
12520 break;
12521
12522 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
12523 case eCSR_ENCRYPT_TYPE_WEP40:
12524 params.cipher = WLAN_CIPHER_SUITE_WEP40;
12525 break;
12526
12527 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
12528 case eCSR_ENCRYPT_TYPE_WEP104:
12529 params.cipher = WLAN_CIPHER_SUITE_WEP104;
12530 break;
12531
12532 case eCSR_ENCRYPT_TYPE_TKIP:
12533 params.cipher = WLAN_CIPHER_SUITE_TKIP;
12534 break;
12535
12536 case eCSR_ENCRYPT_TYPE_AES:
12537 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
12538 break;
12539
12540 default:
12541 params.cipher = IW_AUTH_CIPHER_NONE;
12542 break;
12543 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012544
c_hpothuaaf19692014-05-17 17:01:48 +053012545 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12546 TRACE_CODE_HDD_CFG80211_GET_KEY,
12547 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012548
Jeff Johnson295189b2012-06-20 16:38:30 -070012549 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
12550 params.seq_len = 0;
12551 params.seq = NULL;
12552 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
12553 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012554 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012555 return 0;
12556}
12557
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012558#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12559static int wlan_hdd_cfg80211_get_key(
12560 struct wiphy *wiphy,
12561 struct net_device *ndev,
12562 u8 key_index, bool pairwise,
12563 const u8 *mac_addr, void *cookie,
12564 void (*callback)(void *cookie, struct key_params*)
12565 )
12566#else
12567static int wlan_hdd_cfg80211_get_key(
12568 struct wiphy *wiphy,
12569 struct net_device *ndev,
12570 u8 key_index, const u8 *mac_addr, void *cookie,
12571 void (*callback)(void *cookie, struct key_params*)
12572 )
12573#endif
12574{
12575 int ret;
12576
12577 vos_ssr_protect(__func__);
12578#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12579 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
12580 mac_addr, cookie, callback);
12581#else
12582 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
12583 callback);
12584#endif
12585 vos_ssr_unprotect(__func__);
12586
12587 return ret;
12588}
12589
Jeff Johnson295189b2012-06-20 16:38:30 -070012590/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012591 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070012592 * This function is used to delete the key information
12593 */
12594#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012595static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012596 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012597 u8 key_index,
12598 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070012599 const u8 *mac_addr
12600 )
12601#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012602static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012603 struct net_device *ndev,
12604 u8 key_index,
12605 const u8 *mac_addr
12606 )
12607#endif
12608{
12609 int status = 0;
12610
12611 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012612 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070012613 //it is observed that this is invalidating peer
12614 //key index whenever re-key is done. This is affecting data link.
12615 //It should be ok to ignore del_key.
12616#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012617 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
12618 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070012619 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
12620 tCsrRoamSetKey setKey;
12621 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012622
Jeff Johnson295189b2012-06-20 16:38:30 -070012623 ENTER();
12624
12625 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
12626 __func__,pAdapter->device_mode);
12627
12628 if (CSR_MAX_NUM_KEY <= key_index)
12629 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012630 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012631 key_index);
12632
12633 return -EINVAL;
12634 }
12635
12636 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
12637 setKey.keyId = key_index;
12638
12639 if (mac_addr)
12640 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
12641 else
12642 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
12643
12644 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
12645
12646 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012647 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012648 )
12649 {
12650
12651 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070012652 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
12653 if( pHostapdState->bssState == BSS_START)
12654 {
12655 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012656
Jeff Johnson295189b2012-06-20 16:38:30 -070012657 if ( status != eHAL_STATUS_SUCCESS )
12658 {
12659 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12660 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
12661 __LINE__, status );
12662 }
12663 }
12664 }
12665 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012666 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070012667 )
12668 {
12669 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12670
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012671 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
12672
12673 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070012674 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012675 __func__, setKey.peerMac[0], setKey.peerMac[1],
12676 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070012677 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012678 if(pAdapter->sessionCtx.station.conn_info.connState ==
12679 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070012680 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012681 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070012682 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012683
Jeff Johnson295189b2012-06-20 16:38:30 -070012684 if ( 0 != status )
12685 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012686 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012687 "%s: sme_RoamSetKey failure, returned %d",
12688 __func__, status);
12689 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
12690 return -EINVAL;
12691 }
12692 }
12693 }
12694#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070012695 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012696 return status;
12697}
12698
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012699#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12700static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
12701 struct net_device *ndev,
12702 u8 key_index,
12703 bool pairwise,
12704 const u8 *mac_addr
12705 )
12706#else
12707static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
12708 struct net_device *ndev,
12709 u8 key_index,
12710 const u8 *mac_addr
12711 )
12712#endif
12713{
12714 int ret;
12715
12716 vos_ssr_protect(__func__);
12717#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12718 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
12719 mac_addr);
12720#else
12721 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
12722#endif
12723 vos_ssr_unprotect(__func__);
12724
12725 return ret;
12726}
12727
Jeff Johnson295189b2012-06-20 16:38:30 -070012728/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012729 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070012730 * This function is used to set the default tx key index
12731 */
12732#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012733static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012734 struct net_device *ndev,
12735 u8 key_index,
12736 bool unicast, bool multicast)
12737#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012738static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012739 struct net_device *ndev,
12740 u8 key_index)
12741#endif
12742{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012743 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012744 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053012745 hdd_wext_state_t *pWextState;
12746 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012747 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012748
12749 ENTER();
12750
Gopichand Nakkala29149562013-05-10 21:43:41 +053012751 if ((NULL == pAdapter))
12752 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012753 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053012754 "invalid adapter");
12755 return -EINVAL;
12756 }
12757
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012758 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12759 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
12760 pAdapter->sessionId, key_index));
12761
Gopichand Nakkala29149562013-05-10 21:43:41 +053012762 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12763 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12764
12765 if ((NULL == pWextState) || (NULL == pHddStaCtx))
12766 {
12767 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12768 "invalid Wext state or HDD context");
12769 return -EINVAL;
12770 }
12771
Arif Hussain6d2a3322013-11-17 19:50:10 -080012772 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012773 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012774
Jeff Johnson295189b2012-06-20 16:38:30 -070012775 if (CSR_MAX_NUM_KEY <= key_index)
12776 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012777 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012778 key_index);
12779
12780 return -EINVAL;
12781 }
12782
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012783 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12784 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012785 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012786 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012787 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012788 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012789
Jeff Johnson295189b2012-06-20 16:38:30 -070012790 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070012791 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012792 )
Jeff Johnson295189b2012-06-20 16:38:30 -070012793 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053012794 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080012795 pHddStaCtx->conn_info.ucEncryptionType) &&
Hu Wangb1f68cb2017-08-23 20:01:49 +080012796#ifdef FEATURE_WLAN_WAPI
12797 (eCSR_ENCRYPT_TYPE_WPI !=
12798 pHddStaCtx->conn_info.ucEncryptionType) &&
12799#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012800 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080012801 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070012802 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012803 {
12804 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070012805 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012806
Jeff Johnson295189b2012-06-20 16:38:30 -070012807 tCsrRoamSetKey setKey;
12808 v_U32_t roamId= 0xFF;
12809 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012810
12811 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012812 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012813
Jeff Johnson295189b2012-06-20 16:38:30 -070012814 Keys->defaultIndex = (u8)key_index;
12815 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
12816 setKey.keyId = key_index;
12817 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012818
12819 vos_mem_copy(&setKey.Key[0],
12820 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070012821 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012822
Gopichand Nakkala29149562013-05-10 21:43:41 +053012823 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012824
12825 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070012826 &pHddStaCtx->conn_info.bssId[0],
12827 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012828
Gopichand Nakkala29149562013-05-10 21:43:41 +053012829 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
12830 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
12831 eCSR_ENCRYPT_TYPE_WEP104)
12832 {
12833 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
12834 even though ap is configured for WEP-40 encryption. In this canse the key length
12835 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
12836 type(104) and switching encryption type to 40*/
12837 pWextState->roamProfile.EncryptionType.encryptionType[0] =
12838 eCSR_ENCRYPT_TYPE_WEP40;
12839 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
12840 eCSR_ENCRYPT_TYPE_WEP40;
12841 }
12842
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012843 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070012844 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012845
Jeff Johnson295189b2012-06-20 16:38:30 -070012846 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012847 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070012848 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012849
Jeff Johnson295189b2012-06-20 16:38:30 -070012850 if ( 0 != status )
12851 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012852 hddLog(VOS_TRACE_LEVEL_ERROR,
12853 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012854 status);
12855 return -EINVAL;
12856 }
12857 }
12858 }
12859
12860 /* In SoftAp mode setting key direction for default mode */
12861 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
12862 {
12863 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
12864 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
12865 (eCSR_ENCRYPT_TYPE_AES !=
12866 pWextState->roamProfile.EncryptionType.encryptionType[0])
12867 )
12868 {
12869 /* Saving key direction for default key index to TX default */
12870 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
12871 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
12872 }
12873 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012874 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012875 return status;
12876}
12877
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012878#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12879static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
12880 struct net_device *ndev,
12881 u8 key_index,
12882 bool unicast, bool multicast)
12883#else
12884static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
12885 struct net_device *ndev,
12886 u8 key_index)
12887#endif
12888{
12889 int ret;
12890 vos_ssr_protect(__func__);
12891#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12892 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
12893 multicast);
12894#else
12895 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
12896#endif
12897 vos_ssr_unprotect(__func__);
12898
12899 return ret;
12900}
12901
Jeff Johnson295189b2012-06-20 16:38:30 -070012902/*
12903 * FUNCTION: wlan_hdd_cfg80211_inform_bss
12904 * This function is used to inform the BSS details to nl80211 interface.
12905 */
12906static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
12907 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
12908{
12909 struct net_device *dev = pAdapter->dev;
12910 struct wireless_dev *wdev = dev->ieee80211_ptr;
12911 struct wiphy *wiphy = wdev->wiphy;
12912 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
12913 int chan_no;
12914 int ie_length;
12915 const char *ie;
12916 unsigned int freq;
12917 struct ieee80211_channel *chan;
12918 int rssi = 0;
12919 struct cfg80211_bss *bss = NULL;
12920
Jeff Johnson295189b2012-06-20 16:38:30 -070012921 if( NULL == pBssDesc )
12922 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012923 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012924 return bss;
12925 }
12926
12927 chan_no = pBssDesc->channelId;
12928 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
12929 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
12930
12931 if( NULL == ie )
12932 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012933 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012934 return bss;
12935 }
12936
12937#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
12938 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
12939 {
12940 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
12941 }
12942 else
12943 {
12944 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
12945 }
12946#else
12947 freq = ieee80211_channel_to_frequency(chan_no);
12948#endif
12949
12950 chan = __ieee80211_get_channel(wiphy, freq);
12951
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053012952 if (!chan) {
12953 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
12954 return NULL;
12955 }
12956
Abhishek Singhaee43942014-06-16 18:55:47 +053012957 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070012958
Anand N Sunkad9f80b742015-07-30 20:05:51 +053012959 return cfg80211_inform_bss(wiphy, chan,
12960#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12961 CFG80211_BSS_FTYPE_UNKNOWN,
12962#endif
12963 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012964 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070012965 pBssDesc->capabilityInfo,
12966 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053012967 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070012968}
12969
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053012970/*
12971 * wlan_hdd_cfg80211_update_bss_list :to inform nl80211
12972 * interface that BSS might have been lost.
12973 * @pAdapter: adaptor
12974 * @bssid: bssid which might have been lost
12975 *
12976 * Return: bss which is unlinked from kernel cache
12977 */
12978struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_list(
12979 hdd_adapter_t *pAdapter, tSirMacAddr bssid)
12980{
12981 struct net_device *dev = pAdapter->dev;
12982 struct wireless_dev *wdev = dev->ieee80211_ptr;
12983 struct wiphy *wiphy = wdev->wiphy;
12984 struct cfg80211_bss *bss = NULL;
12985
Abhishek Singh5a597e62016-12-05 15:16:30 +053012986 bss = hdd_get_bss_entry(wiphy,
12987 NULL, bssid,
12988 NULL, 0);
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053012989 if (bss == NULL) {
12990 hddLog(LOGE, FL("BSS not present"));
12991 } else {
12992 hddLog(LOG1, FL("cfg80211_unlink_bss called for BSSID "
12993 MAC_ADDRESS_STR), MAC_ADDR_ARRAY(bssid));
12994 cfg80211_unlink_bss(wiphy, bss);
12995 }
12996 return bss;
12997}
Jeff Johnson295189b2012-06-20 16:38:30 -070012998
12999
13000/*
13001 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
13002 * This function is used to inform the BSS details to nl80211 interface.
13003 */
13004struct cfg80211_bss*
13005wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
13006 tSirBssDescription *bss_desc
13007 )
13008{
13009 /*
13010 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
13011 already exists in bss data base of cfg80211 for that particular BSS ID.
13012 Using cfg80211_inform_bss_frame to update the bss entry instead of
13013 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
13014 now there is no possibility to get the mgmt(probe response) frame from PE,
13015 converting bss_desc to ieee80211_mgmt(probe response) and passing to
13016 cfg80211_inform_bss_frame.
13017 */
13018 struct net_device *dev = pAdapter->dev;
13019 struct wireless_dev *wdev = dev->ieee80211_ptr;
13020 struct wiphy *wiphy = wdev->wiphy;
13021 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080013022#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
13023 qcom_ie_age *qie_age = NULL;
13024 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
13025#else
Jeff Johnson295189b2012-06-20 16:38:30 -070013026 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080013027#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013028 const char *ie =
13029 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
13030 unsigned int freq;
13031 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053013032 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013033 struct cfg80211_bss *bss_status = NULL;
13034 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
13035 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070013036 hdd_context_t *pHddCtx;
13037 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070013038#ifdef WLAN_OPEN_SOURCE
13039 struct timespec ts;
13040#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013041
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013042
Wilson Yangf80a0542013-10-07 13:02:37 -070013043 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13044 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070013045 if (0 != status)
13046 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070013047 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070013048 }
13049
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053013050 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070013051 if (!mgmt)
13052 {
13053 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13054 "%s: memory allocation failed ", __func__);
13055 return NULL;
13056 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070013057
Jeff Johnson295189b2012-06-20 16:38:30 -070013058 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070013059
13060#ifdef WLAN_OPEN_SOURCE
13061 /* Android does not want the timestamp from the frame.
13062 Instead it wants a monotonic increasing value */
13063 get_monotonic_boottime(&ts);
13064 mgmt->u.probe_resp.timestamp =
13065 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
13066#else
13067 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070013068 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
13069 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070013070
13071#endif
13072
Jeff Johnson295189b2012-06-20 16:38:30 -070013073 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
13074 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080013075
13076#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
13077 /* GPS Requirement: need age ie per entry. Using vendor specific. */
13078 /* Assuming this is the last IE, copy at the end */
13079 ie_length -=sizeof(qcom_ie_age);
13080 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
13081 qie_age->element_id = QCOM_VENDOR_IE_ID;
13082 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
13083 qie_age->oui_1 = QCOM_OUI1;
13084 qie_age->oui_2 = QCOM_OUI2;
13085 qie_age->oui_3 = QCOM_OUI3;
13086 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
Selvaraj, Sridhar4b3a8362016-10-12 12:34:08 +053013087 /* Lowi expects the timestamp of bss in units of 1/10 ms. In driver all
13088 * bss related timestamp is in units of ms. Due to this when scan results
13089 * are sent to lowi the scan age is high.To address this, send age in units
13090 * of 1/10 ms.
13091 */
13092 qie_age->age = (vos_timer_get_system_time() -
13093 bss_desc->nReceivedTime)/10;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080013094#endif
13095
Jeff Johnson295189b2012-06-20 16:38:30 -070013096 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053013097 if (bss_desc->fProbeRsp)
13098 {
13099 mgmt->frame_control |=
13100 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
13101 }
13102 else
13103 {
13104 mgmt->frame_control |=
13105 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
13106 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013107
13108#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013109 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070013110 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
13111 {
13112 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
13113 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013114 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070013115 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
13116
13117 {
13118 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
13119 }
13120 else
13121 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013122 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
13123 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070013124 kfree(mgmt);
13125 return NULL;
13126 }
13127#else
13128 freq = ieee80211_channel_to_frequency(chan_no);
13129#endif
13130 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080013131 /*when the band is changed on the fly using the GUI, three things are done
13132 * 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)
13133 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
13134 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
13135 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
13136 * and discards the channels correponding to previous band and calls back with zero bss results.
13137 * 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
13138 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
13139 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
13140 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
13141 * So drop the bss and continue to next bss.
13142 */
13143 if(chan == NULL)
13144 {
Deepthi Gowri306657b2016-04-28 17:10:41 +053013145 hddLog(VOS_TRACE_LEVEL_ERROR,
13146 FL("chan pointer is NULL, chan_no: %d freq: %d"),
13147 chan_no, freq);
Chilam Ngc4244af2013-04-01 15:37:32 -070013148 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080013149 return NULL;
13150 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053013151 /*To keep the rssi icon of the connected AP in the scan window
13152 *and the rssi icon of the wireless networks in sync
13153 * */
13154 if (( eConnectionState_Associated ==
13155 pAdapter->sessionCtx.station.conn_info.connState ) &&
13156 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
13157 pAdapter->sessionCtx.station.conn_info.bssId,
13158 WNI_CFG_BSSID_LEN)) &&
13159 (pHddCtx->hdd_wlan_suspended == FALSE))
13160 {
13161 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
13162 rssi = (pAdapter->rssi * 100);
13163 }
13164 else
13165 {
13166 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
13167 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013168
Nirav Shah20ac06f2013-12-12 18:14:06 +053013169 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053013170 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
13171 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053013172
Jeff Johnson295189b2012-06-20 16:38:30 -070013173 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
13174 frame_len, rssi, GFP_KERNEL);
13175 kfree(mgmt);
13176 return bss_status;
13177}
13178
13179/*
13180 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
13181 * This function is used to update the BSS data base of CFG8011
13182 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013183struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070013184 tCsrRoamInfo *pRoamInfo
13185 )
13186{
13187 tCsrRoamConnectedProfile roamProfile;
13188 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13189 struct cfg80211_bss *bss = NULL;
13190
13191 ENTER();
13192
13193 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
13194 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
13195
13196 if (NULL != roamProfile.pBssDesc)
13197 {
Girish Gowlif4b68022014-08-28 23:18:57 +053013198 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
13199 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070013200
13201 if (NULL == bss)
13202 {
13203 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
13204 __func__);
13205 }
13206
13207 sme_RoamFreeConnectProfile(hHal, &roamProfile);
13208 }
13209 else
13210 {
13211 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
13212 __func__);
13213 }
13214 return bss;
13215}
13216
13217/*
13218 * FUNCTION: wlan_hdd_cfg80211_update_bss
13219 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013220static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
13221 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070013222 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013223{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013224 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013225 tCsrScanResultInfo *pScanResult;
13226 eHalStatus status = 0;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013227 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013228 tScanResultHandle pResult;
13229 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070013230 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013231 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070013232 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013233
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013234 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13235 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
13236 NO_SESSION, pAdapter->sessionId));
13237
Wilson Yangf80a0542013-10-07 13:02:37 -070013238 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013239 ret = wlan_hdd_validate_context(pHddCtx);
13240 if (0 != ret)
Jeff Johnson295189b2012-06-20 16:38:30 -070013241 {
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013242 return ret;
Wilson Yangf80a0542013-10-07 13:02:37 -070013243 }
13244
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013245 if (pAdapter->request != NULL)
13246 {
13247 if ((pAdapter->request->n_ssids == 1)
13248 && (pAdapter->request->ssids != NULL)
13249 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
13250 is_p2p_scan = true;
13251 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013252 /*
13253 * start getting scan results and populate cgf80211 BSS database
13254 */
13255 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
13256
13257 /* no scan results */
13258 if (NULL == pResult)
13259 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013260 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
13261 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053013262 wlan_hdd_get_frame_logs(pAdapter,
13263 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070013264 return status;
13265 }
13266
13267 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
13268
13269 while (pScanResult)
13270 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013271 /*
13272 * cfg80211_inform_bss() is not updating ie field of bss entry, if
13273 * entry already exists in bss data base of cfg80211 for that
13274 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
13275 * bss entry instead of cfg80211_inform_bss, But this call expects
13276 * mgmt packet as input. As of now there is no possibility to get
13277 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070013278 * ieee80211_mgmt(probe response) and passing to c
13279 * fg80211_inform_bss_frame.
13280 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013281 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
13282 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
13283 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013284 pScanResult = sme_ScanResultGetNext(hHal, pResult);
13285 continue; //Skip the non p2p bss entries
13286 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013287 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
13288 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013289
Jeff Johnson295189b2012-06-20 16:38:30 -070013290
13291 if (NULL == bss_status)
13292 {
13293 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013294 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013295 }
13296 else
13297 {
Yue Maf49ba872013-08-19 12:04:25 -070013298 cfg80211_put_bss(
13299#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
13300 wiphy,
13301#endif
13302 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070013303 }
13304
13305 pScanResult = sme_ScanResultGetNext(hHal, pResult);
13306 }
13307
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013308 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013309 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013310 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013311}
13312
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013313void
13314hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
13315{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013316 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080013317 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013318} /****** end hddPrintMacAddr() ******/
13319
13320void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070013321hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013322{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013323 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013324 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070013325 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
13326 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
13327 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013328} /****** end hddPrintPmkId() ******/
13329
13330//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
13331//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
13332
13333//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
13334//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
13335
13336#define dump_bssid(bssid) \
13337 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070013338 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
13339 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013340 }
13341
13342#define dump_pmkid(pMac, pmkid) \
13343 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070013344 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
13345 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013346 }
13347
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070013348#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013349/*
13350 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
13351 * This function is used to notify the supplicant of a new PMKSA candidate.
13352 */
13353int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013354 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013355 int index, bool preauth )
13356{
Jeff Johnsone7245742012-09-05 17:12:55 -070013357#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013358 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070013359 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013360
13361 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070013362 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013363
13364 if( NULL == pRoamInfo )
13365 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013366 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013367 return -EINVAL;
13368 }
13369
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070013370 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
13371 {
13372 dump_bssid(pRoamInfo->bssid);
13373 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013374 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070013375 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013376#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013377 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013378}
13379#endif //FEATURE_WLAN_LFR
13380
Yue Maef608272013-04-08 23:09:17 -070013381#ifdef FEATURE_WLAN_LFR_METRICS
13382/*
13383 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
13384 * 802.11r/LFR metrics reporting function to report preauth initiation
13385 *
13386 */
13387#define MAX_LFR_METRICS_EVENT_LENGTH 100
13388VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
13389 tCsrRoamInfo *pRoamInfo)
13390{
13391 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
13392 union iwreq_data wrqu;
13393
13394 ENTER();
13395
13396 if (NULL == pAdapter)
13397 {
13398 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
13399 return VOS_STATUS_E_FAILURE;
13400 }
13401
13402 /* create the event */
13403 memset(&wrqu, 0, sizeof(wrqu));
13404 memset(metrics_notification, 0, sizeof(metrics_notification));
13405
13406 wrqu.data.pointer = metrics_notification;
13407 wrqu.data.length = scnprintf(metrics_notification,
13408 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
13409 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
13410
13411 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
13412
13413 EXIT();
13414
13415 return VOS_STATUS_SUCCESS;
13416}
13417
13418/*
13419 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
13420 * 802.11r/LFR metrics reporting function to report preauth completion
13421 * or failure
13422 */
13423VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
13424 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
13425{
13426 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
13427 union iwreq_data wrqu;
13428
13429 ENTER();
13430
13431 if (NULL == pAdapter)
13432 {
13433 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
13434 return VOS_STATUS_E_FAILURE;
13435 }
13436
13437 /* create the event */
13438 memset(&wrqu, 0, sizeof(wrqu));
13439 memset(metrics_notification, 0, sizeof(metrics_notification));
13440
13441 scnprintf(metrics_notification, sizeof(metrics_notification),
13442 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
13443 MAC_ADDR_ARRAY(pRoamInfo->bssid));
13444
13445 if (1 == preauth_status)
13446 strncat(metrics_notification, " TRUE", 5);
13447 else
13448 strncat(metrics_notification, " FALSE", 6);
13449
13450 wrqu.data.pointer = metrics_notification;
13451 wrqu.data.length = strlen(metrics_notification);
13452
13453 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
13454
13455 EXIT();
13456
13457 return VOS_STATUS_SUCCESS;
13458}
13459
13460/*
13461 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
13462 * 802.11r/LFR metrics reporting function to report handover initiation
13463 *
13464 */
13465VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
13466 tCsrRoamInfo *pRoamInfo)
13467{
13468 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
13469 union iwreq_data wrqu;
13470
13471 ENTER();
13472
13473 if (NULL == pAdapter)
13474 {
13475 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
13476 return VOS_STATUS_E_FAILURE;
13477 }
13478
13479 /* create the event */
13480 memset(&wrqu, 0, sizeof(wrqu));
13481 memset(metrics_notification, 0, sizeof(metrics_notification));
13482
13483 wrqu.data.pointer = metrics_notification;
13484 wrqu.data.length = scnprintf(metrics_notification,
13485 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
13486 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
13487
13488 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
13489
13490 EXIT();
13491
13492 return VOS_STATUS_SUCCESS;
13493}
13494#endif
13495
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013496
13497/**
13498 * wlan_hdd_cfg80211_validate_scan_req - validate scan request
13499 * @scan_req: scan request to be checked
13500 *
13501 * Return: true or false
13502 */
13503#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
13504static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
13505 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053013506 *scan_req, hdd_context_t
13507 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013508{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053013509 if (!scan_req || !scan_req->wiphy ||
13510 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013511 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
13512 return false;
13513 }
13514 if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HDD, NULL)) {
13515 hddLog(VOS_TRACE_LEVEL_ERROR, "Load/Unload in progress");
13516 return false;
13517 }
13518 return true;
13519}
13520#else
13521static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
13522 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053013523 *scan_req, hdd_context_t
13524 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013525{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053013526 if (!scan_req || !scan_req->wiphy ||
13527 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013528 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
13529 return false;
13530 }
13531 return true;
13532}
13533#endif
13534
Mukul Sharmab392b642017-08-17 17:45:29 +053013535#define NET_DEV_IS_IFF_UP(pAdapter) (pAdapter->dev->flags & IFF_UP)
Jeff Johnson295189b2012-06-20 16:38:30 -070013536/*
13537 * FUNCTION: hdd_cfg80211_scan_done_callback
13538 * scanning callback function, called after finishing scan
13539 *
13540 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013541static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070013542 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
13543{
13544 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013545 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070013546 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013547 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070013548 struct cfg80211_scan_request *req = NULL;
13549 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053013550 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013551 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013552 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013553 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013554
13555 ENTER();
13556
c_manjee1b4ab9a2016-10-26 11:36:55 +053013557 if (!pAdapter || pAdapter->magic != WLAN_HDD_ADAPTER_MAGIC ||
13558 !pAdapter->dev) {
13559 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Adapter is not valid"));
13560 return 0;
13561 }
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013562 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053013563 if (NULL == pHddCtx) {
13564 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013565 return 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013566 }
13567
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053013568#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053013569 if (!NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053013570 {
13571 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Interface is down"));
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053013572 }
13573#endif
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013574 pScanInfo = &pHddCtx->scan_info;
13575
Jeff Johnson295189b2012-06-20 16:38:30 -070013576 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070013577 "%s called with halHandle = %pK, pContext = %pK,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080013578 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013579 __func__, halHandle, pContext, (int) scanId, (int) status);
13580
Kiet Lamac06e2c2013-10-23 16:25:07 +053013581 pScanInfo->mScanPendingCounter = 0;
13582
Jeff Johnson295189b2012-06-20 16:38:30 -070013583 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013584 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070013585 &pScanInfo->scan_req_completion_event,
13586 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013587 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070013588 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013589 hddLog(VOS_TRACE_LEVEL_ERROR,
13590 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070013591 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070013592 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070013593 }
13594
Yue Maef608272013-04-08 23:09:17 -070013595 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070013596 {
13597 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070013598 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070013599 }
13600
13601 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013602 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070013603 {
13604 hddLog(VOS_TRACE_LEVEL_INFO,
13605 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080013606 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070013607 (int) scanId);
13608 }
13609
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053013610#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053013611 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053013612#endif
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013613 {
13614 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
13615 pAdapter);
13616 if (0 > ret)
13617 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053013618 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013619
Jeff Johnson295189b2012-06-20 16:38:30 -070013620 /* If any client wait scan result through WEXT
13621 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013622 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070013623 {
13624 /* The other scan request waiting for current scan finish
13625 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013626 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070013627 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013628 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070013629 }
13630 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013631 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070013632 {
13633 struct net_device *dev = pAdapter->dev;
13634 union iwreq_data wrqu;
13635 int we_event;
13636 char *msg;
13637
13638 memset(&wrqu, '\0', sizeof(wrqu));
13639 we_event = SIOCGIWSCAN;
13640 msg = NULL;
13641 wireless_send_event(dev, we_event, &wrqu, msg);
13642 }
13643 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013644 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013645
13646 /* Get the Scan Req */
13647 req = pAdapter->request;
mukul sharmae7041822015-12-03 15:09:21 +053013648 pAdapter->request = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013649
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013650 /* Scan is no longer pending */
13651 pScanInfo->mScanPending = VOS_FALSE;
13652
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053013653 if (!wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Jeff Johnson295189b2012-06-20 16:38:30 -070013654 {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013655#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
13656 hddLog(VOS_TRACE_LEVEL_ERROR, FL("interface state %s"),
Mukul Sharmab392b642017-08-17 17:45:29 +053013657 NET_DEV_IS_IFF_UP(pAdapter) ? "up" : "down");
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013658#endif
13659
13660 if (pAdapter->dev) {
13661 hddLog(VOS_TRACE_LEVEL_ERROR, FL("device name %s"),
13662 pAdapter->dev->name);
13663 }
mukul sharmae7041822015-12-03 15:09:21 +053013664 complete(&pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -070013665 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070013666 }
13667
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013668 /* last_scan_timestamp is used to decide if new scan
13669 * is needed or not on station interface. If last station
13670 * scan time and new station scan time is less then
13671 * last_scan_timestamp ; driver will return cached scan.
13672 */
13673 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
13674 {
13675 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
13676
13677 if ( req->n_channels )
13678 {
13679 for (i = 0; i < req->n_channels ; i++ )
13680 {
13681 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
13682 }
13683 /* store no of channel scanned */
13684 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
13685 }
13686
13687 }
13688
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070013689 /*
13690 * cfg80211_scan_done informing NL80211 about completion
13691 * of scanning
13692 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053013693 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
13694 {
13695 aborted = true;
13696 }
mukul sharmae7041822015-12-03 15:09:21 +053013697
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013698#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053013699 if (NET_DEV_IS_IFF_UP(pAdapter) &&
13700 wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013701#endif
13702 cfg80211_scan_done(req, aborted);
mukul sharmae7041822015-12-03 15:09:21 +053013703
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080013704 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070013705
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013706allow_suspend:
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053013707 if ((pHddCtx->cfg_ini->enableMacSpoofing == MAC_ADDR_SPOOFING_FW_HOST_ENABLE
13708 ) && (pHddCtx->spoofMacAddr.isEnabled
13709 || pHddCtx->spoofMacAddr.isReqDeferred)) {
Siddharth Bhal76972212014-10-15 16:22:51 +053013710 /* Generate new random mac addr for next scan */
13711 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +053013712
13713 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
13714 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhal76972212014-10-15 16:22:51 +053013715 }
13716
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070013717 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013718 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070013719
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070013720 /* Acquire wakelock to handle the case where APP's tries to suspend
13721 * immediatly after the driver gets connect request(i.e after scan)
13722 * from supplicant, this result in app's is suspending and not able
13723 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013724 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070013725
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013726#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053013727 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013728#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070013729#ifdef FEATURE_WLAN_TDLS
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013730 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070013731#endif
13732
Jeff Johnson295189b2012-06-20 16:38:30 -070013733 EXIT();
13734 return 0;
13735}
13736
13737/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053013738 * FUNCTION: hdd_isConnectionInProgress
13739 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013740 *
13741 */
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013742v_BOOL_t hdd_isConnectionInProgress(hdd_context_t *pHddCtx, v_U8_t *session_id,
13743 scan_reject_states *reason)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013744{
13745 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
13746 hdd_station_ctx_t *pHddStaCtx = NULL;
13747 hdd_adapter_t *pAdapter = NULL;
13748 VOS_STATUS status = 0;
13749 v_U8_t staId = 0;
13750 v_U8_t *staMac = NULL;
13751
13752 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
13753
13754 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
13755 {
13756 pAdapter = pAdapterNode->pAdapter;
13757
13758 if( pAdapter )
13759 {
13760 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013761 "%s: Adapter with device mode %s (%d) exists",
13762 __func__, hdd_device_modetoString(pAdapter->device_mode),
13763 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013764 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053013765 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
13766 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
13767 (eConnectionState_Connecting ==
13768 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
13769 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053013770 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070013771 "%s: %pK(%d) Connection is in progress", __func__,
Rashmi Ramannab1429032014-04-26 14:59:09 +053013772 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013773 if (session_id && reason)
13774 {
13775 *session_id = pAdapter->sessionId;
13776 *reason = eHDD_CONNECTION_IN_PROGRESS;
13777 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053013778 return VOS_TRUE;
13779 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013780 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053013781 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013782 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053013783 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070013784 "%s: %pK(%d) Reassociation is in progress", __func__,
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013785 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013786 if (session_id && reason)
13787 {
13788 *session_id = pAdapter->sessionId;
13789 *reason = eHDD_REASSOC_IN_PROGRESS;
13790 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013791 return VOS_TRUE;
13792 }
13793 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013794 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
13795 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013796 {
13797 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13798 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013799 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013800 {
13801 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053013802 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080013803 "%s: client " MAC_ADDRESS_STR
13804 " is in the middle of WPS/EAPOL exchange.", __func__,
13805 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013806 if (session_id && reason)
13807 {
13808 *session_id = pAdapter->sessionId;
13809 *reason = eHDD_EAPOL_IN_PROGRESS;
13810 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053013811 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013812 }
13813 }
13814 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
13815 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
13816 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013817 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
13818 ptSapContext pSapCtx = NULL;
13819 pSapCtx = VOS_GET_SAP_CB(pVosContext);
13820 if(pSapCtx == NULL){
13821 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13822 FL("psapCtx is NULL"));
13823 return VOS_FALSE;
13824 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013825 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
13826 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013827 if ((pSapCtx->aStaInfo[staId].isUsed) &&
13828 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013829 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013830 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013831
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053013832 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080013833 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
13834 "middle of WPS/EAPOL exchange.", __func__,
13835 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013836 if (session_id && reason)
13837 {
13838 *session_id = pAdapter->sessionId;
13839 *reason = eHDD_SAP_EAPOL_IN_PROGRESS;
13840 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053013841 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013842 }
13843 }
13844 }
13845 }
13846 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13847 pAdapterNode = pNext;
13848 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053013849 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013850}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013851
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053013852/**
13853 * csr_scan_request_assign_bssid() - Set the BSSID received from Supplicant
13854 * to the Scan request
13855 * @scanRequest: Pointer to the csr scan request
13856 * @request: Pointer to the scan request from supplicant
13857 *
13858 * Return: None
13859 */
13860#ifdef CFG80211_SCAN_BSSID
13861static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
13862 struct cfg80211_scan_request *request)
13863{
13864 vos_mem_copy(scanRequest->bssid, request->bssid, VOS_MAC_ADDR_SIZE);
13865}
13866#else
13867static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
13868 struct cfg80211_scan_request *request)
13869{
13870}
13871#endif
13872
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013873/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013874 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070013875 * this scan respond to scan trigger and update cfg80211 scan database
13876 * later, scan dump command can be used to recieve scan results
13877 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013878int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080013879#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13880 struct net_device *dev,
13881#endif
13882 struct cfg80211_scan_request *request)
13883{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013884 hdd_adapter_t *pAdapter = NULL;
13885 hdd_context_t *pHddCtx = NULL;
13886 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013887 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013888 tCsrScanRequest scanRequest;
13889 tANI_U8 *channelList = NULL, i;
13890 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013891 int status;
13892 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013893 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013894 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053013895 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013896 bool is_p2p_scan = false;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013897 v_U8_t curr_session_id;
13898 scan_reject_states curr_reason;
Jeff Johnson295189b2012-06-20 16:38:30 -070013899
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013900#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
13901 struct net_device *dev = NULL;
13902 if (NULL == request)
13903 {
13904 hddLog(VOS_TRACE_LEVEL_ERROR,
13905 "%s: scan req param null", __func__);
13906 return -EINVAL;
13907 }
13908 dev = request->wdev->netdev;
13909#endif
13910
13911 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
13912 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
13913 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13914
Jeff Johnson295189b2012-06-20 16:38:30 -070013915 ENTER();
13916
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013917 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13918 __func__, hdd_device_modetoString(pAdapter->device_mode),
13919 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013920
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013921 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013922 if (0 != status)
13923 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013924 return status;
13925 }
13926
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013927 if (NULL == pwextBuf)
13928 {
13929 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
13930 __func__);
13931 return -EIO;
13932 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013933 cfg_param = pHddCtx->cfg_ini;
13934 pScanInfo = &pHddCtx->scan_info;
13935
Jeff Johnson295189b2012-06-20 16:38:30 -070013936#ifdef WLAN_BTAMP_FEATURE
13937 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013938 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070013939 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080013940 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013941 "%s: No scanning when AMP is on", __func__);
13942 return -EOPNOTSUPP;
13943 }
13944#endif
13945 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013946 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070013947 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013948 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013949 "%s: Not scanning on device_mode = %s (%d)",
13950 __func__, hdd_device_modetoString(pAdapter->device_mode),
13951 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013952 return -EOPNOTSUPP;
13953 }
13954
13955 if (TRUE == pScanInfo->mScanPending)
13956 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053013957 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
13958 {
13959 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
13960 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013961 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070013962 }
13963
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053013964 // Don't allow scan if PNO scan is going on.
13965 if (pHddCtx->isPnoEnable)
13966 {
13967 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13968 FL("pno scan in progress"));
13969 return -EBUSY;
13970 }
13971
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013972 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070013973 //Channel and action frame is pending
13974 //Otherwise Cancel Remain On Channel and allow Scan
13975 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013976 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070013977 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053013978 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070013979 return -EBUSY;
13980 }
13981
Jeff Johnson295189b2012-06-20 16:38:30 -070013982 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
13983 {
13984 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080013985 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013986 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013987 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013988 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
13989 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013990 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013991 "%s: MAX TM Level Scan not allowed", __func__);
13992 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013993 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070013994 }
13995 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
13996
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013997 /* Check if scan is allowed at this point of time.
13998 */
Hanumanth Reddy Pothulaec960842016-09-14 19:04:26 +053013999 if (TRUE == pHddCtx->btCoexModeSet)
14000 {
14001 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14002 FL("BTCoex Mode operation in progress"));
14003 return -EBUSY;
14004 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014005 if (hdd_isConnectionInProgress(pHddCtx, &curr_session_id, &curr_reason))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014006 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014007
14008 if (!(pHddCtx->scan_reject_cnt % HDD_SCAN_REJECT_RATE_LIMIT))
14009 hddLog(LOGE, FL("Scan not allowed Session %d reason %d"),
14010 curr_session_id, curr_reason);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014011 if (pHddCtx->last_scan_reject_session_id != curr_session_id ||
14012 pHddCtx->last_scan_reject_reason != curr_reason ||
14013 !pHddCtx->last_scan_reject_timestamp)
14014 {
14015 pHddCtx->last_scan_reject_session_id = curr_session_id;
14016 pHddCtx->last_scan_reject_reason = curr_reason;
Abhishek Singh3e500772017-07-17 10:13:43 +053014017 pHddCtx->last_scan_reject_timestamp =
14018 jiffies_to_msecs(jiffies) + SCAN_REJECT_THRESHOLD_TIME;
Abhishek Singhe4b12562017-06-20 16:53:39 +053014019 pHddCtx->scan_reject_cnt = 0;
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053014020 }
Abhishek Singhe4b12562017-06-20 16:53:39 +053014021 else
14022 {
14023 pHddCtx->scan_reject_cnt++;
14024
Abhishek Singhe4b12562017-06-20 16:53:39 +053014025 if ((pHddCtx->scan_reject_cnt >=
14026 SCAN_REJECT_THRESHOLD) &&
Abhishek Singh3e500772017-07-17 10:13:43 +053014027 vos_system_time_after(jiffies_to_msecs(jiffies),
14028 pHddCtx->last_scan_reject_timestamp))
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014029 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014030 hddLog(LOGE, FL("Session %d reason %d reject cnt %d threshold time has elapsed? %d"),
14031 curr_session_id, curr_reason, pHddCtx->scan_reject_cnt,
14032 vos_system_time_after(jiffies_to_msecs(jiffies),
14033 pHddCtx->last_scan_reject_timestamp));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014034 pHddCtx->last_scan_reject_timestamp = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053014035 pHddCtx->scan_reject_cnt = 0;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014036 if (pHddCtx->cfg_ini->enableFatalEvent)
14037 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
14038 WLAN_LOG_INDICATOR_HOST_DRIVER,
14039 WLAN_LOG_REASON_SCAN_NOT_ALLOWED,
14040 FALSE, FALSE);
14041 else
14042 {
14043 hddLog(LOGE, FL("Triggering SSR"));
14044 vos_wlanRestart();
14045 }
14046 }
14047 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014048 return -EBUSY;
14049 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014050 pHddCtx->last_scan_reject_timestamp = 0;
14051 pHddCtx->last_scan_reject_session_id = 0xFF;
14052 pHddCtx->last_scan_reject_reason = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053014053 pHddCtx->scan_reject_cnt = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014054
Jeff Johnson295189b2012-06-20 16:38:30 -070014055 vos_mem_zero( &scanRequest, sizeof(scanRequest));
14056
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014057 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
14058 * Becasue of this, driver is assuming that this is not wildcard scan and so
14059 * is not aging out the scan results.
14060 */
Hanumanth Reddy Pothula998efeb2017-10-31 15:43:19 +053014061 if ((request->ssids) && (request->n_ssids == 1) &&
14062 ('\0' == request->ssids->ssid[0])) {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014063 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014064 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014065
14066 if ((request->ssids) && (0 < request->n_ssids))
14067 {
14068 tCsrSSIDInfo *SsidInfo;
14069 int j;
14070 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
14071 /* Allocate num_ssid tCsrSSIDInfo structure */
14072 SsidInfo = scanRequest.SSIDs.SSIDList =
14073 ( tCsrSSIDInfo *)vos_mem_malloc(
14074 request->n_ssids*sizeof(tCsrSSIDInfo));
14075
14076 if(NULL == scanRequest.SSIDs.SSIDList)
14077 {
14078 hddLog(VOS_TRACE_LEVEL_ERROR,
14079 "%s: memory alloc failed SSIDInfo buffer", __func__);
14080 return -ENOMEM;
14081 }
14082
14083 /* copy all the ssid's and their length */
14084 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
14085 {
14086 /* get the ssid length */
14087 SsidInfo->SSID.length = request->ssids[j].ssid_len;
14088 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
14089 SsidInfo->SSID.length);
14090 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
14091 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
14092 j, SsidInfo->SSID.ssId);
14093 }
14094 /* set the scan type to active */
14095 scanRequest.scanType = eSIR_ACTIVE_SCAN;
14096 }
14097 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070014098 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053014099 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14100 TRACE_CODE_HDD_CFG80211_SCAN,
14101 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070014102 /* set the scan type to active */
14103 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070014104 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014105 else
14106 {
14107 /*Set the scan type to default type, in this case it is ACTIVE*/
14108 scanRequest.scanType = pScanInfo->scan_mode;
14109 }
14110 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
14111 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070014112
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053014113 csr_scan_request_assign_bssid(&scanRequest, request);
14114
Jeff Johnson295189b2012-06-20 16:38:30 -070014115 /* set BSSType to default type */
14116 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
14117
14118 /*TODO: scan the requested channels only*/
14119
14120 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014121 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070014122 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014123 hddLog(VOS_TRACE_LEVEL_WARN,
14124 "No of Scan Channels exceeded limit: %d", request->n_channels);
14125 request->n_channels = MAX_CHANNEL;
14126 }
14127
14128 hddLog(VOS_TRACE_LEVEL_INFO,
14129 "No of Scan Channels: %d", request->n_channels);
14130
14131
14132 if( request->n_channels )
14133 {
14134 char chList [(request->n_channels*5)+1];
14135 int len;
14136 channelList = vos_mem_malloc( request->n_channels );
14137 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053014138 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014139 hddLog(VOS_TRACE_LEVEL_ERROR,
14140 "%s: memory alloc failed channelList", __func__);
14141 status = -ENOMEM;
14142 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053014143 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014144
14145 for( i = 0, len = 0; i < request->n_channels ; i++ )
14146 {
14147 channelList[i] = request->channels[i]->hw_value;
14148 len += snprintf(chList+len, 5, "%d ", channelList[i]);
14149 }
14150
Nirav Shah20ac06f2013-12-12 18:14:06 +053014151 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014152 "Channel-List: %s ", chList);
14153 }
c_hpothu53512302014-04-15 18:49:53 +053014154
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014155 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
14156 scanRequest.ChannelInfo.ChannelList = channelList;
14157
14158 /* set requestType to full scan */
14159 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
14160
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014161 /* if there is back to back scan happening in driver with in
14162 * nDeferScanTimeInterval interval driver should defer new scan request
14163 * and should provide last cached scan results instead of new channel list.
14164 * This rule is not applicable if scan is p2p scan.
14165 * This condition will work only in case when last request no of channels
14166 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053014167 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053014168 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014169 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014170
Sushant Kaushik86592172015-04-27 16:35:03 +053014171 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
14172 /* if wps ie is NULL , then only defer scan */
14173 if ( pWpsIe == NULL &&
14174 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053014175 {
14176 if ( pScanInfo->last_scan_timestamp !=0 &&
14177 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
14178 {
14179 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
14180 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
14181 vos_mem_compare(pScanInfo->last_scan_channelList,
14182 channelList, pScanInfo->last_scan_numChannels))
14183 {
14184 hddLog(VOS_TRACE_LEVEL_WARN,
14185 " New and old station scan time differ is less then %u",
14186 pHddCtx->cfg_ini->nDeferScanTimeInterval);
14187
14188 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014189 pAdapter);
14190
Agarwal Ashish57e84372014-12-05 18:26:53 +053014191 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053014192 "Return old cached scan as all channels and no of channels are same");
14193
Agarwal Ashish57e84372014-12-05 18:26:53 +053014194 if (0 > ret)
14195 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014196
Agarwal Ashish57e84372014-12-05 18:26:53 +053014197 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053014198
14199 status = eHAL_STATUS_SUCCESS;
14200 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053014201 }
14202 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014203 }
14204
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014205 /* Flush the scan results(only p2p beacons) for STA scan and P2P
14206 * search (Flush on both full scan and social scan but not on single
14207 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
14208 */
14209
14210 /* Supplicant does single channel scan after 8-way handshake
14211 * and in that case driver shoudnt flush scan results. If
14212 * driver flushes the scan results here and unfortunately if
14213 * the AP doesnt respond to our probe req then association
14214 * fails which is not desired
14215 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053014216 if ((request->n_ssids == 1)
14217 && (request->ssids != NULL)
14218 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
14219 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014220
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053014221 if( is_p2p_scan ||
14222 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014223 {
14224 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
14225 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
14226 pAdapter->sessionId );
14227 }
14228
14229 if( request->ie_len )
14230 {
14231 /* save this for future association (join requires this) */
14232 /*TODO: Array needs to be converted to dynamic allocation,
14233 * as multiple ie.s can be sent in cfg80211_scan_request structure
14234 * CR 597966
14235 */
14236 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
14237 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
14238 pScanInfo->scanAddIE.length = request->ie_len;
14239
14240 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
14241 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
14242 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070014243 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014244 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070014245 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014246 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
14247 memcpy( pwextBuf->roamProfile.addIEScan,
14248 request->ie, request->ie_len);
14249 }
14250 else
14251 {
14252 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
14253 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070014254 }
14255
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014256 }
14257 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
14258 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
14259
14260 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
14261 request->ie_len);
14262 if (pP2pIe != NULL)
14263 {
14264#ifdef WLAN_FEATURE_P2P_DEBUG
14265 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
14266 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
14267 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053014268 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014269 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
14270 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
14271 "Go nego completed to Connection is started");
14272 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
14273 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053014274 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014275 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
14276 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070014277 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014278 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
14279 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
14280 "Disconnected state to Connection is started");
14281 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
14282 "for 4way Handshake");
14283 }
14284#endif
14285
14286 /* no_cck will be set during p2p find to disable 11b rates */
14287 if(TRUE == request->no_cck)
14288 {
14289 hddLog(VOS_TRACE_LEVEL_INFO,
14290 "%s: This is a P2P Search", __func__);
14291 scanRequest.p2pSearch = 1;
14292
14293 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053014294 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014295 /* set requestType to P2P Discovery */
14296 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
14297 }
14298
14299 /*
14300 Skip Dfs Channel in case of P2P Search
14301 if it is set in ini file
14302 */
14303 if(cfg_param->skipDfsChnlInP2pSearch)
14304 {
14305 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053014306 }
14307 else
14308 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014309 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053014310 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014311
Agarwal Ashish4f616132013-12-30 23:32:50 +053014312 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014313 }
14314 }
14315
14316 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
14317
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014318#ifdef FEATURE_WLAN_TDLS
14319 /* if tdls disagree scan right now, return immediately.
14320 tdls will schedule the scan when scan is allowed. (return SUCCESS)
14321 or will reject the scan if any TDLS is in progress. (return -EBUSY)
14322 */
14323 status = wlan_hdd_tdls_scan_callback (pAdapter,
14324 wiphy,
14325#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
14326 dev,
14327#endif
14328 request);
Abhishek Singhe2b63952016-01-05 18:27:29 +053014329 if (status <= 0)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014330 {
Abhishek Singhe2b63952016-01-05 18:27:29 +053014331 if (!status)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014332 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
14333 "scan rejected %d", __func__, status);
14334 else
14335 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
14336 __func__, status);
Abhishek Singhe2b63952016-01-05 18:27:29 +053014337 hdd_wlan_block_scan_by_tdls();
Gupta, Kapil2ebf3e02016-03-17 19:45:19 +053014338 goto free_mem;
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014339 }
14340#endif
14341
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070014342 /* acquire the wakelock to avoid the apps suspend during the scan. To
14343 * address the following issues.
14344 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
14345 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
14346 * for long time, this result in apps running at full power for long time.
14347 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
14348 * be stuck in full power because of resume BMPS
14349 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014350 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070014351
Nirav Shah20ac06f2013-12-12 18:14:06 +053014352 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
14353 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014354 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
14355 scanRequest.requestType, scanRequest.scanType,
14356 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053014357 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
14358
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053014359 if (pHddCtx->spoofMacAddr.isEnabled &&
14360 pHddCtx->cfg_ini->enableMacSpoofing == 1)
Siddharth Bhal76972212014-10-15 16:22:51 +053014361 {
14362 hddLog(VOS_TRACE_LEVEL_INFO,
14363 "%s: MAC Spoofing enabled for current scan", __func__);
14364 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
14365 * to fill TxBds for probe request during current scan
14366 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053014367 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053014368 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053014369
14370 if(status != VOS_STATUS_SUCCESS)
14371 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014372 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053014373 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053014374#ifdef FEATURE_WLAN_TDLS
14375 wlan_hdd_tdls_scan_done_callback(pAdapter);
14376#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053014377 goto free_mem;
14378 }
Siddharth Bhal76972212014-10-15 16:22:51 +053014379 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053014380 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070014381 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070014382 pAdapter->sessionId, &scanRequest, &scanId,
14383 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070014384
Jeff Johnson295189b2012-06-20 16:38:30 -070014385 if (eHAL_STATUS_SUCCESS != status)
14386 {
14387 hddLog(VOS_TRACE_LEVEL_ERROR,
14388 "%s: sme_ScanRequest returned error %d", __func__, status);
14389 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070014390 if(eHAL_STATUS_RESOURCES == status)
14391 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014392 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
14393 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070014394 status = -EBUSY;
14395 } else {
14396 status = -EIO;
14397 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014398 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014399
14400#ifdef FEATURE_WLAN_TDLS
14401 wlan_hdd_tdls_scan_done_callback(pAdapter);
14402#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014403 goto free_mem;
14404 }
14405
14406 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053014407 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070014408 pAdapter->request = request;
14409 pScanInfo->scanId = scanId;
14410
14411 complete(&pScanInfo->scan_req_completion_event);
14412
14413free_mem:
14414 if( scanRequest.SSIDs.SSIDList )
14415 {
14416 vos_mem_free(scanRequest.SSIDs.SSIDList);
14417 }
14418
14419 if( channelList )
14420 vos_mem_free( channelList );
14421
14422 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014423 return status;
14424}
14425
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014426int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
14427#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
14428 struct net_device *dev,
14429#endif
14430 struct cfg80211_scan_request *request)
14431{
14432 int ret;
14433
14434 vos_ssr_protect(__func__);
14435 ret = __wlan_hdd_cfg80211_scan(wiphy,
14436#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
14437 dev,
14438#endif
14439 request);
14440 vos_ssr_unprotect(__func__);
14441
14442 return ret;
14443}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014444
14445void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
14446{
14447 v_U8_t iniDot11Mode =
14448 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
14449 eHddDot11Mode hddDot11Mode = iniDot11Mode;
14450
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014451 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
14452 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014453 switch ( iniDot11Mode )
14454 {
14455 case eHDD_DOT11_MODE_AUTO:
14456 case eHDD_DOT11_MODE_11ac:
14457 case eHDD_DOT11_MODE_11ac_ONLY:
14458#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053014459 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
14460 sme_IsFeatureSupportedByFW(DOT11AC) )
14461 hddDot11Mode = eHDD_DOT11_MODE_11ac;
14462 else
14463 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014464#else
14465 hddDot11Mode = eHDD_DOT11_MODE_11n;
14466#endif
14467 break;
14468 case eHDD_DOT11_MODE_11n:
14469 case eHDD_DOT11_MODE_11n_ONLY:
14470 hddDot11Mode = eHDD_DOT11_MODE_11n;
14471 break;
14472 default:
14473 hddDot11Mode = iniDot11Mode;
14474 break;
14475 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053014476#ifdef WLAN_FEATURE_AP_HT40_24G
14477 if (operationChannel > SIR_11B_CHANNEL_END)
14478#endif
14479 {
14480 /* This call decides required channel bonding mode */
14481 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014482 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
Abhishek Singh02b823e2017-10-30 17:53:20 +053014483 operationChannel, eHT_MAX_CHANNEL_WIDTH);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053014484 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014485}
14486
Jeff Johnson295189b2012-06-20 16:38:30 -070014487/*
14488 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014489 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070014490 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014491int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053014492 const u8 *ssid, size_t ssid_len, const u8 *bssid,
14493 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070014494{
14495 int status = 0;
14496 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080014497 hdd_context_t *pHddCtx;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053014498 hdd_station_ctx_t *hdd_sta_ctx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014499 v_U32_t roamId;
14500 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070014501 eCsrAuthType RSNAuthType;
14502
14503 ENTER();
14504
14505 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080014506 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053014507 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080014508
14509 status = wlan_hdd_validate_context(pHddCtx);
14510 if (status)
14511 {
Yue Mae36e3552014-03-05 17:06:20 -080014512 return status;
14513 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014514
Jeff Johnson295189b2012-06-20 16:38:30 -070014515 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
14516 {
14517 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
14518 return -EINVAL;
14519 }
14520
Nitesh Shah9b066282017-06-06 18:05:52 +053014521 wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
14522
Jeff Johnson295189b2012-06-20 16:38:30 -070014523 pRoamProfile = &pWextState->roamProfile;
14524
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014525 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070014526 {
Jeff Johnsone7245742012-09-05 17:12:55 -070014527 hdd_station_ctx_t *pHddStaCtx;
14528 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Abhishek Singh6782c9e2017-06-06 13:37:45 +053014529 pHddStaCtx->get_mgmt_log_sent = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014530
Siddharth Bhalda0d1622015-04-24 15:47:49 +053014531 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
14532
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014533 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070014534 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
14535 {
14536 /*QoS not enabled in cfg file*/
14537 pRoamProfile->uapsd_mask = 0;
14538 }
14539 else
14540 {
14541 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014542 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070014543 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
14544 }
14545
14546 pRoamProfile->SSIDs.numOfSSIDs = 1;
14547 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
14548 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014549 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070014550 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
14551 ssid, ssid_len);
14552
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014553 vos_mem_zero(pRoamProfile->BSSIDs.bssid, WNI_CFG_BSSID_LEN);
14554 vos_mem_zero(pRoamProfile->bssid_hint, WNI_CFG_BSSID_LEN);
14555
Jeff Johnson295189b2012-06-20 16:38:30 -070014556 if (bssid)
14557 {
14558 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014559 vos_mem_copy(pRoamProfile->BSSIDs.bssid, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070014560 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014561 /* Save BSSID in seperate variable as well, as RoamProfile
14562 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070014563 case of join failure we should send valid BSSID to supplicant
14564 */
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014565 vos_mem_copy(pWextState->req_bssId, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070014566 WNI_CFG_BSSID_LEN);
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014567
Jeff Johnson295189b2012-06-20 16:38:30 -070014568 }
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014569 else if (bssid_hint)
Dhanashri Atre51981c62013-06-13 11:47:57 -070014570 {
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014571 /* Store bssid_hint to use in the scan filter. */
14572 vos_mem_copy(pRoamProfile->bssid_hint, bssid_hint,
14573 WNI_CFG_BSSID_LEN);
14574 /*
14575 * Save BSSID in seperate variable as well, as RoamProfile
14576 * BSSID is getting zeroed out in the association process. And in
14577 * case of join failure we should send valid BSSID to supplicant
14578 */
14579 vos_mem_copy(pWextState->req_bssId, bssid_hint,
14580 WNI_CFG_BSSID_LEN);
14581 hddLog(LOG1, FL(" bssid_hint: "MAC_ADDRESS_STR),
14582 MAC_ADDR_ARRAY(pRoamProfile->bssid_hint));
Dhanashri Atre51981c62013-06-13 11:47:57 -070014583 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014584
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014585
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014586 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
14587 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070014588 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
14589 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014590 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014591 /*set gen ie*/
14592 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
14593 /*set auth*/
14594 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
14595 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014596#ifdef FEATURE_WLAN_WAPI
14597 if (pAdapter->wapi_info.nWapiMode)
14598 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014599 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014600 switch (pAdapter->wapi_info.wapiAuthMode)
14601 {
14602 case WAPI_AUTH_MODE_PSK:
14603 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014604 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014605 pAdapter->wapi_info.wapiAuthMode);
14606 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
14607 break;
14608 }
14609 case WAPI_AUTH_MODE_CERT:
14610 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014611 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014612 pAdapter->wapi_info.wapiAuthMode);
14613 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
14614 break;
14615 }
14616 } // End of switch
14617 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
14618 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
14619 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014620 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014621 pRoamProfile->AuthType.numEntries = 1;
14622 pRoamProfile->EncryptionType.numEntries = 1;
14623 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
14624 pRoamProfile->mcEncryptionType.numEntries = 1;
14625 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
14626 }
14627 }
14628#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014629#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014630 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014631 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
14632 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
14633 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014634 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
14635 sizeof (tSirGtkOffloadParams));
14636 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014637 }
14638#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014639 pRoamProfile->csrPersona = pAdapter->device_mode;
14640
Jeff Johnson32d95a32012-09-10 13:15:23 -070014641 if( operatingChannel )
14642 {
14643 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
14644 pRoamProfile->ChannelInfo.numOfChannels = 1;
14645 }
Chet Lanctot186b5732013-03-18 10:26:30 -070014646 else
14647 {
14648 pRoamProfile->ChannelInfo.ChannelList = NULL;
14649 pRoamProfile->ChannelInfo.numOfChannels = 0;
14650 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014651 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
14652 {
14653 hdd_select_cbmode(pAdapter,operatingChannel);
14654 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014655
Agarwal Ashish40f9b872015-09-01 16:17:35 +053014656 /*
14657 * Change conn_state to connecting before sme_RoamConnect(),
14658 * because sme_RoamConnect() has a direct path to call
14659 * hdd_smeRoamCallback(), which will change the conn_state
14660 * If direct path, conn_state will be accordingly changed
14661 * to NotConnected or Associated by either
14662 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
14663 * in sme_RoamCallback()
14664 * if sme_RomConnect is to be queued,
14665 * Connecting state will remain until it is completed.
14666 * If connection state is not changed,
14667 * connection state will remain in eConnectionState_NotConnected state.
14668 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
14669 * if conn state is eConnectionState_NotConnected.
14670 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
14671 * informed of connect result indication which is an issue.
14672 */
14673
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053014674 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
14675 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053014676 {
14677 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053014678 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080014679 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
14680 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053014681 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014682 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070014683 pAdapter->sessionId, pRoamProfile, &roamId);
14684
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053014685 if ((eHAL_STATUS_SUCCESS != status) &&
14686 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
14687 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053014688
14689 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053014690 hddLog(VOS_TRACE_LEVEL_ERROR,
14691 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
14692 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080014693 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053014694 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080014695 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053014696 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080014697
14698 pRoamProfile->ChannelInfo.ChannelList = NULL;
14699 pRoamProfile->ChannelInfo.numOfChannels = 0;
14700
Jeff Johnson295189b2012-06-20 16:38:30 -070014701 }
14702 else
14703 {
14704 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
14705 return -EINVAL;
14706 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080014707 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014708 return status;
14709}
14710
14711/*
14712 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
14713 * This function is used to set the authentication type (OPEN/SHARED).
14714 *
14715 */
14716static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
14717 enum nl80211_auth_type auth_type)
14718{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014719 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014720 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14721
14722 ENTER();
14723
14724 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014725 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070014726 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014727 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053014728 hddLog(VOS_TRACE_LEVEL_INFO,
14729 "%s: set authentication type to AUTOSWITCH", __func__);
14730 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
14731 break;
14732
14733 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014734#ifdef WLAN_FEATURE_VOWIFI_11R
14735 case NL80211_AUTHTYPE_FT:
14736#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014737 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070014738 "%s: set authentication type to OPEN", __func__);
14739 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
14740 break;
14741
14742 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014743 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070014744 "%s: set authentication type to SHARED", __func__);
14745 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
14746 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080014747#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070014748 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014749 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070014750 "%s: set authentication type to CCKM WPA", __func__);
14751 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
14752 break;
14753#endif
14754
14755
14756 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014757 hddLog(VOS_TRACE_LEVEL_ERROR,
14758 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014759 auth_type);
14760 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
14761 return -EINVAL;
14762 }
14763
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014764 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070014765 pHddStaCtx->conn_info.authType;
14766 return 0;
14767}
14768
14769/*
14770 * FUNCTION: wlan_hdd_set_akm_suite
14771 * This function is used to set the key mgmt type(PSK/8021x).
14772 *
14773 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014774static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014775 u32 key_mgmt
14776 )
14777{
14778 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
14779 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053014780 /* Should be in ieee802_11_defs.h */
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053014781#ifndef WLAN_AKM_SUITE_8021X_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053014782#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053014783#endif
14784#ifndef WLAN_AKM_SUITE_PSK_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053014785#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053014786#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014787 /*set key mgmt type*/
14788 switch(key_mgmt)
14789 {
14790 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053014791 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053014792#ifdef WLAN_FEATURE_VOWIFI_11R
14793 case WLAN_AKM_SUITE_FT_PSK:
14794#endif
14795 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070014796 __func__);
14797 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
14798 break;
14799
14800 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053014801 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053014802#ifdef WLAN_FEATURE_VOWIFI_11R
14803 case WLAN_AKM_SUITE_FT_8021X:
14804#endif
14805 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070014806 __func__);
14807 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
14808 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080014809#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070014810#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
14811#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
14812 case WLAN_AKM_SUITE_CCKM:
14813 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
14814 __func__);
14815 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
14816 break;
14817#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070014818#ifndef WLAN_AKM_SUITE_OSEN
14819#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
14820 case WLAN_AKM_SUITE_OSEN:
14821 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
14822 __func__);
14823 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
14824 break;
14825#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014826
14827 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014828 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014829 __func__, key_mgmt);
14830 return -EINVAL;
14831
14832 }
14833 return 0;
14834}
14835
14836/*
14837 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014838 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070014839 * (NONE/WEP40/WEP104/TKIP/CCMP).
14840 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014841static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
14842 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070014843 bool ucast
14844 )
14845{
14846 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014847 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014848 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14849
14850 ENTER();
14851
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014852 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070014853 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053014854 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070014855 __func__, cipher);
14856 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
14857 }
14858 else
14859 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014860
Jeff Johnson295189b2012-06-20 16:38:30 -070014861 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014862 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070014863 {
14864 case IW_AUTH_CIPHER_NONE:
14865 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
14866 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014867
Jeff Johnson295189b2012-06-20 16:38:30 -070014868 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053014869 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070014870 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014871
Jeff Johnson295189b2012-06-20 16:38:30 -070014872 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053014873 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070014874 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014875
Jeff Johnson295189b2012-06-20 16:38:30 -070014876 case WLAN_CIPHER_SUITE_TKIP:
14877 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
14878 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014879
Jeff Johnson295189b2012-06-20 16:38:30 -070014880 case WLAN_CIPHER_SUITE_CCMP:
14881 encryptionType = eCSR_ENCRYPT_TYPE_AES;
14882 break;
14883#ifdef FEATURE_WLAN_WAPI
14884 case WLAN_CIPHER_SUITE_SMS4:
14885 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
14886 break;
14887#endif
14888
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080014889#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070014890 case WLAN_CIPHER_SUITE_KRK:
14891 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
14892 break;
14893#endif
14894 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014895 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014896 __func__, cipher);
14897 return -EOPNOTSUPP;
14898 }
14899 }
14900
14901 if (ucast)
14902 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014903 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014904 __func__, encryptionType);
14905 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
14906 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014907 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070014908 encryptionType;
14909 }
14910 else
14911 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014912 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014913 __func__, encryptionType);
14914 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
14915 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
14916 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
14917 }
14918
14919 return 0;
14920}
14921
14922
14923/*
14924 * FUNCTION: wlan_hdd_cfg80211_set_ie
14925 * This function is used to parse WPA/RSN IE's.
14926 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014927int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014928#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14929 const u8 *ie,
14930#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014931 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014932#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014933 size_t ie_len
14934 )
14935{
14936 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014937#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14938 const u8 *genie = ie;
14939#else
Jeff Johnson295189b2012-06-20 16:38:30 -070014940 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014941#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014942 v_U16_t remLen = ie_len;
14943#ifdef FEATURE_WLAN_WAPI
14944 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
14945 u16 *tmp;
14946 v_U16_t akmsuiteCount;
14947 int *akmlist;
14948#endif
14949 ENTER();
14950
14951 /* clear previous assocAddIE */
14952 pWextState->assocAddIE.length = 0;
14953 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070014954 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014955
14956 while (remLen >= 2)
14957 {
14958 v_U16_t eLen = 0;
14959 v_U8_t elementId;
14960 elementId = *genie++;
14961 eLen = *genie++;
14962 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014963
Nachiket Kukade4aba5f02017-06-09 15:43:48 +053014964 /* Sanity check on eLen */
14965 if (eLen > remLen) {
14966 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid IE length[%d] for IE[0x%X]",
14967 __func__, eLen, elementId);
14968 VOS_ASSERT(0);
14969 return -EINVAL;
14970 }
14971
Arif Hussain6d2a3322013-11-17 19:50:10 -080014972 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070014973 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014974
14975 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070014976 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014977 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014978 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 -070014979 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014980 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014981 "%s: Invalid WPA IE", __func__);
14982 return -EINVAL;
14983 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014984 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070014985 {
14986 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014987 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070014988 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014989
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014990 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070014991 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014992 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
14993 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070014994 VOS_ASSERT(0);
14995 return -ENOMEM;
14996 }
14997 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
14998 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14999 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015000
Jeff Johnson295189b2012-06-20 16:38:30 -070015001 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
15002 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15003 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15004 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015005 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
15006 {
Nachiket Kukade3d72b7e2017-06-09 16:58:24 +053015007 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
15008 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d]",
15009 __func__, eLen);
15010 VOS_ASSERT(0);
15011 return -EINVAL;
15012 }
15013
Jeff Johnson295189b2012-06-20 16:38:30 -070015014 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
15015 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
15016 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
15017 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
15018 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
15019 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015020 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053015021 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070015022 {
15023 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015024 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070015025 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015026
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015027 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015028 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015029 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15030 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070015031 VOS_ASSERT(0);
15032 return -ENOMEM;
15033 }
15034 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
15035 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15036 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015037
Jeff Johnson295189b2012-06-20 16:38:30 -070015038 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15039 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15040 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015041#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015042 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
15043 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015044 /*Consider WFD IE, only for P2P Client */
15045 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
15046 {
15047 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015048 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070015049 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015050
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015051 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015052 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015053 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15054 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070015055 VOS_ASSERT(0);
15056 return -ENOMEM;
15057 }
15058 // WFD IE is saved to Additional IE ; it should be accumulated to handle
15059 // WPS IE + P2P IE + WFD IE
15060 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15061 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015062
Jeff Johnson295189b2012-06-20 16:38:30 -070015063 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15064 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15065 }
15066#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015067 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015068 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015069 HS20_OUI_TYPE_SIZE)) )
15070 {
15071 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015072 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015073 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015074
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015075 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015076 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015077 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15078 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015079 VOS_ASSERT(0);
15080 return -ENOMEM;
15081 }
15082 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15083 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015084
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015085 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15086 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15087 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070015088 /* Appending OSEN Information Element in Assiciation Request */
15089 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
15090 OSEN_OUI_TYPE_SIZE)) )
15091 {
15092 v_U16_t curAddIELen = pWextState->assocAddIE.length;
15093 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
15094 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015095
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015096 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070015097 {
15098 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15099 "Need bigger buffer space");
15100 VOS_ASSERT(0);
15101 return -ENOMEM;
15102 }
15103 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15104 pWextState->assocAddIE.length += eLen + 2;
15105
15106 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
15107 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15108 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15109 }
15110
Abhishek Singh4322e622015-06-10 15:42:54 +053015111 /* Update only for WPA IE */
15112 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
15113 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070015114
15115 /* populating as ADDIE in beacon frames */
15116 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015117 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070015118 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
15119 {
15120 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
15121 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
15122 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
15123 {
15124 hddLog(LOGE,
15125 "Coldn't pass "
15126 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
15127 }
15128 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
15129 else
15130 hddLog(LOGE,
15131 "Could not pass on "
15132 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
15133
15134 /* IBSS mode doesn't contain params->proberesp_ies still
15135 beaconIE's need to be populated in probe response frames */
15136 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
15137 {
15138 u16 rem_probe_resp_ie_len = eLen + 2;
15139 u8 probe_rsp_ie_len[3] = {0};
15140 u8 counter = 0;
15141
15142 /* Check Probe Resp Length if it is greater then 255 then
15143 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
15144 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
15145 not able Store More then 255 bytes into One Variable */
15146
15147 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
15148 {
15149 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
15150 {
15151 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
15152 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
15153 }
15154 else
15155 {
15156 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
15157 rem_probe_resp_ie_len = 0;
15158 }
15159 }
15160
15161 rem_probe_resp_ie_len = 0;
15162
15163 if (probe_rsp_ie_len[0] > 0)
15164 {
15165 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
15166 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
15167 (tANI_U8*)(genie - 2),
15168 probe_rsp_ie_len[0], NULL,
15169 eANI_BOOLEAN_FALSE)
15170 == eHAL_STATUS_FAILURE)
15171 {
15172 hddLog(LOGE,
15173 "Could not pass"
15174 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
15175 }
15176 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
15177 }
15178
15179 if (probe_rsp_ie_len[1] > 0)
15180 {
15181 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
15182 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
15183 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
15184 probe_rsp_ie_len[1], NULL,
15185 eANI_BOOLEAN_FALSE)
15186 == eHAL_STATUS_FAILURE)
15187 {
15188 hddLog(LOGE,
15189 "Could not pass"
15190 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
15191 }
15192 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
15193 }
15194
15195 if (probe_rsp_ie_len[2] > 0)
15196 {
15197 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
15198 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
15199 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
15200 probe_rsp_ie_len[2], NULL,
15201 eANI_BOOLEAN_FALSE)
15202 == eHAL_STATUS_FAILURE)
15203 {
15204 hddLog(LOGE,
15205 "Could not pass"
15206 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
15207 }
15208 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
15209 }
15210
15211 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
15212 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
15213 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
15214 {
15215 hddLog(LOGE,
15216 "Could not pass"
15217 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
15218 }
15219 }
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070015220 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070015221 break;
15222 case DOT11F_EID_RSN:
15223 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
15224 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
15225 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
15226 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
15227 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
15228 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053015229
Abhishek Singhb16f3562016-01-20 11:08:32 +053015230 /* Appending extended capabilities with Interworking or
15231 * bsstransition bit set in Assoc Req.
Abhishek Singh15d95602015-03-24 15:52:57 +053015232 *
15233 * In assoc req this EXT Cap will only be taken into account if
Abhishek Singhb16f3562016-01-20 11:08:32 +053015234 * interworkingService or bsstransition bit is set to 1.
15235 * Driver is only interested in interworkingService and
15236 * bsstransition capability from supplicant.
15237 * If in future any other EXT Cap info is
Abhishek Singh15d95602015-03-24 15:52:57 +053015238 * required from supplicat, it needs to be handled while
15239 * sending Assoc Req in LIM.
15240 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015241 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015242 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015243 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015244 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015245 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015246
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015247 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015248 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015249 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15250 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015251 VOS_ASSERT(0);
15252 return -ENOMEM;
15253 }
15254 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15255 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015256
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015257 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15258 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15259 break;
15260 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015261#ifdef FEATURE_WLAN_WAPI
15262 case WLAN_EID_WAPI:
15263 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070015264 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070015265 pAdapter->wapi_info.nWapiMode);
15266 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015267 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070015268 akmsuiteCount = WPA_GET_LE16(tmp);
15269 tmp = tmp + 1;
15270 akmlist = (int *)(tmp);
15271 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
15272 {
15273 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
15274 }
15275 else
15276 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015277 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070015278 VOS_ASSERT(0);
15279 return -EINVAL;
15280 }
15281
15282 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
15283 {
15284 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015285 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015286 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015287 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015288 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015289 {
Jeff Johnson295189b2012-06-20 16:38:30 -070015290 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015291 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015292 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
15293 }
15294 break;
15295#endif
15296 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015297 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015298 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015299 /* when Unknown IE is received we should break and continue
15300 * to the next IE in the buffer instead we were returning
15301 * so changing this to break */
15302 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070015303 }
15304 genie += eLen;
15305 remLen -= eLen;
15306 }
15307 EXIT();
15308 return 0;
15309}
15310
15311/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053015312 * FUNCTION: hdd_isWPAIEPresent
15313 * Parse the received IE to find the WPA IE
15314 *
15315 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015316static bool hdd_isWPAIEPresent(
15317#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
15318 const u8 *ie,
15319#else
15320 u8 *ie,
15321#endif
15322 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053015323{
15324 v_U8_t eLen = 0;
15325 v_U16_t remLen = ie_len;
15326 v_U8_t elementId = 0;
15327
15328 while (remLen >= 2)
15329 {
15330 elementId = *ie++;
15331 eLen = *ie++;
15332 remLen -= 2;
15333 if (eLen > remLen)
15334 {
15335 hddLog(VOS_TRACE_LEVEL_ERROR,
15336 "%s: IE length is wrong %d", __func__, eLen);
15337 return FALSE;
15338 }
15339 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
15340 {
15341 /* OUI - 0x00 0X50 0XF2
15342 WPA Information Element - 0x01
15343 WPA version - 0x01*/
15344 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
15345 return TRUE;
15346 }
15347 ie += eLen;
15348 remLen -= eLen;
15349 }
15350 return FALSE;
15351}
15352
15353/*
Jeff Johnson295189b2012-06-20 16:38:30 -070015354 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015355 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070015356 * parameters during connect operation.
15357 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015358int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070015359 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015360 )
Jeff Johnson295189b2012-06-20 16:38:30 -070015361{
15362 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015363 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070015364 ENTER();
15365
15366 /*set wpa version*/
15367 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
15368
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015369 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070015370 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053015371 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070015372 {
15373 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
15374 }
15375 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
15376 {
15377 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
15378 }
15379 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015380
15381 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015382 pWextState->wpaVersion);
15383
15384 /*set authentication type*/
15385 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
15386
15387 if (0 > status)
15388 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015389 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015390 "%s: failed to set authentication type ", __func__);
15391 return status;
15392 }
15393
15394 /*set key mgmt type*/
15395 if (req->crypto.n_akm_suites)
15396 {
15397 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
15398 if (0 > status)
15399 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015400 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070015401 __func__);
15402 return status;
15403 }
15404 }
15405
15406 /*set pairwise cipher type*/
15407 if (req->crypto.n_ciphers_pairwise)
15408 {
15409 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
15410 req->crypto.ciphers_pairwise[0], true);
15411 if (0 > status)
15412 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015413 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015414 "%s: failed to set unicast cipher type", __func__);
15415 return status;
15416 }
15417 }
15418 else
15419 {
15420 /*Reset previous cipher suite to none*/
15421 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
15422 if (0 > status)
15423 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015424 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015425 "%s: failed to set unicast cipher type", __func__);
15426 return status;
15427 }
15428 }
15429
15430 /*set group cipher type*/
15431 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
15432 false);
15433
15434 if (0 > status)
15435 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015436 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070015437 __func__);
15438 return status;
15439 }
15440
Chet Lanctot186b5732013-03-18 10:26:30 -070015441#ifdef WLAN_FEATURE_11W
15442 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
15443#endif
15444
Jeff Johnson295189b2012-06-20 16:38:30 -070015445 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
15446 if (req->ie_len)
15447 {
15448 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
15449 if ( 0 > status)
15450 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015451 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070015452 __func__);
15453 return status;
15454 }
15455 }
15456
15457 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015458 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070015459 {
15460 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
15461 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
15462 )
15463 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015464 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070015465 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
15466 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015467 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070015468 __func__);
15469 return -EOPNOTSUPP;
15470 }
15471 else
15472 {
15473 u8 key_len = req->key_len;
15474 u8 key_idx = req->key_idx;
15475
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015476 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070015477 && (CSR_MAX_NUM_KEY > key_idx)
15478 )
15479 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015480 hddLog(VOS_TRACE_LEVEL_INFO,
15481 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015482 __func__, key_idx, key_len);
15483 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015484 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070015485 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015486 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070015487 (u8)key_len;
15488 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
15489 }
15490 }
15491 }
15492 }
15493
15494 return status;
15495}
15496
15497/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015498 * FUNCTION: wlan_hdd_try_disconnect
15499 * This function is used to disconnect from previous
15500 * connection
15501 */
Agrawal Ashishc407f192017-01-23 17:18:35 +053015502int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015503{
15504 long ret = 0;
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015505 int status, result = 0;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015506 hdd_station_ctx_t *pHddStaCtx;
15507 eMib_dot11DesiredBssType connectedBssType;
Abhishek Singh19a7dd92015-12-30 16:31:51 +053015508 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015509
Abhishek Singh19a7dd92015-12-30 16:31:51 +053015510 ret = wlan_hdd_validate_context(pHddCtx);
15511 if (0 != ret)
15512 {
15513 return ret;
15514 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015515 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15516
15517 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
15518
15519 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
15520 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
Abhishek Singh630ff592016-01-07 18:15:53 +053015521 (eConnectionState_Connecting == pHddStaCtx->conn_info.connState) ||
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015522 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
15523 {
Abhishek Singh9f4df782017-03-15 17:29:10 +053015524 /* Indicate disconnect to SME so that in-progress connection or preauth
15525 * can be aborted
15526 */
15527 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
15528 pAdapter->sessionId);
Abhishek Singh19a7dd92015-12-30 16:31:51 +053015529 spin_lock_bh(&pAdapter->lock_for_active_session);
15530 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
15531 {
15532 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
15533 }
15534 spin_unlock_bh(&pAdapter->lock_for_active_session);
Abhishek Singhf7962582015-10-23 10:54:06 +053015535 hdd_connSetConnectionState(pHddStaCtx,
15536 eConnectionState_Disconnecting);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015537 /* Issue disconnect to CSR */
15538 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015539 status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015540 pAdapter->sessionId,
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015541 eCSR_DISCONNECT_REASON_UNSPECIFIED);
15542 if(eHAL_STATUS_CMD_NOT_QUEUED == status) {
15543 hddLog(LOG1,
15544 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
15545 } else if ( 0 != status ) {
15546 hddLog(LOGE,
15547 FL("csrRoamDisconnect failure, returned %d"),
15548 (int)status );
15549 result = -EINVAL;
15550 goto disconnected;
15551 }
15552 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015553 &pAdapter->disconnect_comp_var,
15554 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015555 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status)) {
15556 hddLog(LOGE,
15557 "%s: Failed to disconnect, timed out", __func__);
15558 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015559 }
15560 }
15561 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
15562 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015563 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015564 &pAdapter->disconnect_comp_var,
15565 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015566 if (!ret)
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015567 {
15568 hddLog(LOGE, FL("Failed to receive disconnect event"));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015569 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015570 }
15571 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015572disconnected:
15573 hddLog(LOG1,
15574 FL("Set HDD connState to eConnectionState_NotConnected"));
15575 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
15576 return result;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015577}
15578
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053015579/**
15580 * wlan_hdd_reassoc_bssid_hint() - Start reassociation if bssid is present
15581 * @adapter: Pointer to the HDD adapter
15582 * @req: Pointer to the structure cfg_connect_params receieved from user space
15583 *
15584 * This function will start reassociation if bssid hint, channel hint and
15585 * previous bssid parameters are present in the connect request
15586 *
15587 * Return: success if reassociation is happening
15588 * Error code if reassociation is not permitted or not happening
15589 */
15590#ifdef CFG80211_CONNECT_PREV_BSSID
15591static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
15592 struct cfg80211_connect_params *req)
15593{
15594 int status = -EPERM;
15595 if (req->bssid_hint && req->channel_hint && req->prev_bssid) {
15596 hddLog(VOS_TRACE_LEVEL_INFO,
15597 FL("REASSOC Attempt on channel %d to "MAC_ADDRESS_STR),
15598 req->channel_hint->hw_value,
15599 MAC_ADDR_ARRAY(req->bssid_hint));
15600 status = hdd_reassoc(adapter, req->bssid_hint,
15601 req->channel_hint->hw_value,
15602 CONNECT_CMD_USERSPACE);
15603 }
15604 return status;
15605}
15606#else
15607static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
15608 struct cfg80211_connect_params *req)
15609{
15610 return -EPERM;
15611}
15612#endif
15613
Abhishek Singhe3beee22017-07-31 15:35:40 +053015614/**
15615 * wlan_hdd_check_ht20_ht40_ind() - check if Supplicant has indicated to
15616 * connect in HT20 mode
15617 * @hdd_ctx: hdd context
15618 * @adapter: Pointer to the HDD adapter
15619 * @req: Pointer to the structure cfg_connect_params receieved from user space
15620 *
15621 * This function will check if supplicant has indicated to to connect in HT20
15622 * mode. this is currently applicable only for 2.4Ghz mode only.
15623 * if feature is enabled and supplicant indicate HT20 set
15624 * force_24ghz_in_ht20 to true to force 2.4Ghz in HT20 else set it to false.
15625 *
15626 * Return: void
15627 */
15628#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
15629static void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
15630 hdd_adapter_t *adapter,
15631 struct cfg80211_connect_params *req)
15632{
15633 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
15634 tCsrRoamProfile *roam_profile;
15635
15636 roam_profile = &wext_state->roamProfile;
15637 roam_profile->force_24ghz_in_ht20 = false;
15638 if (hdd_ctx->cfg_ini->override_ht20_40_24g &&
15639 !(req->ht_capa.cap_info &
15640 IEEE80211_HT_CAP_SUP_WIDTH_20_40))
15641 roam_profile->force_24ghz_in_ht20 = true;
15642
15643 hddLog(LOG1, FL("req->ht_capa.cap_info %x override_ht20_40_24g %d"),
15644 req->ht_capa.cap_info, hdd_ctx->cfg_ini->override_ht20_40_24g);
15645}
15646#else
15647static inline void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
15648 hdd_adapter_t *adapter,
15649 struct cfg80211_connect_params *req)
15650{
15651 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
15652 tCsrRoamProfile *roam_profile;
15653
15654 roam_profile = &wext_state->roamProfile;
15655 roam_profile->force_24ghz_in_ht20 = false;
15656}
15657#endif
15658
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015659/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053015660 * FUNCTION: __wlan_hdd_cfg80211_connect
15661 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070015662 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015663static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015664 struct net_device *ndev,
15665 struct cfg80211_connect_params *req
15666 )
15667{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015668 int status;
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053015669 u16 channel;
Edhar, Mahesh Kumar496c7f72016-03-18 12:47:44 +053015670#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) || \
15671 defined(CFG80211_BSSID_HINT_BACKPORT)
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053015672 const u8 *bssid_hint = req->bssid_hint;
15673#else
15674 const u8 *bssid_hint = NULL;
15675#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015676 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070015677 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053015678 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015679
15680 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015681
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015682 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15683 TRACE_CODE_HDD_CFG80211_CONNECT,
15684 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015685 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015686 "%s: device_mode = %s (%d)", __func__,
15687 hdd_device_modetoString(pAdapter->device_mode),
15688 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015689
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015690 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080015691 if (!pHddCtx)
15692 {
15693 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15694 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053015695 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080015696 }
15697
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015698 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015699 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070015700 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015701 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015702 }
15703
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053015704 status = wlan_hdd_reassoc_bssid_hint(pAdapter, req);
15705 if (0 == status)
15706 return status;
15707
Agarwal Ashish51325b52014-06-16 16:50:49 +053015708
Jeff Johnson295189b2012-06-20 16:38:30 -070015709#ifdef WLAN_BTAMP_FEATURE
15710 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015711 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070015712 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015713 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015714 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080015715 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070015716 }
15717#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015718
15719 //If Device Mode is Station Concurrent Sessions Exit BMps
15720 //P2P Mode will be taken care in Open/close adapter
15721 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053015722 (vos_concurrent_open_sessions_running())) {
15723 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
15724 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015725 }
15726
15727 /*Try disconnecting if already in connected state*/
15728 status = wlan_hdd_try_disconnect(pAdapter);
15729 if ( 0 > status)
15730 {
15731 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
15732 " connection"));
15733 return -EALREADY;
15734 }
Agrawal Ashish559530c2015-12-01 18:04:20 +053015735 /* Check for max concurrent connections after doing disconnect if any*/
15736 if (vos_max_concurrent_connections_reached()) {
15737 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
15738 return -ECONNREFUSED;
15739 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015740
Jeff Johnson295189b2012-06-20 16:38:30 -070015741 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015742 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070015743
15744 if ( 0 > status)
15745 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015746 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070015747 __func__);
15748 return status;
15749 }
Sravan Kumar Kairam589c5722016-01-27 20:28:53 +053015750
15751 if (pHddCtx->spoofMacAddr.isEnabled)
15752 {
15753 hddLog(VOS_TRACE_LEVEL_INFO,
15754 "%s: MAC Spoofing enabled ", __func__);
15755 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
15756 * to fill TxBds for probe request during SSID scan which may happen
15757 * as part of connect command
15758 */
15759 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
15760 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
15761 if (status != VOS_STATUS_SUCCESS)
15762 return -ECONNREFUSED;
15763 }
15764
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053015765 if (req->channel)
15766 channel = req->channel->hw_value;
Mohit Khanna765234a2012-09-11 15:08:35 -070015767 else
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053015768 channel = 0;
Kapil Gupta312028a2016-10-25 14:15:20 +053015769
15770 /* Abort if any scan is going on */
15771 status = wlan_hdd_scan_abort(pAdapter);
15772 if (0 != status)
15773 hddLog(VOS_TRACE_LEVEL_ERROR, FL("scan abort failed"));
15774
Abhishek Singhe3beee22017-07-31 15:35:40 +053015775 wlan_hdd_check_ht20_ht40_ind(pHddCtx, pAdapter, req);
15776
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053015777 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
15778 req->ssid_len, req->bssid,
15779 bssid_hint, channel);
Jeff Johnson295189b2012-06-20 16:38:30 -070015780
Sushant Kaushikd7083982015-03-18 14:33:24 +053015781 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070015782 {
15783 //ReEnable BMPS if disabled
15784 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
15785 (NULL != pHddCtx))
15786 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053015787 if (pHddCtx->hdd_wlan_suspended)
15788 {
15789 hdd_set_pwrparams(pHddCtx);
15790 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015791 //ReEnable Bmps and Imps back
15792 hdd_enable_bmps_imps(pHddCtx);
15793 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053015794 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070015795 return status;
15796 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015797 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015798 EXIT();
15799 return status;
15800}
15801
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015802static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
15803 struct net_device *ndev,
15804 struct cfg80211_connect_params *req)
15805{
15806 int ret;
15807 vos_ssr_protect(__func__);
15808 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
15809 vos_ssr_unprotect(__func__);
15810
15811 return ret;
15812}
Jeff Johnson295189b2012-06-20 16:38:30 -070015813
15814/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015815 * FUNCTION: wlan_hdd_disconnect
15816 * This function is used to issue a disconnect request to SME
15817 */
15818int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
15819{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015820 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015821 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015822 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053015823 long ret;
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053015824 eConnectionState prev_conn_state;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015825
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015826 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015827
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015828 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015829 if (0 != status)
15830 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015831 return status;
15832 }
Abhishek Singh07e4a892015-11-23 11:29:57 +053015833 /* Indicate sme of disconnect so that in progress connection or preauth
15834 * can be aborted
15835 */
15836 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
Sushant Kaushikb4834d22015-07-15 15:29:05 +053015837 pAdapter->sessionId);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015838 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053015839
Agarwal Ashish47d18112014-08-04 19:55:07 +053015840 /* Need to apply spin lock before decreasing active sessions
15841 * as there can be chance for double decrement if context switch
15842 * Calls hdd_DisConnectHandler.
15843 */
15844
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053015845 prev_conn_state = pHddStaCtx->conn_info.connState;
15846
Agarwal Ashish47d18112014-08-04 19:55:07 +053015847 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053015848 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
15849 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053015850 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
15851 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053015852 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
15853 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053015854
Abhishek Singhf4669da2014-05-26 15:07:49 +053015855 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053015856 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
15857
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015858 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015859
Mihir Shete182a0b22014-08-18 16:08:48 +053015860 /*
15861 * stop tx queues before deleting STA/BSS context from the firmware.
15862 * tx has to be disabled because the firmware can get busy dropping
15863 * the tx frames after BSS/STA has been deleted and will not send
15864 * back a response resulting in WDI timeout
15865 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053015866 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053015867 netif_tx_disable(pAdapter->dev);
15868 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015869
Mihir Shete182a0b22014-08-18 16:08:48 +053015870 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015871 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
15872 pAdapter->sessionId, reason);
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053015873 if((eHAL_STATUS_CMD_NOT_QUEUED == status) &&
15874 prev_conn_state != eConnectionState_Connecting)
15875 {
15876 hddLog(LOG1,
15877 FL("status = %d, already disconnected"), status);
15878 result = 0;
15879 goto disconnected;
15880 }
15881 /*
15882 * Wait here instead of returning directly, this will block the next
15883 * connect command and allow processing of the scan for ssid and
15884 * the previous connect command in CSR. Else we might hit some
15885 * race conditions leading to SME and HDD out of sync.
15886 */
15887 else if(eHAL_STATUS_CMD_NOT_QUEUED == status)
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015888 {
15889 hddLog(LOG1,
15890 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053015891 }
15892 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015893 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015894 hddLog(LOGE,
15895 FL("csrRoamDisconnect failure, returned %d"),
15896 (int)status);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015897 result = -EINVAL;
15898 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015899 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015900 ret = wait_for_completion_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015901 &pAdapter->disconnect_comp_var,
15902 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015903 if (!ret && (eHAL_STATUS_CMD_NOT_QUEUED != status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015904 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015905 hddLog(LOGE,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053015906 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015907 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053015908 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015909disconnected:
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015910 hddLog(LOG1,
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053015911 FL("Set HDD connState to eConnectionState_NotConnected"));
15912 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Mahesh A Saptasagar936ffc32016-05-25 11:27:43 +053015913#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
15914 /* Sending disconnect event to userspace for kernel version < 3.11
15915 * is handled by __cfg80211_disconnect call to __cfg80211_disconnected
15916 */
15917 hddLog(LOG1, FL("Send disconnected event to userspace"));
15918
Mahesh A Saptasagarf5859b12016-06-01 17:17:50 +053015919 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, true,
Mahesh A Saptasagar936ffc32016-05-25 11:27:43 +053015920 WLAN_REASON_UNSPECIFIED);
15921#endif
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053015922
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015923 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015924 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015925}
15926
15927
15928/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015929 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070015930 * This function is used to issue a disconnect request to SME
15931 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015932static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015933 struct net_device *dev,
15934 u16 reason
15935 )
15936{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015937 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015938 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053015939 tCsrRoamProfile *pRoamProfile;
15940 hdd_station_ctx_t *pHddStaCtx;
15941 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015942#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015943 tANI_U8 staIdx;
15944#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015945
Jeff Johnson295189b2012-06-20 16:38:30 -070015946 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015947
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053015948 if (!pAdapter) {
15949 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
15950 return -EINVAL;
15951 }
15952
15953 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15954 if (!pHddStaCtx) {
15955 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
15956 return -EINVAL;
15957 }
15958
15959 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15960 status = wlan_hdd_validate_context(pHddCtx);
15961 if (0 != status)
15962 {
15963 return status;
15964 }
15965
15966 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
15967
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015968 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15969 TRACE_CODE_HDD_CFG80211_DISCONNECT,
15970 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015971 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
15972 __func__, hdd_device_modetoString(pAdapter->device_mode),
15973 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015974
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015975 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
15976 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070015977
Jeff Johnson295189b2012-06-20 16:38:30 -070015978 if (NULL != pRoamProfile)
15979 {
15980 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053015981 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
15982 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070015983 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015984 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070015985 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015986 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070015987 switch(reason)
15988 {
15989 case WLAN_REASON_MIC_FAILURE:
15990 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
15991 break;
15992
15993 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
15994 case WLAN_REASON_DISASSOC_AP_BUSY:
15995 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
15996 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
15997 break;
15998
15999 case WLAN_REASON_PREV_AUTH_NOT_VALID:
16000 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053016001 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070016002 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
16003 break;
16004
Jeff Johnson295189b2012-06-20 16:38:30 -070016005 default:
16006 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
16007 break;
16008 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053016009 pScanInfo = &pHddCtx->scan_info;
16010 if (pScanInfo->mScanPending)
16011 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053016012 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053016013 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053016014 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053016015 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053016016 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053016017 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016018#ifdef FEATURE_WLAN_TDLS
16019 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080016020 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016021 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080016022 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
16023 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016024 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016025 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080016026 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053016027 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016028 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080016029 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016030 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016031 status = sme_DeleteTdlsPeerSta(
16032 WLAN_HDD_GET_HAL_CTX(pAdapter),
16033 pAdapter->sessionId,
16034 mac);
16035 if (status != eHAL_STATUS_SUCCESS) {
16036 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
16037 return -EPERM;
16038 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016039 }
16040 }
16041#endif
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053016042
16043 hddLog(LOG1, FL("Disconnecting with reasoncode:%u connState %d"),
16044 reasonCode,
16045 pHddStaCtx->conn_info.connState);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016046 status = wlan_hdd_disconnect(pAdapter, reasonCode);
16047 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070016048 {
16049 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080016050 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016051 __func__, (int)status );
16052 return -EINVAL;
16053 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016054 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053016055 else
16056 {
16057 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
16058 "called while in %d state", __func__,
16059 pHddStaCtx->conn_info.connState);
16060 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016061 }
16062 else
16063 {
16064 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
16065 }
16066
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016067 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016068 return status;
16069}
16070
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016071static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
16072 struct net_device *dev,
16073 u16 reason
16074 )
16075{
16076 int ret;
16077 vos_ssr_protect(__func__);
16078 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
16079 vos_ssr_unprotect(__func__);
16080
16081 return ret;
16082}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016083
Jeff Johnson295189b2012-06-20 16:38:30 -070016084/*
16085 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016086 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070016087 * settings in IBSS mode.
16088 */
16089static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016090 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070016091 struct cfg80211_ibss_params *params
16092 )
16093{
16094 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016095 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016096 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
16097 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016098
Jeff Johnson295189b2012-06-20 16:38:30 -070016099 ENTER();
16100
16101 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070016102 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070016103
16104 if (params->ie_len && ( NULL != params->ie) )
16105 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016106 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
16107 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070016108 {
16109 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
16110 encryptionType = eCSR_ENCRYPT_TYPE_AES;
16111 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016112 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070016113 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070016114 tDot11fIEWPA dot11WPAIE;
16115 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016116 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070016117
Wilson Yang00256342013-10-10 23:13:38 -070016118 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016119 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
16120 params->ie_len, DOT11F_EID_WPA);
16121 if ( NULL != ie )
16122 {
16123 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
16124 // Unpack the WPA IE
16125 //Skip past the EID byte and length byte - and four byte WiFi OUI
16126 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
16127 &ie[2+4],
16128 ie[1] - 4,
16129 &dot11WPAIE);
16130 /*Extract the multicast cipher, the encType for unicast
16131 cipher for wpa-none is none*/
16132 encryptionType =
16133 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
16134 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016135 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016136
Jeff Johnson295189b2012-06-20 16:38:30 -070016137 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
16138
16139 if (0 > status)
16140 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016141 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070016142 __func__);
16143 return status;
16144 }
16145 }
16146
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016147 pWextState->roamProfile.AuthType.authType[0] =
16148 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070016149 eCSR_AUTH_TYPE_OPEN_SYSTEM;
16150
16151 if (params->privacy)
16152 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016153 /* Security enabled IBSS, At this time there is no information available
16154 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070016155 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016156 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070016157 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016158 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070016159 *enable privacy bit in beacons */
16160
16161 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
16162 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070016163 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
16164 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070016165 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
16166 pWextState->roamProfile.EncryptionType.numEntries = 1;
16167 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070016168 return status;
16169}
16170
16171/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016172 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016173 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070016174 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016175static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016176 struct net_device *dev,
16177 struct cfg80211_ibss_params *params
16178 )
16179{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016180 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070016181 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
16182 tCsrRoamProfile *pRoamProfile;
16183 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016184 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16185 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016186 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070016187
16188 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016189
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016190 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16191 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
16192 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016193 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016194 "%s: device_mode = %s (%d)", __func__,
16195 hdd_device_modetoString(pAdapter->device_mode),
16196 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070016197
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016198 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016199 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070016200 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016201 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016202 }
16203
16204 if (NULL == pWextState)
16205 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016206 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070016207 __func__);
16208 return -EIO;
16209 }
16210
Agarwal Ashish51325b52014-06-16 16:50:49 +053016211 if (vos_max_concurrent_connections_reached()) {
16212 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
16213 return -ECONNREFUSED;
16214 }
16215
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016216 /*Try disconnecting if already in connected state*/
16217 status = wlan_hdd_try_disconnect(pAdapter);
16218 if ( 0 > status)
16219 {
16220 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
16221 " IBSS connection"));
16222 return -EALREADY;
16223 }
16224
Jeff Johnson295189b2012-06-20 16:38:30 -070016225 pRoamProfile = &pWextState->roamProfile;
16226
16227 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
16228 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016229 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080016230 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016231 return -EINVAL;
16232 }
16233
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070016234 /* BSSID is provided by upper layers hence no need to AUTO generate */
16235 if (NULL != params->bssid) {
16236 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
16237 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
16238 hddLog (VOS_TRACE_LEVEL_ERROR,
16239 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
16240 return -EIO;
16241 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016242 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070016243 }
krunal sonie9002db2013-11-25 14:24:17 -080016244 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
16245 {
16246 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
16247 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
16248 {
16249 hddLog (VOS_TRACE_LEVEL_ERROR,
16250 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
16251 return -EIO;
16252 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016253
16254 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080016255 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016256 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080016257 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070016258
Jeff Johnson295189b2012-06-20 16:38:30 -070016259 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070016260 if (NULL !=
16261#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
16262 params->chandef.chan)
16263#else
16264 params->channel)
16265#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016266 {
16267 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016268 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
16269 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
16270 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
16271 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070016272
16273 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016274 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070016275 ieee80211_frequency_to_channel(
16276#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
16277 params->chandef.chan->center_freq);
16278#else
16279 params->channel->center_freq);
16280#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016281
16282 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
16283 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070016284 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016285 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
16286 __func__);
16287 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070016288 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016289
16290 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070016291 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016292 if (channelNum == validChan[indx])
16293 {
16294 break;
16295 }
16296 }
16297 if (indx >= numChans)
16298 {
16299 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016300 __func__, channelNum);
16301 return -EINVAL;
16302 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016303 /* Set the Operational Channel */
16304 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
16305 channelNum);
16306 pRoamProfile->ChannelInfo.numOfChannels = 1;
16307 pHddStaCtx->conn_info.operationChannel = channelNum;
16308 pRoamProfile->ChannelInfo.ChannelList =
16309 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070016310 }
16311
16312 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016313 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070016314 if (status < 0)
16315 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016316 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070016317 __func__);
16318 return status;
16319 }
16320
16321 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016322 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Abhishek Singh4d924682015-11-17 15:23:06 +053016323 params->ssid_len, (const u8 *)&bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016324 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070016325
16326 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070016327 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016328
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016329 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016330 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016331}
16332
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016333static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
16334 struct net_device *dev,
16335 struct cfg80211_ibss_params *params
16336 )
16337{
16338 int ret = 0;
16339
16340 vos_ssr_protect(__func__);
16341 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
16342 vos_ssr_unprotect(__func__);
16343
16344 return ret;
16345}
16346
Jeff Johnson295189b2012-06-20 16:38:30 -070016347/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016348 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016349 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070016350 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016351static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016352 struct net_device *dev
16353 )
16354{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016355 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016356 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
16357 tCsrRoamProfile *pRoamProfile;
16358 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016359 int status;
Abhishek Singh69de3302016-11-11 16:44:32 +053016360 eHalStatus hal_status;
Abhishek Singh7cd040e2016-01-07 10:51:04 +053016361#ifdef WLAN_FEATURE_RMC
16362 tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN] = {0};
16363#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016364
16365 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016366
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016367 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16368 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
16369 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016370 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016371 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016372 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016373 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016374 }
16375
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016376 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
16377 hdd_device_modetoString(pAdapter->device_mode),
16378 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070016379 if (NULL == pWextState)
16380 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016381 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070016382 __func__);
16383 return -EIO;
16384 }
16385
16386 pRoamProfile = &pWextState->roamProfile;
16387
16388 /* Issue disconnect only if interface type is set to IBSS */
16389 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
16390 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016391 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070016392 __func__);
16393 return -EINVAL;
16394 }
16395
Abhishek Singh7cd040e2016-01-07 10:51:04 +053016396#ifdef WLAN_FEATURE_RMC
16397 /* Clearing add IE of beacon */
16398 if (ccmCfgSetStr(pHddCtx->hHal,
16399 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0],
16400 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN,
16401 NULL, eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
16402 {
16403 hddLog (VOS_TRACE_LEVEL_ERROR,
16404 "%s: unable to clear PROBE_RSP_BCN_ADDNIE_DATA", __func__);
16405 return -EINVAL;
16406 }
16407 if (ccmCfgSetInt(pHddCtx->hHal,
16408 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0, NULL,
16409 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
16410 {
16411 hddLog (VOS_TRACE_LEVEL_ERROR,
16412 "%s: unable to clear WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
16413 __func__);
16414 return -EINVAL;
16415 }
16416
16417 // Reset WNI_CFG_PROBE_RSP Flags
16418 wlan_hdd_reset_prob_rspies(pAdapter);
16419
16420 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
16421 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 0,NULL,
16422 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
16423 {
16424 hddLog (VOS_TRACE_LEVEL_ERROR,
16425 "%s: unable to clear WNI_CFG_PROBE_RSP_ADDNIE_FLAG",
16426 __func__);
16427 return -EINVAL;
16428 }
16429#endif
16430
Jeff Johnson295189b2012-06-20 16:38:30 -070016431 /* Issue Disconnect request */
16432 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singh69de3302016-11-11 16:44:32 +053016433 hal_status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
16434 pAdapter->sessionId,
16435 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
16436 if (!HAL_STATUS_SUCCESS(hal_status)) {
16437 hddLog(LOGE,
16438 FL("sme_RoamDisconnect failed hal_status(%d)"),
16439 hal_status);
16440 return -EAGAIN;
16441 }
16442 status = wait_for_completion_timeout(
16443 &pAdapter->disconnect_comp_var,
16444 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
16445 if (!status) {
16446 hddLog(LOGE,
16447 FL("wait on disconnect_comp_var failed"));
16448 return -ETIMEDOUT;
16449 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016450
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016451 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016452 return 0;
16453}
16454
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016455static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
16456 struct net_device *dev
16457 )
16458{
16459 int ret = 0;
16460
16461 vos_ssr_protect(__func__);
16462 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
16463 vos_ssr_unprotect(__func__);
16464
16465 return ret;
16466}
16467
Jeff Johnson295189b2012-06-20 16:38:30 -070016468/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016469 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070016470 * This function is used to set the phy parameters
16471 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
16472 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016473static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016474 u32 changed)
16475{
16476 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
16477 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016478 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016479
16480 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016481
16482 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016483 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
16484 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016485
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016486 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016487 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016488 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016489 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016490 }
16491
Jeff Johnson295189b2012-06-20 16:38:30 -070016492 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
16493 {
16494 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
16495 WNI_CFG_RTS_THRESHOLD_STAMAX :
16496 wiphy->rts_threshold;
16497
16498 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016499 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070016500 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016501 hddLog(VOS_TRACE_LEVEL_ERROR,
16502 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016503 __func__, rts_threshold);
16504 return -EINVAL;
16505 }
16506
16507 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
16508 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016509 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016510 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016511 hddLog(VOS_TRACE_LEVEL_ERROR,
16512 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016513 __func__, rts_threshold);
16514 return -EIO;
16515 }
16516
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016517 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016518 rts_threshold);
16519 }
16520
16521 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
16522 {
16523 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
16524 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
16525 wiphy->frag_threshold;
16526
16527 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016528 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016529 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016530 hddLog(VOS_TRACE_LEVEL_ERROR,
16531 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016532 frag_threshold);
16533 return -EINVAL;
16534 }
16535
16536 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
16537 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016538 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016539 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016540 hddLog(VOS_TRACE_LEVEL_ERROR,
16541 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016542 __func__, frag_threshold);
16543 return -EIO;
16544 }
16545
16546 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
16547 frag_threshold);
16548 }
16549
16550 if ((changed & WIPHY_PARAM_RETRY_SHORT)
16551 || (changed & WIPHY_PARAM_RETRY_LONG))
16552 {
16553 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
16554 wiphy->retry_short :
16555 wiphy->retry_long;
16556
16557 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
16558 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
16559 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016560 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016561 __func__, retry_value);
16562 return -EINVAL;
16563 }
16564
16565 if (changed & WIPHY_PARAM_RETRY_SHORT)
16566 {
16567 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
16568 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016569 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016570 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016571 hddLog(VOS_TRACE_LEVEL_ERROR,
16572 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016573 __func__, retry_value);
16574 return -EIO;
16575 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016576 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016577 __func__, retry_value);
16578 }
16579 else if (changed & WIPHY_PARAM_RETRY_SHORT)
16580 {
16581 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
16582 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016583 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016584 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016585 hddLog(VOS_TRACE_LEVEL_ERROR,
16586 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016587 __func__, retry_value);
16588 return -EIO;
16589 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016590 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016591 __func__, retry_value);
16592 }
16593 }
16594
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016595 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016596 return 0;
16597}
16598
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016599static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
16600 u32 changed)
16601{
16602 int ret;
16603
16604 vos_ssr_protect(__func__);
16605 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
16606 vos_ssr_unprotect(__func__);
16607
16608 return ret;
16609}
16610
Jeff Johnson295189b2012-06-20 16:38:30 -070016611/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016612 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070016613 * This function is used to set the txpower
16614 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016615static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070016616#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16617 struct wireless_dev *wdev,
16618#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016619#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016620 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070016621#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016622 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070016623#endif
16624 int dbm)
16625{
16626 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016627 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070016628 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
16629 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016630 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016631
16632 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016633
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016634 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16635 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
16636 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016637 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016638 if (0 != status)
16639 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016640 return status;
16641 }
16642
16643 hHal = pHddCtx->hHal;
16644
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016645 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
16646 dbm, ccmCfgSetCallback,
16647 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016648 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016649 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016650 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
16651 return -EIO;
16652 }
16653
16654 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
16655 dbm);
16656
16657 switch(type)
16658 {
16659 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
16660 /* Fall through */
16661 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
16662 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
16663 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016664 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
16665 __func__);
16666 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070016667 }
16668 break;
16669 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016670 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070016671 __func__);
16672 return -EOPNOTSUPP;
16673 break;
16674 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016675 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
16676 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070016677 return -EIO;
16678 }
16679
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016680 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016681 return 0;
16682}
16683
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016684static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
16685#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16686 struct wireless_dev *wdev,
16687#endif
16688#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
16689 enum tx_power_setting type,
16690#else
16691 enum nl80211_tx_power_setting type,
16692#endif
16693 int dbm)
16694{
16695 int ret;
16696 vos_ssr_protect(__func__);
16697 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
16698#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16699 wdev,
16700#endif
16701#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
16702 type,
16703#else
16704 type,
16705#endif
16706 dbm);
16707 vos_ssr_unprotect(__func__);
16708
16709 return ret;
16710}
16711
Jeff Johnson295189b2012-06-20 16:38:30 -070016712/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016713 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070016714 * This function is used to read the txpower
16715 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016716static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070016717#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16718 struct wireless_dev *wdev,
16719#endif
16720 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070016721{
16722
16723 hdd_adapter_t *pAdapter;
16724 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016725 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016726
Jeff Johnsone7245742012-09-05 17:12:55 -070016727 ENTER();
16728
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016729 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016730 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016731 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016732 *dbm = 0;
16733 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016734 }
16735
Jeff Johnson295189b2012-06-20 16:38:30 -070016736 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
16737 if (NULL == pAdapter)
16738 {
16739 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
16740 return -ENOENT;
16741 }
16742
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016743 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16744 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
16745 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070016746 wlan_hdd_get_classAstats(pAdapter);
16747 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
16748
Jeff Johnsone7245742012-09-05 17:12:55 -070016749 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016750 return 0;
16751}
16752
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016753static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
16754#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16755 struct wireless_dev *wdev,
16756#endif
16757 int *dbm)
16758{
16759 int ret;
16760
16761 vos_ssr_protect(__func__);
16762 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
16763#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16764 wdev,
16765#endif
16766 dbm);
16767 vos_ssr_unprotect(__func__);
16768
16769 return ret;
16770}
16771
Dustin Brown8c1d4092017-07-28 18:08:01 +053016772/*
16773 * wlan_hdd_fill_summary_stats() - populate station_info summary stats
16774 * @stats: summary stats to use as a source
16775 * @info: kernel station_info struct to use as a destination
16776 *
16777 * Return: None
16778 */
16779static void wlan_hdd_fill_summary_stats(tCsrSummaryStatsInfo *stats,
16780 struct station_info *info)
16781{
16782 int i;
16783
16784 info->rx_packets = stats->rx_frm_cnt;
16785 info->tx_packets = 0;
16786 info->tx_retries = 0;
16787 info->tx_failed = 0;
16788
16789 for (i = 0; i < 4; ++i) {
16790 info->tx_packets += stats->tx_frm_cnt[i];
16791 info->tx_retries += stats->multiple_retry_cnt[i];
16792 info->tx_failed += stats->fail_cnt[i];
16793 }
16794
16795 info->filled |= STATION_INFO_TX_PACKETS |
16796 STATION_INFO_TX_RETRIES |
16797 STATION_INFO_TX_FAILED |
16798 STATION_INFO_RX_PACKETS;
16799}
16800
16801/**
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053016802 * wlan_hdd_sap_get_sta_rssi() - get RSSI of the SAP client
16803 * @adapter: sap adapter pointer
16804 * @staid: station id of the client
16805 * @rssi: rssi value to fill
16806 *
16807 * Return: None
16808 */
16809static void
16810wlan_hdd_sap_get_sta_rssi(hdd_adapter_t *adapter, uint8_t staid, s8 *rssi)
16811{
16812 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
16813
16814 WLANTL_GetSAPStaRSSi(pVosContext, staid, rssi);
16815}
16816
16817/**
Dustin Brown8c1d4092017-07-28 18:08:01 +053016818 * wlan_hdd_get_sap_stats() - get aggregate SAP stats
16819 * @adapter: sap adapter to get stats for
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053016820 * @mac: mac address of the station
Dustin Brown8c1d4092017-07-28 18:08:01 +053016821 * @info: kernel station_info struct to populate
16822 *
16823 * Fetch the vdev-level aggregate stats for the given SAP adapter. This is to
16824 * support "station dump" and "station get" for SAP vdevs, even though they
16825 * aren't technically stations.
16826 *
16827 * Return: errno
16828 */
16829static int
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053016830wlan_hdd_get_sap_stats(hdd_adapter_t *adapter,
16831#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16832 const u8* mac,
16833#else
16834 u8* mac,
16835#endif
16836 struct station_info *info)
Dustin Brown8c1d4092017-07-28 18:08:01 +053016837{
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053016838 v_MACADDR_t *peerMacAddr;
16839 uint8_t staid;
Dustin Brown8c1d4092017-07-28 18:08:01 +053016840 VOS_STATUS status;
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053016841 bool bc_mac_addr;
Dustin Brown8c1d4092017-07-28 18:08:01 +053016842
16843 status = wlan_hdd_get_station_stats(adapter);
16844 if (!VOS_IS_STATUS_SUCCESS(status)) {
16845 hddLog(VOS_TRACE_LEVEL_ERROR,
16846 "Failed to get SAP stats; status:%d", status);
16847 return 0;
16848 }
16849
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053016850 peerMacAddr = (v_MACADDR_t *)mac;
16851 bc_mac_addr = vos_is_macaddr_broadcast(peerMacAddr);
16852 staid = hdd_sta_id_find_from_mac_addr(adapter, peerMacAddr);
16853 hddLog(VOS_TRACE_LEVEL_INFO, "Get SAP stats for sta id:%d", staid);
16854
16855 if (staid < WLAN_MAX_STA_COUNT && !bc_mac_addr) {
16856 wlan_hdd_sap_get_sta_rssi(adapter, staid, &info->signal);
16857 info->filled |= STATION_INFO_SIGNAL;
16858 }
16859
Dustin Brown8c1d4092017-07-28 18:08:01 +053016860 wlan_hdd_fill_summary_stats(&adapter->hdd_stats.summary_stat, info);
16861
16862 return 0;
16863}
16864
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016865static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016866#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16867 const u8* mac,
16868#else
16869 u8* mac,
16870#endif
16871 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070016872{
16873 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
16874 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16875 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053016876 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070016877
16878 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
16879 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070016880
16881 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
16882 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
16883 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
16884 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
16885 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
16886 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
16887 tANI_U16 maxRate = 0;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053016888 int8_t snr = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070016889 tANI_U16 myRate;
16890 tANI_U16 currentRate = 0;
16891 tANI_U8 maxSpeedMCS = 0;
16892 tANI_U8 maxMCSIdx = 0;
16893 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053016894 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070016895 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016896 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016897
Leo Chang6f8870f2013-03-26 18:11:36 -070016898#ifdef WLAN_FEATURE_11AC
16899 tANI_U32 vht_mcs_map;
16900 eDataRate11ACMaxMcs vhtMaxMcs;
16901#endif /* WLAN_FEATURE_11AC */
16902
Jeff Johnsone7245742012-09-05 17:12:55 -070016903 ENTER();
16904
Dustin Brown8c1d4092017-07-28 18:08:01 +053016905 status = wlan_hdd_validate_context(pHddCtx);
16906 if (0 != status)
16907 {
16908 return status;
16909 }
16910
16911 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053016912 return wlan_hdd_get_sap_stats(pAdapter, mac, sinfo);
Dustin Brown8c1d4092017-07-28 18:08:01 +053016913
Jeff Johnson295189b2012-06-20 16:38:30 -070016914 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
16915 (0 == ssidlen))
16916 {
16917 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
16918 " Invalid ssidlen, %d", __func__, ssidlen);
16919 /*To keep GUI happy*/
16920 return 0;
16921 }
16922
Mukul Sharma811205f2014-07-09 21:07:30 +053016923 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
16924 {
16925 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16926 "%s: Roaming in progress, so unable to proceed this request", __func__);
Sachin Ahuja81ab1812016-08-19 21:35:58 +053016927 /* return a cached value */
16928 sinfo->signal = pAdapter->rssi;
Mukul Sharma811205f2014-07-09 21:07:30 +053016929 return 0;
16930 }
16931
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053016932 wlan_hdd_get_station_stats(pAdapter);
16933 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070016934
Kiet Lam3b17fc82013-09-27 05:24:08 +053016935 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053016936 wlan_hdd_get_snr(pAdapter, &snr);
16937 pHddStaCtx->conn_info.signal = sinfo->signal;
16938 pHddStaCtx->conn_info.noise = pHddStaCtx->conn_info.signal - snr;
Kiet Lam3b17fc82013-09-27 05:24:08 +053016939 sinfo->filled |= STATION_INFO_SIGNAL;
16940
c_hpothu09f19542014-05-30 21:53:31 +053016941 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053016942 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
16943 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053016944 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053016945 {
16946 rate_flags = pAdapter->maxRateFlags;
16947 }
c_hpothu44ff4e02014-05-08 00:13:57 +053016948
Jeff Johnson295189b2012-06-20 16:38:30 -070016949 //convert to the UI units of 100kbps
16950 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
16951
16952#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070016953 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 -070016954 sinfo->signal,
16955 pCfg->reportMaxLinkSpeed,
16956 myRate,
16957 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070016958 (int) pCfg->linkSpeedRssiMid,
16959 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070016960 (int) rate_flags,
16961 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070016962#endif //LINKSPEED_DEBUG_ENABLED
16963
16964 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
16965 {
16966 // we do not want to necessarily report the current speed
16967 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
16968 {
16969 // report the max possible speed
16970 rssidx = 0;
16971 }
16972 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
16973 {
16974 // report the max possible speed with RSSI scaling
16975 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
16976 {
16977 // report the max possible speed
16978 rssidx = 0;
16979 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070016980 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070016981 {
16982 // report middle speed
16983 rssidx = 1;
16984 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070016985 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
16986 {
16987 // report middle speed
16988 rssidx = 2;
16989 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016990 else
16991 {
16992 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070016993 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070016994 }
16995 }
16996 else
16997 {
16998 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
16999 hddLog(VOS_TRACE_LEVEL_ERROR,
17000 "%s: Invalid value for reportMaxLinkSpeed: %u",
17001 __func__, pCfg->reportMaxLinkSpeed);
17002 rssidx = 0;
17003 }
17004
17005 maxRate = 0;
17006
17007 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053017008 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
17009 OperationalRates, &ORLeng))
17010 {
17011 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
17012 /*To keep GUI happy*/
17013 return 0;
17014 }
17015
Jeff Johnson295189b2012-06-20 16:38:30 -070017016 for (i = 0; i < ORLeng; i++)
17017 {
Jeff Johnsone7245742012-09-05 17:12:55 -070017018 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070017019 {
17020 /* Validate Rate Set */
17021 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
17022 {
17023 currentRate = supported_data_rate[j].supported_rate[rssidx];
17024 break;
17025 }
17026 }
17027 /* Update MAX rate */
17028 maxRate = (currentRate > maxRate)?currentRate:maxRate;
17029 }
17030
17031 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053017032 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
17033 ExtendedRates, &ERLeng))
17034 {
17035 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
17036 /*To keep GUI happy*/
17037 return 0;
17038 }
17039
Jeff Johnson295189b2012-06-20 16:38:30 -070017040 for (i = 0; i < ERLeng; i++)
17041 {
Jeff Johnsone7245742012-09-05 17:12:55 -070017042 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070017043 {
17044 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
17045 {
17046 currentRate = supported_data_rate[j].supported_rate[rssidx];
17047 break;
17048 }
17049 }
17050 /* Update MAX rate */
17051 maxRate = (currentRate > maxRate)?currentRate:maxRate;
17052 }
c_hpothu79aab322014-07-14 21:11:01 +053017053
Kiet Lamb69f8dc2013-11-15 15:34:27 +053017054 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053017055 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053017056 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053017057 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070017058 {
c_hpothu79aab322014-07-14 21:11:01 +053017059 if (rate_flags & eHAL_TX_RATE_VHT80)
17060 mode = 2;
17061 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
17062 mode = 1;
17063 else
17064 mode = 0;
17065
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053017066 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
17067 MCSRates, &MCSLeng))
17068 {
17069 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
17070 /*To keep GUI happy*/
17071 return 0;
17072 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017073 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070017074#ifdef WLAN_FEATURE_11AC
17075 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017076 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070017077 {
Leo Chang6f8870f2013-03-26 18:11:36 -070017078 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017079 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070017080 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070017081 {
Leo Chang6f8870f2013-03-26 18:11:36 -070017082 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070017083 }
Leo Chang6f8870f2013-03-26 18:11:36 -070017084 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070017085 {
Leo Chang6f8870f2013-03-26 18:11:36 -070017086 maxMCSIdx = 7;
17087 }
17088 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
17089 {
17090 maxMCSIdx = 8;
17091 }
17092 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
17093 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017094 //VHT20 is supporting 0~8
17095 if (rate_flags & eHAL_TX_RATE_VHT20)
17096 maxMCSIdx = 8;
17097 else
17098 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070017099 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017100
c_hpothu79aab322014-07-14 21:11:01 +053017101 if (0 != rssidx)/*check for scaled */
17102 {
17103 //get middle rate MCS index if rssi=1/2
17104 for (i=0; i <= maxMCSIdx; i++)
17105 {
17106 if (sinfo->signal <= rssiMcsTbl[mode][i])
17107 {
17108 maxMCSIdx = i;
17109 break;
17110 }
17111 }
17112 }
17113
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017114 if (rate_flags & eHAL_TX_RATE_VHT80)
17115 {
17116 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
17117 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
17118 }
17119 else if (rate_flags & eHAL_TX_RATE_VHT40)
17120 {
17121 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
17122 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
17123 }
17124 else if (rate_flags & eHAL_TX_RATE_VHT20)
17125 {
17126 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
17127 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
17128 }
17129
Leo Chang6f8870f2013-03-26 18:11:36 -070017130 maxSpeedMCS = 1;
17131 if (currentRate > maxRate)
17132 {
17133 maxRate = currentRate;
17134 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017135
Leo Chang6f8870f2013-03-26 18:11:36 -070017136 }
17137 else
17138#endif /* WLAN_FEATURE_11AC */
17139 {
17140 if (rate_flags & eHAL_TX_RATE_HT40)
17141 {
17142 rateFlag |= 1;
17143 }
17144 if (rate_flags & eHAL_TX_RATE_SGI)
17145 {
17146 rateFlag |= 2;
17147 }
17148
Girish Gowli01abcee2014-07-31 20:18:55 +053017149 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053017150 if (rssidx == 1 || rssidx == 2)
17151 {
17152 //get middle rate MCS index if rssi=1/2
17153 for (i=0; i <= 7; i++)
17154 {
17155 if (sinfo->signal <= rssiMcsTbl[mode][i])
17156 {
17157 temp = i+1;
17158 break;
17159 }
17160 }
17161 }
c_hpothu79aab322014-07-14 21:11:01 +053017162
17163 for (i = 0; i < MCSLeng; i++)
17164 {
Leo Chang6f8870f2013-03-26 18:11:36 -070017165 for (j = 0; j < temp; j++)
17166 {
17167 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
17168 {
17169 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053017170 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070017171 break;
17172 }
17173 }
17174 if ((j < temp) && (currentRate > maxRate))
17175 {
17176 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070017177 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017178 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053017179 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070017180 }
17181 }
17182
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017183 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
17184 {
17185 maxRate = myRate;
17186 maxSpeedMCS = 1;
17187 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
17188 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017189 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053017190 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070017191 {
17192 maxRate = myRate;
17193 if (rate_flags & eHAL_TX_RATE_LEGACY)
17194 {
17195 maxSpeedMCS = 0;
17196 }
17197 else
17198 {
17199 maxSpeedMCS = 1;
17200 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
17201 }
17202 }
17203
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017204 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070017205 {
17206 sinfo->txrate.legacy = maxRate;
17207#ifdef LINKSPEED_DEBUG_ENABLED
17208 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
17209#endif //LINKSPEED_DEBUG_ENABLED
17210 }
17211 else
17212 {
17213 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070017214#ifdef WLAN_FEATURE_11AC
17215 sinfo->txrate.nss = 1;
17216 if (rate_flags & eHAL_TX_RATE_VHT80)
17217 {
17218 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017219 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070017220 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017221 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070017222 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017223 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
17224 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
17225 }
17226 else if (rate_flags & eHAL_TX_RATE_VHT20)
17227 {
17228 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
17229 }
17230#endif /* WLAN_FEATURE_11AC */
17231 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
17232 {
17233 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
17234 if (rate_flags & eHAL_TX_RATE_HT40)
17235 {
17236 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
17237 }
Leo Chang6f8870f2013-03-26 18:11:36 -070017238 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017239 if (rate_flags & eHAL_TX_RATE_SGI)
17240 {
17241 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
17242 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017243
Jeff Johnson295189b2012-06-20 16:38:30 -070017244#ifdef LINKSPEED_DEBUG_ENABLED
17245 pr_info("Reporting MCS rate %d flags %x\n",
17246 sinfo->txrate.mcs,
17247 sinfo->txrate.flags );
17248#endif //LINKSPEED_DEBUG_ENABLED
17249 }
17250 }
17251 else
17252 {
17253 // report current rate instead of max rate
17254
17255 if (rate_flags & eHAL_TX_RATE_LEGACY)
17256 {
17257 //provide to the UI in units of 100kbps
17258 sinfo->txrate.legacy = myRate;
17259#ifdef LINKSPEED_DEBUG_ENABLED
17260 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
17261#endif //LINKSPEED_DEBUG_ENABLED
17262 }
17263 else
17264 {
17265 //must be MCS
17266 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070017267#ifdef WLAN_FEATURE_11AC
17268 sinfo->txrate.nss = 1;
17269 if (rate_flags & eHAL_TX_RATE_VHT80)
17270 {
17271 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
17272 }
17273 else
17274#endif /* WLAN_FEATURE_11AC */
17275 {
17276 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
17277 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017278 if (rate_flags & eHAL_TX_RATE_SGI)
17279 {
17280 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
17281 }
17282 if (rate_flags & eHAL_TX_RATE_HT40)
17283 {
17284 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
17285 }
Leo Chang6f8870f2013-03-26 18:11:36 -070017286#ifdef WLAN_FEATURE_11AC
17287 else if (rate_flags & eHAL_TX_RATE_VHT80)
17288 {
17289 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
17290 }
17291#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070017292#ifdef LINKSPEED_DEBUG_ENABLED
17293 pr_info("Reporting actual MCS rate %d flags %x\n",
17294 sinfo->txrate.mcs,
17295 sinfo->txrate.flags );
17296#endif //LINKSPEED_DEBUG_ENABLED
17297 }
17298 }
17299 sinfo->filled |= STATION_INFO_TX_BITRATE;
17300
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070017301 sinfo->tx_packets =
17302 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
17303 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
17304 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
17305 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
17306
17307 sinfo->tx_retries =
17308 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
17309 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
17310 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
17311 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
17312
17313 sinfo->tx_failed =
17314 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
17315 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
17316 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
17317 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
17318
17319 sinfo->filled |=
17320 STATION_INFO_TX_PACKETS |
17321 STATION_INFO_TX_RETRIES |
17322 STATION_INFO_TX_FAILED;
17323
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053017324 sinfo->rx_packets = pAdapter->hdd_stats.summary_stat.rx_frm_cnt;
17325 sinfo->filled |= STATION_INFO_RX_PACKETS;
17326
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053017327 vos_mem_copy(&pHddStaCtx->conn_info.txrate,
17328 &sinfo->txrate, sizeof(sinfo->txrate));
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053017329 if (rate_flags & eHAL_TX_RATE_LEGACY)
17330 hddLog(LOG1, FL("Reporting RSSI:%d legacy rate %d pkt cnt tx %d rx %d"),
17331 sinfo->signal, sinfo->txrate.legacy, sinfo->tx_packets,
17332 sinfo->rx_packets);
17333 else
17334 hddLog(LOG1,
17335 FL("Reporting RSSI:%d MCS rate %d flags 0x%x pkt cnt tx %d rx %d"),
17336 sinfo->signal, sinfo->txrate.mcs, sinfo->txrate.flags,
17337 sinfo->tx_packets, sinfo->rx_packets);
17338
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017339 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17340 TRACE_CODE_HDD_CFG80211_GET_STA,
17341 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070017342 EXIT();
17343 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070017344}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017345#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
17346static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
17347 const u8* mac, struct station_info *sinfo)
17348#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017349static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
17350 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017351#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017352{
17353 int ret;
17354
17355 vos_ssr_protect(__func__);
17356 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
17357 vos_ssr_unprotect(__func__);
17358
17359 return ret;
17360}
17361
17362static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070017363 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070017364{
17365 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017366 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070017367 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017368 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017369
Jeff Johnsone7245742012-09-05 17:12:55 -070017370 ENTER();
17371
Jeff Johnson295189b2012-06-20 16:38:30 -070017372 if (NULL == pAdapter)
17373 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017374 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017375 return -ENODEV;
17376 }
17377
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017378 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17379 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
17380 pAdapter->sessionId, timeout));
17381
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017382 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017383 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017384 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017385 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017386 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017387 }
17388
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017389 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
17390 (TRUE == pHddCtx->hdd_wlan_suspended) &&
17391 (pHddCtx->cfg_ini->fhostArpOffload) &&
17392 (eConnectionState_Associated ==
17393 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
17394 {
Amar Singhald53568e2013-09-26 11:03:45 -070017395
17396 hddLog(VOS_TRACE_LEVEL_INFO,
17397 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053017398 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017399 if (!VOS_IS_STATUS_SUCCESS(vos_status))
17400 {
17401 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017402 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017403 __func__, vos_status);
17404 }
17405 }
17406
Jeff Johnson295189b2012-06-20 16:38:30 -070017407 /**The get power cmd from the supplicant gets updated by the nl only
17408 *on successful execution of the function call
17409 *we are oppositely mapped w.r.t mode in the driver
17410 **/
17411 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
17412
17413 if (VOS_STATUS_E_FAILURE == vos_status)
17414 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053017415 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17416 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017417 return -EINVAL;
17418 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017419 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017420 return 0;
17421}
17422
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017423static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
17424 struct net_device *dev, bool mode, int timeout)
17425{
17426 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070017427
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017428 vos_ssr_protect(__func__);
17429 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
17430 vos_ssr_unprotect(__func__);
17431
17432 return ret;
17433}
Sushant Kaushik084f6592015-09-10 13:11:56 +053017434
Jeff Johnson295189b2012-06-20 16:38:30 -070017435#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017436static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
17437 struct net_device *netdev,
17438 u8 key_index)
17439{
17440 ENTER();
17441 return 0;
17442}
17443
Jeff Johnson295189b2012-06-20 16:38:30 -070017444static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017445 struct net_device *netdev,
17446 u8 key_index)
17447{
17448 int ret;
17449 vos_ssr_protect(__func__);
17450 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
17451 vos_ssr_unprotect(__func__);
17452 return ret;
17453}
17454#endif //LINUX_VERSION_CODE
17455
17456#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
17457static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
17458 struct net_device *dev,
17459 struct ieee80211_txq_params *params)
17460{
17461 ENTER();
17462 return 0;
17463}
17464#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
17465static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
17466 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070017467{
Jeff Johnsone7245742012-09-05 17:12:55 -070017468 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070017469 return 0;
17470}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017471#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070017472
17473#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
17474static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017475 struct net_device *dev,
17476 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070017477{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017478 int ret;
17479
17480 vos_ssr_protect(__func__);
17481 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
17482 vos_ssr_unprotect(__func__);
17483 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070017484}
17485#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
17486static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
17487 struct ieee80211_txq_params *params)
17488{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017489 int ret;
17490
17491 vos_ssr_protect(__func__);
17492 ret = __wlan_hdd_set_txq_params(wiphy, params);
17493 vos_ssr_unprotect(__func__);
17494 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070017495}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017496#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017497
Naresh Jayaram69e3f282014-10-14 12:29:12 +053017498static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017499 struct net_device *dev,
17500 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070017501{
17502 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017503 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017504 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017505 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017506 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017507 v_CONTEXT_t pVosContext = NULL;
17508 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017509
Jeff Johnsone7245742012-09-05 17:12:55 -070017510 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017511
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017512 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070017513 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017514 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017515 return -EINVAL;
17516 }
17517
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017518 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17519 TRACE_CODE_HDD_CFG80211_DEL_STA,
17520 pAdapter->sessionId, pAdapter->device_mode));
17521
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017522 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17523 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017524 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017525 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017526 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017527 }
17528
Jeff Johnson295189b2012-06-20 16:38:30 -070017529 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070017530 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070017531 )
17532 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017533 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
17534 pSapCtx = VOS_GET_SAP_CB(pVosContext);
17535 if(pSapCtx == NULL){
17536 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17537 FL("psapCtx is NULL"));
17538 return -ENOENT;
17539 }
Agrawal Ashish306b75f2017-01-11 19:16:25 +053017540 if (pHddCtx->cfg_ini->enable_sap_auth_offload)
17541 {
17542 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
17543 "Change reason code to eSIR_MAC_DISASSOC_LEAVING_BSS_REASON in sap auth offload");
17544 pDelStaParams->reason_code = eSIR_MAC_DISASSOC_LEAVING_BSS_REASON;
17545 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017546 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070017547 {
17548 v_U16_t i;
17549 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
17550 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017551 if ((pSapCtx->aStaInfo[i].isUsed) &&
17552 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070017553 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017554 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017555 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017556 ETHER_ADDR_LEN);
17557
Jeff Johnson295189b2012-06-20 16:38:30 -070017558 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080017559 "%s: Delete STA with MAC::"
17560 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017561 __func__,
17562 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
17563 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070017564 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017565 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070017566 }
17567 }
17568 }
17569 else
17570 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017571
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017572 vos_status = hdd_softap_GetStaId(pAdapter,
17573 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017574 if (!VOS_IS_STATUS_SUCCESS(vos_status))
17575 {
17576 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080017577 "%s: Skip this DEL STA as this is not used::"
17578 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017579 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017580 return -ENOENT;
17581 }
17582
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017583 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017584 {
17585 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080017586 "%s: Skip this DEL STA as deauth is in progress::"
17587 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017588 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017589 return -ENOENT;
17590 }
17591
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017592 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017593
Jeff Johnson295189b2012-06-20 16:38:30 -070017594 hddLog(VOS_TRACE_LEVEL_INFO,
17595 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080017596 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070017597 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017598 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017599
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017600 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017601 if (!VOS_IS_STATUS_SUCCESS(vos_status))
17602 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017603 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017604 hddLog(VOS_TRACE_LEVEL_INFO,
17605 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080017606 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017607 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017608 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017609 return -ENOENT;
17610 }
17611
Jeff Johnson295189b2012-06-20 16:38:30 -070017612 }
17613 }
17614
17615 EXIT();
17616
17617 return 0;
17618}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053017619
17620#ifdef CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053017621int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Naresh Jayaram69e3f282014-10-14 12:29:12 +053017622 struct net_device *dev,
17623 struct station_del_parameters *param)
17624#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017625#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
Kapil Gupta137ef892016-12-13 19:38:00 +053017626int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017627 struct net_device *dev, const u8 *mac)
17628#else
Kapil Gupta137ef892016-12-13 19:38:00 +053017629int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017630 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053017631#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017632#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017633{
17634 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017635 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070017636
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017637 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017638
Naresh Jayaram69e3f282014-10-14 12:29:12 +053017639#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017640 if (NULL == param) {
17641 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017642 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017643 return -EINVAL;
17644 }
17645
17646 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
17647 param->subtype, &delStaParams);
17648
Naresh Jayaram69e3f282014-10-14 12:29:12 +053017649#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053017650 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017651 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053017652#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017653 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
17654
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017655 vos_ssr_unprotect(__func__);
17656
17657 return ret;
17658}
17659
17660static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017661 struct net_device *dev,
17662#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17663 const u8 *mac,
17664#else
17665 u8 *mac,
17666#endif
17667 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017668{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017669 hdd_adapter_t *pAdapter;
17670 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017671 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017672#ifdef FEATURE_WLAN_TDLS
17673 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017674
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017675 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017676
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017677 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17678 if (NULL == pAdapter)
17679 {
17680 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17681 "%s: Adapter is NULL",__func__);
17682 return -EINVAL;
17683 }
17684 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17685 status = wlan_hdd_validate_context(pHddCtx);
17686 if (0 != status)
17687 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017688 return status;
17689 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017690
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017691 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17692 TRACE_CODE_HDD_CFG80211_ADD_STA,
17693 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017694 mask = params->sta_flags_mask;
17695
17696 set = params->sta_flags_set;
17697
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017698 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017699 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
17700 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017701
17702 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
17703 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080017704 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017705 }
17706 }
17707#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017708 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017709 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017710}
17711
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017712#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
17713static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
17714 struct net_device *dev, const u8 *mac,
17715 struct station_parameters *params)
17716#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017717static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
17718 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017719#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017720{
17721 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017722
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017723 vos_ssr_protect(__func__);
17724 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
17725 vos_ssr_unprotect(__func__);
17726
17727 return ret;
17728}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017729#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070017730
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017731static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070017732 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017733{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017734 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17735 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017736 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017737 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017738 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017739 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070017740
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017741 ENTER();
17742
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017743 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017744 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017745 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017746 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017747 return -EINVAL;
17748 }
17749
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017750 if (!pmksa) {
17751 hddLog(LOGE, FL("pmksa is NULL"));
17752 return -EINVAL;
17753 }
17754
17755 if (!pmksa->bssid || !pmksa->pmkid) {
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070017756 hddLog(LOGE, FL("pmksa->bssid(%pK) or pmksa->pmkid(%pK) is NULL"),
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017757 pmksa->bssid, pmksa->pmkid);
17758 return -EINVAL;
17759 }
17760
17761 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
17762 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
17763
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017764 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17765 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017766 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017767 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017768 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017769 }
17770
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017771 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017772 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
17773
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017774 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
17775 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017776
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017777 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017778 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017779 &pmk_id, 1, FALSE);
17780
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017781 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17782 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
17783 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017784
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017785 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017786 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017787}
17788
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017789static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
17790 struct cfg80211_pmksa *pmksa)
17791{
17792 int ret;
17793
17794 vos_ssr_protect(__func__);
17795 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
17796 vos_ssr_unprotect(__func__);
17797
17798 return ret;
17799}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017800
Wilson Yang6507c4e2013-10-01 20:11:19 -070017801
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017802static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070017803 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017804{
Wilson Yang6507c4e2013-10-01 20:11:19 -070017805 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17806 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017807 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080017808 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017809
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017810 ENTER();
17811
Wilson Yang6507c4e2013-10-01 20:11:19 -070017812 /* Validate pAdapter */
17813 if (NULL == pAdapter)
17814 {
17815 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
17816 return -EINVAL;
17817 }
17818
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017819 if (!pmksa) {
17820 hddLog(LOGE, FL("pmksa is NULL"));
17821 return -EINVAL;
17822 }
17823
17824 if (!pmksa->bssid) {
17825 hddLog(LOGE, FL("pmksa->bssid is NULL"));
17826 return -EINVAL;
17827 }
17828
Kiet Lam98c46a12014-10-31 15:34:57 -070017829 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
17830 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
17831
Wilson Yang6507c4e2013-10-01 20:11:19 -070017832 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17833 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070017834 if (0 != status)
17835 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070017836 return status;
17837 }
17838
17839 /*Retrieve halHandle*/
17840 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
17841
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017842 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17843 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
17844 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017845 /* Delete the PMKID CSR cache */
17846 if (eHAL_STATUS_SUCCESS !=
17847 sme_RoamDelPMKIDfromCache(halHandle,
17848 pAdapter->sessionId, pmksa->bssid, FALSE)) {
17849 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
17850 MAC_ADDR_ARRAY(pmksa->bssid));
17851 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017852 }
17853
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017854 EXIT();
17855 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017856}
17857
Wilson Yang6507c4e2013-10-01 20:11:19 -070017858
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017859static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
17860 struct cfg80211_pmksa *pmksa)
17861{
17862 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017863
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017864 vos_ssr_protect(__func__);
17865 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
17866 vos_ssr_unprotect(__func__);
17867
17868 return ret;
17869
17870}
17871
17872static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017873{
Wilson Yang6507c4e2013-10-01 20:11:19 -070017874 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17875 tHalHandle halHandle;
17876 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080017877 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017878
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017879 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070017880
17881 /* Validate pAdapter */
17882 if (NULL == pAdapter)
17883 {
17884 hddLog(VOS_TRACE_LEVEL_ERROR,
17885 "%s: Invalid Adapter" ,__func__);
17886 return -EINVAL;
17887 }
17888
17889 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17890 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070017891 if (0 != status)
17892 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070017893 return status;
17894 }
17895
17896 /*Retrieve halHandle*/
17897 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
17898
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017899 /* Flush the PMKID cache in CSR */
17900 if (eHAL_STATUS_SUCCESS !=
17901 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
17902 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
17903 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017904 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017905 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080017906 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017907}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017908
17909static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
17910{
17911 int ret;
17912
17913 vos_ssr_protect(__func__);
17914 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
17915 vos_ssr_unprotect(__func__);
17916
17917 return ret;
17918}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017919#endif
17920
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017921#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017922static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
17923 struct net_device *dev,
17924 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017925{
17926 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17927 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017928 hdd_context_t *pHddCtx;
17929 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017930
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017931 ENTER();
17932
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017933 if (NULL == pAdapter)
17934 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017935 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017936 return -ENODEV;
17937 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017938 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17939 ret = wlan_hdd_validate_context(pHddCtx);
17940 if (0 != ret)
17941 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017942 return ret;
17943 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017944 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017945 if (NULL == pHddStaCtx)
17946 {
17947 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
17948 return -EINVAL;
17949 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017950
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017951 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17952 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
17953 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017954 // Added for debug on reception of Re-assoc Req.
17955 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
17956 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017957 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017958 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080017959 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017960 }
17961
17962#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080017963 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017964 ftie->ie_len);
17965#endif
17966
17967 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053017968 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
17969 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017970 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017971
17972 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017973 return 0;
17974}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017975
17976static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
17977 struct net_device *dev,
17978 struct cfg80211_update_ft_ies_params *ftie)
17979{
17980 int ret;
17981
17982 vos_ssr_protect(__func__);
17983 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
17984 vos_ssr_unprotect(__func__);
17985
17986 return ret;
17987}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017988#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017989
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017990#ifdef FEATURE_WLAN_SCAN_PNO
17991
17992void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
17993 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
17994{
17995 int ret;
17996 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
17997 hdd_context_t *pHddCtx;
17998
Nirav Shah80830bf2013-12-31 16:35:12 +053017999 ENTER();
18000
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018001 if (NULL == pAdapter)
18002 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053018003 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018004 "%s: HDD adapter is Null", __func__);
18005 return ;
18006 }
18007
18008 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18009 if (NULL == pHddCtx)
18010 {
18011 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18012 "%s: HDD context is Null!!!", __func__);
18013 return ;
18014 }
18015
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018016 spin_lock(&pHddCtx->schedScan_lock);
18017 if (TRUE == pHddCtx->isWiphySuspended)
18018 {
18019 pHddCtx->isSchedScanUpdatePending = TRUE;
18020 spin_unlock(&pHddCtx->schedScan_lock);
18021 hddLog(VOS_TRACE_LEVEL_INFO,
18022 "%s: Update cfg80211 scan database after it resume", __func__);
18023 return ;
18024 }
18025 spin_unlock(&pHddCtx->schedScan_lock);
18026
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018027 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
18028
18029 if (0 > ret)
18030 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagarfb49cdd2015-10-16 18:41:59 +053018031 else
18032 {
18033 /* Acquire wakelock to handle the case where APP's tries to suspend
18034 * immediatly after the driver gets connect request(i.e after pno)
18035 * from supplicant, this result in app's is suspending and not able
18036 * to process the connect request to AP */
18037 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
18038 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018039 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018040 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18041 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018042}
18043
18044/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018045 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053018046 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018047 */
18048static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
18049{
18050 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
18051 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018052 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018053 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18054 int status = 0;
Agrawal Ashishcff31692016-12-16 17:17:50 +053018055
18056 if (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
18057 {
18058 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18059 "%s: PNO is allowed only in STA interface", __func__);
18060 return eHAL_STATUS_FAILURE;
18061 }
18062
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018063 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
18064
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053018065 /* The current firmware design does not allow PNO during any
Agrawal Ashishcff31692016-12-16 17:17:50 +053018066 * active sessions. PNO is allowed only in case when sap session
18067 * is present and sapo auth offload feature enabled in firmare.
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053018068 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018069 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
18070 {
18071 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018072 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018073
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018074 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
18075 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
18076 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
18077 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
Agrawal Ashishcff31692016-12-16 17:17:50 +053018078 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode &&
18079 !pHddCtx->cfg_ini->enable_sap_auth_offload)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053018080 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018081 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018082 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018083 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018084 }
18085 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
18086 pAdapterNode = pNext;
18087 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018088 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018089}
18090
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018091void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
18092{
18093 hdd_adapter_t *pAdapter = callbackContext;
18094 hdd_context_t *pHddCtx;
18095
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018096 ENTER();
18097
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018098 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
18099 {
18100 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18101 FL("Invalid adapter or adapter has invalid magic"));
18102 return;
18103 }
18104
18105 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18106 if (0 != wlan_hdd_validate_context(pHddCtx))
18107 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018108 return;
18109 }
18110
c_hpothub53c45d2014-08-18 16:53:14 +053018111 if (VOS_STATUS_SUCCESS != status)
18112 {
18113 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018114 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053018115 pHddCtx->isPnoEnable = FALSE;
18116 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018117
18118 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
18119 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018120 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018121}
18122
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018123#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) || \
18124 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
18125/**
18126 * hdd_config_sched_scan_plan() - configures the sched scan plans
18127 * from the framework.
18128 * @pno_req: pointer to PNO scan request
18129 * @request: pointer to scan request from framework
18130 *
18131 * Return: None
18132 */
18133static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
18134 struct cfg80211_sched_scan_request *request,
18135 hdd_context_t *hdd_ctx)
18136{
18137 v_U32_t i = 0;
18138
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018139 pno_req->scanTimers.ucScanTimersCount = request->n_scan_plans;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018140 for (i = 0; i < request->n_scan_plans; i++)
18141 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018142 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
18143 request->scan_plans[i].iterations;
18144 pno_req->scanTimers.aTimerValues[i].uTimerValue =
18145 request->scan_plans[i].interval;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018146 }
18147}
18148#else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018149static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018150 struct cfg80211_sched_scan_request *request,
18151 hdd_context_t *hdd_ctx)
18152{
18153 v_U32_t i, temp_int;
18154 /* Driver gets only one time interval which is hardcoded in
18155 * supplicant for 10000ms. Taking power consumption into account 6
18156 * timers will be used, Timervalue is increased exponentially
18157 * i.e 10,20,40, 80,160,320 secs. And number of scan cycle for each
18158 * timer is configurable through INI param gPNOScanTimerRepeatValue.
18159 * If it is set to 0 only one timer will be used and PNO scan cycle
18160 * will be repeated after each interval specified by supplicant
18161 * till PNO is disabled.
18162 */
18163 if (0 == hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue)
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018164 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018165 HDD_PNO_SCAN_TIMERS_SET_ONE;
18166 else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018167 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018168 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
18169
18170 temp_int = (request->interval)/1000;
18171 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18172 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
18173 temp_int, hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue);
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018174 for ( i = 0; i < pno_req->scanTimers.ucScanTimersCount; i++)
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018175 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018176 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018177 hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue;
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018178 pno_req->scanTimers.aTimerValues[i].uTimerValue = temp_int;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018179 temp_int *= 2;
18180 }
18181 //Repeat last timer until pno disabled.
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018182 pno_req->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018183}
18184#endif
18185
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018186/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018187 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
18188 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018189 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018190static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018191 struct net_device *dev, struct cfg80211_sched_scan_request *request)
18192{
18193 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018194 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018195 hdd_context_t *pHddCtx;
18196 tHalHandle hHal;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018197 v_U32_t i, indx, num_ch, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053018198 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
18199 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018200 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
18201 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018202 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053018203 hdd_config_t *pConfig = NULL;
18204 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018205
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018206 ENTER();
18207
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018208 if (NULL == pAdapter)
18209 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018210 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018211 "%s: HDD adapter is Null", __func__);
18212 return -ENODEV;
18213 }
18214
18215 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018216 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018217
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018218 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018219 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018220 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018221 }
18222
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053018223 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018224 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
18225 if (NULL == hHal)
18226 {
18227 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18228 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018229 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018230 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018231 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18232 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
18233 pAdapter->sessionId, pAdapter->device_mode));
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053018234 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053018235 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053018236 {
18237 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18238 "%s: aborting the existing scan is unsuccessfull", __func__);
18239 return -EBUSY;
18240 }
18241
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018242 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018243 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053018244 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018245 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018246 return -EBUSY;
18247 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018248
c_hpothu37f21312014-04-09 21:49:54 +053018249 if (TRUE == pHddCtx->isPnoEnable)
18250 {
18251 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
18252 FL("already PNO is enabled"));
18253 return -EBUSY;
18254 }
c_hpothu225aa7c2014-10-22 17:45:13 +053018255
18256 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
18257 {
18258 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18259 "%s: abort ROC failed ", __func__);
18260 return -EBUSY;
18261 }
18262
c_hpothu37f21312014-04-09 21:49:54 +053018263 pHddCtx->isPnoEnable = TRUE;
18264
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018265 pnoRequest.enable = 1; /*Enable PNO */
18266 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018267
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018268 if (( !pnoRequest.ucNetworksCount ) ||
18269 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018270 {
18271 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053018272 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018273 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053018274 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018275 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018276 goto error;
18277 }
18278
18279 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
18280 {
18281 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053018282 "%s: Incorrect number of channels %d",
18283 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018284 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018285 goto error;
18286 }
18287
18288 /* Framework provides one set of channels(all)
18289 * common for all saved profile */
18290 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
18291 channels_allowed, &num_channels_allowed))
18292 {
18293 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18294 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018295 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018296 goto error;
18297 }
18298 /* Checking each channel against allowed channel list */
18299 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053018300 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018301 {
Nirav Shah80830bf2013-12-31 16:35:12 +053018302 char chList [(request->n_channels*5)+1];
18303 int len;
18304 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018305 {
Nirav Shah80830bf2013-12-31 16:35:12 +053018306 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018307 {
Nirav Shah80830bf2013-12-31 16:35:12 +053018308 if (request->channels[i]->hw_value == channels_allowed[indx])
18309 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053018310 if ((!pConfig->enableDFSPnoChnlScan) &&
18311 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
18312 {
18313 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18314 "%s : Dropping DFS channel : %d",
18315 __func__,channels_allowed[indx]);
18316 num_ignore_dfs_ch++;
18317 break;
18318 }
18319
Nirav Shah80830bf2013-12-31 16:35:12 +053018320 valid_ch[num_ch++] = request->channels[i]->hw_value;
18321 len += snprintf(chList+len, 5, "%d ",
18322 request->channels[i]->hw_value);
18323 break ;
18324 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018325 }
18326 }
Nirav Shah80830bf2013-12-31 16:35:12 +053018327 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018328
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053018329 /*If all channels are DFS and dropped, then ignore the PNO request*/
18330 if (num_ignore_dfs_ch == request->n_channels)
18331 {
18332 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18333 "%s : All requested channels are DFS channels", __func__);
18334 ret = -EINVAL;
18335 goto error;
18336 }
18337 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018338
18339 pnoRequest.aNetworks =
18340 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
18341 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018342 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018343 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
18344 FL("failed to allocate memory aNetworks %u"),
18345 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
18346 goto error;
18347 }
18348 vos_mem_zero(pnoRequest.aNetworks,
18349 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
18350
18351 /* Filling per profile params */
18352 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
18353 {
18354 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018355 request->match_sets[i].ssid.ssid_len;
18356
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018357 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
18358 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018359 {
18360 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053018361 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018362 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018363 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018364 goto error;
18365 }
18366
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018367 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018368 request->match_sets[i].ssid.ssid,
18369 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053018370 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18371 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018372 i, pnoRequest.aNetworks[i].ssId.ssId);
18373 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
18374 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
18375 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018376
18377 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018378 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
18379 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018380
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018381 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018382 }
18383
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018384 for (i = 0; i < request->n_ssids; i++)
18385 {
18386 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018387 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018388 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018389 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018390 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018391 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018392 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018393 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018394 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018395 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018396 break;
18397 }
18398 j++;
18399 }
18400 }
18401 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18402 "Number of hidden networks being Configured = %d",
18403 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053018404 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080018405 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018406
18407 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
18408 if (pnoRequest.p24GProbeTemplate == NULL)
18409 {
18410 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
18411 FL("failed to allocate memory p24GProbeTemplate %u"),
18412 SIR_PNO_MAX_PB_REQ_SIZE);
18413 goto error;
18414 }
18415
18416 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
18417 if (pnoRequest.p5GProbeTemplate == NULL)
18418 {
18419 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
18420 FL("failed to allocate memory p5GProbeTemplate %u"),
18421 SIR_PNO_MAX_PB_REQ_SIZE);
18422 goto error;
18423 }
18424
18425 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
18426 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
18427
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053018428 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
18429 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053018430 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018431 pnoRequest.us24GProbeTemplateLen = request->ie_len;
18432 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
18433 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053018434
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018435 pnoRequest.us5GProbeTemplateLen = request->ie_len;
18436 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
18437 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053018438 }
18439
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018440 hdd_config_sched_scan_plan(&pnoRequest, request, pHddCtx);
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053018441
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018442 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018443
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018444 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018445 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
18446 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018447 pAdapter->pno_req_status = 0;
18448
Nirav Shah80830bf2013-12-31 16:35:12 +053018449 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18450 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018451 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
18452 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053018453
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018454 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018455 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018456 hdd_cfg80211_sched_scan_done_callback, pAdapter);
18457 if (eHAL_STATUS_SUCCESS != status)
18458 {
18459 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053018460 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018461 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018462 goto error;
18463 }
18464
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018465 ret = wait_for_completion_timeout(
18466 &pAdapter->pno_comp_var,
18467 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
18468 if (0 >= ret)
18469 {
18470 // Did not receive the response for PNO enable in time.
18471 // Assuming the PNO enable was success.
18472 // Returning error from here, because we timeout, results
18473 // in side effect of Wifi (Wifi Setting) not to work.
18474 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18475 FL("Timed out waiting for PNO to be Enabled"));
18476 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018477 }
18478
18479 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053018480 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018481
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018482error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018483 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18484 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053018485 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018486 if (pnoRequest.aNetworks)
18487 vos_mem_free(pnoRequest.aNetworks);
18488 if (pnoRequest.p24GProbeTemplate)
18489 vos_mem_free(pnoRequest.p24GProbeTemplate);
18490 if (pnoRequest.p5GProbeTemplate)
18491 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018492
18493 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018494 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018495}
18496
18497/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018498 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
18499 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018500 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018501static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
18502 struct net_device *dev, struct cfg80211_sched_scan_request *request)
18503{
18504 int ret;
18505
18506 vos_ssr_protect(__func__);
18507 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
18508 vos_ssr_unprotect(__func__);
18509
18510 return ret;
18511}
18512
18513/*
18514 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
18515 * Function to disable PNO
18516 */
18517static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018518 struct net_device *dev)
18519{
18520 eHalStatus status = eHAL_STATUS_FAILURE;
18521 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18522 hdd_context_t *pHddCtx;
18523 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018524 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018525 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018526
18527 ENTER();
18528
18529 if (NULL == pAdapter)
18530 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018531 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018532 "%s: HDD adapter is Null", __func__);
18533 return -ENODEV;
18534 }
18535
18536 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018537
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018538 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018539 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018540 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018541 "%s: HDD context is Null", __func__);
18542 return -ENODEV;
18543 }
18544
18545 /* The return 0 is intentional when isLogpInProgress and
18546 * isLoadUnloadInProgress. We did observe a crash due to a return of
18547 * failure in sched_scan_stop , especially for a case where the unload
18548 * of the happens at the same time. The function __cfg80211_stop_sched_scan
18549 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
18550 * success. If it returns a failure , then its next invocation due to the
18551 * clean up of the second interface will have the dev pointer corresponding
18552 * to the first one leading to a crash.
18553 */
18554 if (pHddCtx->isLogpInProgress)
18555 {
18556 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18557 "%s: LOGP in Progress. Ignore!!!", __func__);
Mahesh A Saptasagar0c11d822015-10-08 19:54:08 +053018558 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018559 return ret;
18560 }
18561
Mihir Shete18156292014-03-11 15:38:30 +053018562 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018563 {
18564 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18565 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
18566 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018567 }
18568
18569 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
18570 if (NULL == hHal)
18571 {
18572 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18573 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018574 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018575 }
18576
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018577 pnoRequest.enable = 0; /* Disable PNO */
18578 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018579
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018580 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18581 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
18582 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053018583
18584 INIT_COMPLETION(pAdapter->pno_comp_var);
18585 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
18586 pnoRequest.callbackContext = pAdapter;
18587 pAdapter->pno_req_status = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018588 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018589 pAdapter->sessionId,
18590 NULL, pAdapter);
18591 if (eHAL_STATUS_SUCCESS != status)
18592 {
18593 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18594 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018595 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018596 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018597 }
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053018598 ret = wait_for_completion_timeout(
18599 &pAdapter->pno_comp_var,
18600 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
18601 if (0 >= ret)
18602 {
18603 // Did not receive the response for PNO disable in time.
18604 // Assuming the PNO disable was success.
18605 // Returning error from here, because we timeout, results
18606 // in side effect of Wifi (Wifi Setting) not to work.
Anurag Chouhan96b41cb2016-09-28 18:54:47 +053018607 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053018608 FL("Timed out waiting for PNO to be disabled"));
18609 ret = 0;
18610 }
18611
18612 ret = pAdapter->pno_req_status;
18613 pHddCtx->isPnoEnable = (ret == 0) ? FALSE : TRUE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018614
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018615error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018616 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018617 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018618
18619 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018620 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018621}
18622
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018623/*
18624 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
18625 * NL interface to disable PNO
18626 */
18627static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
18628 struct net_device *dev)
18629{
18630 int ret;
18631
18632 vos_ssr_protect(__func__);
18633 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
18634 vos_ssr_unprotect(__func__);
18635
18636 return ret;
18637}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018638#endif /*FEATURE_WLAN_SCAN_PNO*/
18639
18640
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018641#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018642#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018643static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18644 struct net_device *dev,
18645 u8 *peer, u8 action_code,
18646 u8 dialog_token,
18647 u16 status_code, u32 peer_capability,
18648 const u8 *buf, size_t len)
18649#else /* TDLS_MGMT_VERSION2 */
18650#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
18651static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18652 struct net_device *dev,
18653 const u8 *peer, u8 action_code,
18654 u8 dialog_token, u16 status_code,
18655 u32 peer_capability, bool initiator,
18656 const u8 *buf, size_t len)
18657#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
18658static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18659 struct net_device *dev,
18660 const u8 *peer, u8 action_code,
18661 u8 dialog_token, u16 status_code,
18662 u32 peer_capability, const u8 *buf,
18663 size_t len)
18664#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
18665static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18666 struct net_device *dev,
18667 u8 *peer, u8 action_code,
18668 u8 dialog_token,
18669 u16 status_code, u32 peer_capability,
18670 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018671#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018672static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18673 struct net_device *dev,
18674 u8 *peer, u8 action_code,
18675 u8 dialog_token,
18676 u16 status_code, const u8 *buf,
18677 size_t len)
18678#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018679#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018680{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018681 hdd_adapter_t *pAdapter;
18682 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018683 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070018684 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080018685 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070018686 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018687 int ret;
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053018688 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018689#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018690 u32 peer_capability = 0;
18691#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053018692 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018693 hdd_station_ctx_t *pHddStaCtx = NULL;
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053018694 tdlsCtx_t *pHddTdlsCtx;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018695
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018696 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18697 if (NULL == pAdapter)
18698 {
18699 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18700 "%s: Adapter is NULL",__func__);
18701 return -EINVAL;
18702 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018703 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18704 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
18705 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018706
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018707 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018708 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018709 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018710 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018711 "Invalid arguments");
18712 return -EINVAL;
18713 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018714
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080018715 if (pHddCtx->isLogpInProgress)
18716 {
18717 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18718 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053018719 wlan_hdd_tdls_set_link_status(pAdapter,
18720 peer,
18721 eTDLS_LINK_IDLE,
18722 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080018723 return -EBUSY;
18724 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018725
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018726 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
18727 {
18728 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18729 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
18730 return -EAGAIN;
18731 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018732
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053018733 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
18734 if (!pHddTdlsCtx) {
18735 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18736 "%s: pHddTdlsCtx not valid.", __func__);
18737 }
18738
Hoonki Lee27511902013-03-14 18:19:06 -070018739 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018740 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018741 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070018742 "%s: TDLS mode is disabled OR not enabled in FW."
18743 MAC_ADDRESS_STR " action %d declined.",
18744 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018745 return -ENOTSUPP;
18746 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018747
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018748 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18749
18750 if( NULL == pHddStaCtx )
18751 {
18752 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18753 "%s: HDD station context NULL ",__func__);
18754 return -EINVAL;
18755 }
18756
18757 /* STA should be connected and authenticated
18758 * before sending any TDLS frames
18759 */
18760 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
18761 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
18762 {
18763 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18764 "STA is not connected or unauthenticated. "
18765 "connState %u, uIsAuthenticated %u",
18766 pHddStaCtx->conn_info.connState,
18767 pHddStaCtx->conn_info.uIsAuthenticated);
18768 return -EAGAIN;
18769 }
18770
Hoonki Lee27511902013-03-14 18:19:06 -070018771 /* other than teardown frame, other mgmt frames are not sent if disabled */
18772 if (SIR_MAC_TDLS_TEARDOWN != action_code)
18773 {
18774 /* if tdls_mode is disabled to respond to peer's request */
18775 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
18776 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018777 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070018778 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070018779 " TDLS mode is disabled. action %d declined.",
18780 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070018781
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018782 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070018783 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053018784
18785 if (vos_max_concurrent_connections_reached())
18786 {
18787 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
18788 return -EINVAL;
18789 }
Hoonki Lee27511902013-03-14 18:19:06 -070018790 }
18791
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018792 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
18793 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053018794 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018795 {
18796 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018797 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070018798 " TDLS setup is ongoing. action %d declined.",
18799 __func__, MAC_ADDR_ARRAY(peer), action_code);
18800 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018801 }
18802 }
18803
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018804 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
18805 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080018806 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053018807 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
18808 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080018809 {
18810 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
18811 we return error code at 'add_station()'. Hence we have this
18812 check again in addtion to add_station().
18813 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018814 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080018815 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018816 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18817 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053018818 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
18819 __func__, MAC_ADDR_ARRAY(peer), action_code,
18820 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053018821 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080018822 }
18823 else
18824 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018825 /* maximum reached. tweak to send error code to peer and return
18826 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080018827 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018828 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18829 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053018830 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
18831 __func__, MAC_ADDR_ARRAY(peer), status_code,
18832 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070018833 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018834 /* fall through to send setup resp with failure status
18835 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080018836 }
18837 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018838 else
18839 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018840 mutex_lock(&pHddCtx->tdls_lock);
18841 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018842 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018843 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018844 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018845 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070018846 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
18847 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018848 return -EPERM;
18849 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018850 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018851 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018852 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018853
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018854 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053018855 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018856 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
18857 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018858
Hoonki Leea34dd892013-02-05 22:56:02 -080018859 /*Except teardown responder will not be used so just make 0*/
18860 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018861 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080018862 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070018863
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018864 mutex_lock(&pHddCtx->tdls_lock);
18865 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070018866
18867 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
18868 responder = pTdlsPeer->is_responder;
18869 else
Hoonki Leea34dd892013-02-05 22:56:02 -080018870 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070018871 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053018872 "%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 -070018873 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
18874 dialog_token, status_code, len);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018875 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070018876 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080018877 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018878 mutex_unlock(&pHddCtx->tdls_lock);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018879 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018880
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053018881 /* Discard TDLS setup if peer is removed by user app */
18882 if ((pHddCtx->cfg_ini->fTDLSExternalControl) &&
18883 ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
18884 (SIR_MAC_TDLS_SETUP_CNF == action_code) ||
18885 (SIR_MAC_TDLS_DIS_REQ == action_code))) {
18886
18887 mutex_lock(&pHddCtx->tdls_lock);
18888 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18889 if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) {
18890 mutex_unlock(&pHddCtx->tdls_lock);
18891 hddLog(LOGE, FL("TDLS External Control enabled, but peer "
18892 MAC_ADDRESS_STR " is not forced, so reject the action code %d"),
18893 MAC_ADDR_ARRAY(peer), action_code);
18894 return -EINVAL;
18895 }
18896 mutex_unlock(&pHddCtx->tdls_lock);
18897 }
18898
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053018899 /* For explicit trigger of DIS_REQ come out of BMPS for
18900 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070018901 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Deepthi Gowrif78f1f72016-03-21 13:13:28 +053018902 (SIR_MAC_TDLS_SETUP_CNF== action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053018903 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
18904 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070018905 {
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053018906 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter))) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018907 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053018908 "%s: Sending frame action_code %u.Disable BMPS", __func__,
18909 action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018910 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
18911 if (status != VOS_STATUS_SUCCESS) {
18912 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053018913 } else {
18914 pHddTdlsCtx->is_tdls_disabled_bmps = true;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018915 }
Hoonki Lee14621352013-04-16 17:51:19 -070018916 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018917 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018918 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018919 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
18920 }
18921 }
Hoonki Lee14621352013-04-16 17:51:19 -070018922 }
18923
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018924 /* make sure doesn't call send_mgmt() while it is pending */
18925 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
18926 {
18927 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080018928 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018929 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018930 ret = -EBUSY;
18931 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018932 }
18933
18934 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018935 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
18936
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018937 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
18938 pAdapter->sessionId, peer, action_code, dialog_token,
18939 status_code, peer_capability, (tANI_U8 *)buf, len,
18940 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018941
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018942 if (VOS_STATUS_SUCCESS != status)
18943 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018944 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18945 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018946 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018947 ret = -EINVAL;
18948 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018949 }
18950
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018951 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18952 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
18953 WAIT_TIME_TDLS_MGMT);
18954
Hoonki Leed37cbb32013-04-20 00:31:14 -070018955 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
18956 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
18957
18958 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018959 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070018960 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070018961 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070018962 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018963 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080018964
18965 if (pHddCtx->isLogpInProgress)
18966 {
18967 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18968 "%s: LOGP in Progress. Ignore!!!", __func__);
18969 return -EAGAIN;
18970 }
Abhishek Singh837adf22015-10-01 17:37:37 +053018971 if (rc <= 0)
18972 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
18973 WLAN_LOG_INDICATOR_HOST_DRIVER,
18974 WLAN_LOG_REASON_HDD_TIME_OUT,
18975 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080018976
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018977 ret = -EINVAL;
18978 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018979 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018980 else
18981 {
18982 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18983 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
18984 __func__, rc, pAdapter->mgmtTxCompletionStatus);
18985 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018986
Gopichand Nakkala05922802013-03-14 12:23:19 -070018987 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070018988 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018989 ret = max_sta_failed;
18990 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070018991 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018992
Hoonki Leea34dd892013-02-05 22:56:02 -080018993 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
18994 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018995 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018996 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
18997 }
Hoonki Leea34dd892013-02-05 22:56:02 -080018998 }
18999 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
19000 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019001 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019002 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
19003 }
Hoonki Leea34dd892013-02-05 22:56:02 -080019004 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019005
19006 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019007
19008tx_failed:
19009 /* add_station will be called before sending TDLS_SETUP_REQ and
19010 * TDLS_SETUP_RSP and as part of add_station driver will enable
19011 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
19012 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
19013 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
19014 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
19015 */
19016
19017 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
19018 (SIR_MAC_TDLS_SETUP_RSP == action_code))
19019 wlan_hdd_tdls_check_bmps(pAdapter);
19020 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019021}
19022
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019023#if TDLS_MGMT_VERSION2
19024static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
19025 u8 *peer, u8 action_code, u8 dialog_token,
19026 u16 status_code, u32 peer_capability,
19027 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019028#else /* TDLS_MGMT_VERSION2 */
19029#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
19030static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19031 struct net_device *dev,
19032 const u8 *peer, u8 action_code,
19033 u8 dialog_token, u16 status_code,
19034 u32 peer_capability, bool initiator,
19035 const u8 *buf, size_t len)
19036#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
19037static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19038 struct net_device *dev,
19039 const u8 *peer, u8 action_code,
19040 u8 dialog_token, u16 status_code,
19041 u32 peer_capability, const u8 *buf,
19042 size_t len)
19043#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
19044static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19045 struct net_device *dev,
19046 u8 *peer, u8 action_code,
19047 u8 dialog_token,
19048 u16 status_code, u32 peer_capability,
19049 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019050#else
19051static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
19052 u8 *peer, u8 action_code, u8 dialog_token,
19053 u16 status_code, const u8 *buf, size_t len)
19054#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019055#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019056{
19057 int ret;
19058
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019059 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019060#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019061 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
19062 dialog_token, status_code,
19063 peer_capability, buf, len);
19064#else /* TDLS_MGMT_VERSION2 */
19065#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
19066 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
19067 dialog_token, status_code,
19068 peer_capability, initiator,
19069 buf, len);
19070#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
19071 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
19072 dialog_token, status_code,
19073 peer_capability, buf, len);
19074#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
19075 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
19076 dialog_token, status_code,
19077 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019078#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019079 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
19080 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019081#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019082#endif
19083 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019084
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019085 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019086}
Atul Mittal115287b2014-07-08 13:26:33 +053019087
19088int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019089#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19090 const u8 *peer,
19091#else
Atul Mittal115287b2014-07-08 13:26:33 +053019092 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019093#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019094 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053019095 cfg80211_exttdls_callback callback)
19096{
19097
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019098 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053019099 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053019100 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053019101 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19102 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
19103 __func__, MAC_ADDR_ARRAY(peer));
19104
19105 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
19106 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
19107
19108 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019109 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
19110 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
19111 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053019112 return -ENOTSUPP;
19113 }
19114
19115 /* To cater the requirement of establishing the TDLS link
19116 * irrespective of the data traffic , get an entry of TDLS peer.
19117 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053019118 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019119 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
19120 if (pTdlsPeer == NULL) {
19121 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19122 "%s: peer " MAC_ADDRESS_STR " not existing",
19123 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053019124 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019125 return -EINVAL;
19126 }
19127
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053019128 /* check FW TDLS Off Channel capability */
19129 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053019130 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053019131 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019132 {
19133 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
19134 pTdlsPeer->peerParams.global_operating_class =
19135 tdls_peer_params->global_operating_class;
19136 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
19137 pTdlsPeer->peerParams.min_bandwidth_kbps =
19138 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053019139 /* check configured channel is valid, non dfs and
19140 * not current operating channel */
19141 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
19142 tdls_peer_params->channel)) &&
19143 (pHddStaCtx) &&
19144 (tdls_peer_params->channel !=
19145 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019146 {
19147 pTdlsPeer->isOffChannelConfigured = TRUE;
19148 }
19149 else
19150 {
19151 pTdlsPeer->isOffChannelConfigured = FALSE;
19152 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19153 "%s: Configured Tdls Off Channel is not valid", __func__);
19154
19155 }
19156 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053019157 "%s: tdls_off_channel %d isOffChannelConfigured %d "
19158 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019159 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053019160 pTdlsPeer->isOffChannelConfigured,
19161 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019162 }
19163 else
19164 {
19165 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053019166 "%s: TDLS off channel FW capability %d, "
19167 "host capab %d or Invalid TDLS Peer Params", __func__,
19168 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
19169 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019170 }
19171
Atul Mittal115287b2014-07-08 13:26:33 +053019172 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
19173
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019174 mutex_unlock(&pHddCtx->tdls_lock);
19175
Atul Mittal115287b2014-07-08 13:26:33 +053019176 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19177 " %s TDLS Add Force Peer Failed",
19178 __func__);
19179 return -EINVAL;
19180 }
19181 /*EXT TDLS*/
19182
19183 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019184 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019185 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19186 " %s TDLS set callback Failed",
19187 __func__);
19188 return -EINVAL;
19189 }
19190
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019191 mutex_unlock(&pHddCtx->tdls_lock);
19192
Atul Mittal115287b2014-07-08 13:26:33 +053019193 return(0);
19194
19195}
19196
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019197int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
19198#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19199 const u8 *peer
19200#else
19201 u8 *peer
19202#endif
19203)
Atul Mittal115287b2014-07-08 13:26:33 +053019204{
19205
19206 hddTdlsPeer_t *pTdlsPeer;
19207 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053019208
Atul Mittal115287b2014-07-08 13:26:33 +053019209 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19210 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
19211 __func__, MAC_ADDR_ARRAY(peer));
19212
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053019213 if (0 != wlan_hdd_validate_context(pHddCtx)) {
19214 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
19215 return -EINVAL;
19216 }
19217
Atul Mittal115287b2014-07-08 13:26:33 +053019218 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
19219 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
19220
19221 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019222 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
19223 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
19224 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053019225 return -ENOTSUPP;
19226 }
19227
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019228 mutex_lock(&pHddCtx->tdls_lock);
19229 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Atul Mittal115287b2014-07-08 13:26:33 +053019230
19231 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019232 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019233 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019234 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053019235 __func__, MAC_ADDR_ARRAY(peer));
19236 return -EINVAL;
19237 }
19238 else {
19239 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
19240 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053019241 hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_EXT_CTRL,
19242 pTdlsPeer->peerMac);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019243 /* if channel switch is configured, reset
19244 the channel for this peer */
19245 if (TRUE == pTdlsPeer->isOffChannelConfigured)
19246 {
19247 pTdlsPeer->peerParams.channel = 0;
19248 pTdlsPeer->isOffChannelConfigured = FALSE;
19249 }
Atul Mittal115287b2014-07-08 13:26:33 +053019250 }
19251
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019252 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019253 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019254 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053019255 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019256 }
Atul Mittal115287b2014-07-08 13:26:33 +053019257
19258 /*EXT TDLS*/
19259
19260 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019261 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019262 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19263 " %s TDLS set callback Failed",
19264 __func__);
19265 return -EINVAL;
19266 }
Atul Mittal115287b2014-07-08 13:26:33 +053019267
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019268 mutex_unlock(&pHddCtx->tdls_lock);
19269
19270 return(0);
Atul Mittal115287b2014-07-08 13:26:33 +053019271}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019272static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019273#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19274 const u8 *peer,
19275#else
19276 u8 *peer,
19277#endif
19278 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019279{
19280 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19281 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019282 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019283 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019284
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019285 ENTER();
19286
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053019287 if (!pAdapter) {
19288 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
19289 return -EINVAL;
19290 }
19291
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019292 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19293 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
19294 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019295 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019296 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019297 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070019298 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019299 return -EINVAL;
19300 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080019301
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019302 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019303 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080019304 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019305 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080019306 }
19307
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019308
19309 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080019310 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019311 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080019312 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019313 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
19314 "Cannot process TDLS commands",
19315 pHddCtx->cfg_ini->fEnableTDLSSupport,
19316 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019317 return -ENOTSUPP;
19318 }
19319
19320 switch (oper) {
19321 case NL80211_TDLS_ENABLE_LINK:
19322 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019323 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019324 long ret;
Hanumantha Reddy Pothulada389492016-02-11 17:29:27 +053019325 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams = { {0}, 0,
19326 0, 0, 0, 0, 0, 0, {0}, 0, {0} };
Agarwal Ashish16020c42014-12-29 22:01:11 +053019327 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019328 tANI_U16 numCurrTdlsPeers = 0;
19329 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053019330 tANI_U8 suppChannelLen = 0;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019331 tSirMacAddr peerMac;
19332 int channel;
19333 tTDLSLinkStatus peer_status = eTDLS_LINK_IDLE;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019334
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019335 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19336 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
19337 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019338
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019339 mutex_lock(&pHddCtx->tdls_lock);
19340 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053019341 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053019342 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019343 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053019344 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
19345 " (oper %d) not exsting. ignored",
19346 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
19347 return -EINVAL;
19348 }
19349
19350 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19351 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
19352 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
19353 "NL80211_TDLS_ENABLE_LINK");
19354
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070019355 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
19356 {
19357 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
19358 MAC_ADDRESS_STR " failed",
19359 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019360 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070019361 return -EINVAL;
19362 }
19363
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053019364 /* before starting tdls connection, set tdls
19365 * off channel established status to default value */
19366 pTdlsPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019367
19368 mutex_unlock(&pHddCtx->tdls_lock);
19369
Deepthi Gowri2d85bbf2016-07-25 15:43:31 +053019370 wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019371 /* TDLS Off Channel, Disable tdls channel switch,
19372 when there are more than one tdls link */
19373 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053019374 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019375 {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019376 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019377 /* get connected peer and send disable tdls off chan */
19378 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019379 if ((connPeer) &&
19380 (connPeer->isOffChannelSupported == TRUE) &&
19381 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019382 {
19383 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19384 "%s: More then one peer connected, Disable "
19385 "TDLS channel switch", __func__);
19386
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053019387 connPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019388 vos_mem_copy(peerMac, connPeer->peerMac, sizeof (tSirMacAddr));
19389 channel = connPeer->peerParams.channel;
19390
19391 mutex_unlock(&pHddCtx->tdls_lock);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019392
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019393 ret = sme_SendTdlsChanSwitchReq(
19394 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019395 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019396 peerMac,
19397 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019398 TDLS_OFF_CHANNEL_BW_OFFSET,
19399 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019400 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019401 hddLog(VOS_TRACE_LEVEL_ERROR,
19402 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019403 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019404 }
19405 else
19406 {
19407 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19408 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019409 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019410 "isOffChannelConfigured %d",
19411 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019412 (connPeer ? (connPeer->isOffChannelSupported)
19413 : -1),
19414 (connPeer ? (connPeer->isOffChannelConfigured)
19415 : -1));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019416 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019417 }
19418 }
19419
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019420 mutex_lock(&pHddCtx->tdls_lock);
19421 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
19422 if ( NULL == pTdlsPeer ) {
19423 mutex_unlock(&pHddCtx->tdls_lock);
19424 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19425 "%s: " MAC_ADDRESS_STR
19426 " (oper %d) peer got freed in other context. ignored",
19427 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
19428 return -EINVAL;
19429 }
19430 peer_status = pTdlsPeer->link_status;
19431 mutex_unlock(&pHddCtx->tdls_lock);
19432
19433 if (eTDLS_LINK_CONNECTED != peer_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019434 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019435 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053019436
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019437 if (0 != wlan_hdd_tdls_get_link_establish_params(
19438 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019439 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019440 return -EINVAL;
19441 }
19442 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053019443
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019444 ret = sme_SendTdlsLinkEstablishParams(
19445 WLAN_HDD_GET_HAL_CTX(pAdapter),
19446 pAdapter->sessionId, peer,
19447 &tdlsLinkEstablishParams);
19448 if (ret != VOS_STATUS_SUCCESS) {
19449 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
19450 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019451 /* Send TDLS peer UAPSD capabilities to the firmware and
19452 * register with the TL on after the response for this operation
19453 * is received .
19454 */
19455 ret = wait_for_completion_interruptible_timeout(
19456 &pAdapter->tdls_link_establish_req_comp,
19457 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
Masti, Narayanraddie1892a52015-12-15 15:01:01 +053019458
19459 mutex_lock(&pHddCtx->tdls_lock);
19460 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
19461 if ( NULL == pTdlsPeer ) {
19462 mutex_unlock(&pHddCtx->tdls_lock);
19463 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19464 "%s %d: " MAC_ADDRESS_STR
19465 " (oper %d) peer got freed in other context. ignored",
19466 __func__, __LINE__, MAC_ADDR_ARRAY(peer),
19467 (int)oper);
19468 return -EINVAL;
19469 }
19470 peer_status = pTdlsPeer->link_status;
19471 mutex_unlock(&pHddCtx->tdls_lock);
19472
19473 if (ret <= 0 || (peer_status == eTDLS_LINK_TEARING))
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019474 {
19475 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019476 FL("Link Establish Request Failed Status %ld"),
19477 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019478 return -EINVAL;
19479 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053019480 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019481
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019482 mutex_lock(&pHddCtx->tdls_lock);
19483 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
19484 if ( NULL == pTdlsPeer ) {
19485 mutex_unlock(&pHddCtx->tdls_lock);
19486 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19487 "%s: " MAC_ADDRESS_STR
19488 " (oper %d) peer got freed in other context. ignored",
19489 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
19490 return -EINVAL;
19491 }
19492
Atul Mittal115287b2014-07-08 13:26:33 +053019493 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
19494 eTDLS_LINK_CONNECTED,
19495 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053019496 staDesc.ucSTAId = pTdlsPeer->staId;
19497 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053019498
19499 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19500 "%s: tdlsLinkEstablishParams of peer "
19501 MAC_ADDRESS_STR "uapsdQueues: %d"
19502 "qos: %d maxSp: %d isBufSta: %d isOffChannelSupported: %d"
19503 "isResponder: %d peerstaId: %d",
19504 __func__,
19505 MAC_ADDR_ARRAY(tdlsLinkEstablishParams.peerMac),
19506 tdlsLinkEstablishParams.uapsdQueues,
19507 tdlsLinkEstablishParams.qos,
19508 tdlsLinkEstablishParams.maxSp,
19509 tdlsLinkEstablishParams.isBufSta,
19510 tdlsLinkEstablishParams.isOffChannelSupported,
19511 tdlsLinkEstablishParams.isResponder,
19512 pTdlsPeer->staId);
19513
19514 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19515 "%s: StaDesc ucSTAId: %d ucQosEnabled: %d",
19516 __func__,
19517 staDesc.ucSTAId,
19518 staDesc.ucQosEnabled);
19519
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019520 ret = WLANTL_UpdateTdlsSTAClient(
19521 pHddCtx->pvosContext,
19522 &staDesc);
19523 if (ret != VOS_STATUS_SUCCESS) {
19524 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
19525 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053019526
Gopichand Nakkala471708b2013-06-04 20:03:01 +053019527 /* Mark TDLS client Authenticated .*/
19528 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
19529 pTdlsPeer->staId,
19530 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070019531 if (VOS_STATUS_SUCCESS == status)
19532 {
Hoonki Lee14621352013-04-16 17:51:19 -070019533 if (pTdlsPeer->is_responder == 0)
19534 {
19535 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053019536 tdlsConnInfo_t *tdlsInfo;
19537
19538 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
19539
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053019540 if (!vos_timer_is_initialized(
19541 &pTdlsPeer->initiatorWaitTimeoutTimer))
19542 {
19543 /* Initialize initiator wait callback */
19544 vos_timer_init(
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053019545 &pTdlsPeer->initiatorWaitTimeoutTimer,
19546 VOS_TIMER_TYPE_SW,
19547 wlan_hdd_tdls_initiator_wait_cb,
19548 tdlsInfo);
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053019549 }
Hoonki Lee14621352013-04-16 17:51:19 -070019550 wlan_hdd_tdls_timer_restart(pAdapter,
19551 &pTdlsPeer->initiatorWaitTimeoutTimer,
19552 WAIT_TIME_TDLS_INITIATOR);
19553 /* suspend initiator TX until it receives direct packet from the
19554 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019555 ret = WLANTL_SuspendDataTx(
19556 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
19557 &staId, NULL);
19558 if (ret != VOS_STATUS_SUCCESS) {
19559 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
19560 }
Hoonki Lee14621352013-04-16 17:51:19 -070019561 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019562
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053019563 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019564 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053019565 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019566 suppChannelLen =
19567 tdlsLinkEstablishParams.supportedChannelsLen;
19568
19569 if ((suppChannelLen > 0) &&
19570 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
19571 {
19572 tANI_U8 suppPeerChannel = 0;
19573 int i = 0;
19574 for (i = 0U; i < suppChannelLen; i++)
19575 {
19576 suppPeerChannel =
19577 tdlsLinkEstablishParams.supportedChannels[i];
19578
19579 pTdlsPeer->isOffChannelSupported = FALSE;
19580 if (suppPeerChannel ==
19581 pTdlsPeer->peerParams.channel)
19582 {
19583 pTdlsPeer->isOffChannelSupported = TRUE;
19584 break;
19585 }
19586 }
19587 }
19588 else
19589 {
19590 pTdlsPeer->isOffChannelSupported = FALSE;
19591 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053019592 }
19593 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19594 "%s: TDLS channel switch request for channel "
19595 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019596 "%d isOffChannelSupported %d", __func__,
19597 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053019598 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019599 suppChannelLen,
19600 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053019601
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019602 /* TDLS Off Channel, Enable tdls channel switch,
19603 when their is only one tdls link and it supports */
19604 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
19605 if ((numCurrTdlsPeers == 1) &&
19606 (TRUE == pTdlsPeer->isOffChannelSupported) &&
19607 (TRUE == pTdlsPeer->isOffChannelConfigured))
19608 {
19609 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19610 "%s: Send TDLS channel switch request for channel %d",
19611 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053019612
19613 pTdlsPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019614 vos_mem_copy(peerMac, pTdlsPeer->peerMac, sizeof (tSirMacAddr));
19615 channel = pTdlsPeer->peerParams.channel;
19616
19617 mutex_unlock(&pHddCtx->tdls_lock);
19618
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019619 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
19620 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019621 peerMac,
19622 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019623 TDLS_OFF_CHANNEL_BW_OFFSET,
19624 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019625 if (ret != VOS_STATUS_SUCCESS) {
19626 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
19627 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019628 }
19629 else
19630 {
19631 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19632 "%s: TDLS channel switch request not sent"
19633 " numCurrTdlsPeers %d "
19634 "isOffChannelSupported %d "
19635 "isOffChannelConfigured %d",
19636 __func__, numCurrTdlsPeers,
19637 pTdlsPeer->isOffChannelSupported,
19638 pTdlsPeer->isOffChannelConfigured);
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019639 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019640 }
19641
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070019642 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019643 else
19644 mutex_unlock(&pHddCtx->tdls_lock);
19645
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019646 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053019647
19648 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053019649 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
19650 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053019651 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053019652 int ac;
19653 uint8 ucAc[4] = { WLANTL_AC_VO,
19654 WLANTL_AC_VI,
19655 WLANTL_AC_BK,
19656 WLANTL_AC_BE };
19657 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
19658 for(ac=0; ac < 4; ac++)
19659 {
19660 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
19661 pTdlsPeer->staId, ucAc[ac],
19662 tlTid[ac], tlTid[ac], 0, 0,
19663 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019664 if (status != VOS_STATUS_SUCCESS) {
19665 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
19666 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053019667 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053019668 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019669 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019670
Bhargav Shah66896792015-10-01 18:17:37 +053019671 /* stop TCP delack timer if TDLS is enable */
19672 set_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
19673 hdd_manage_delack_timer(pHddCtx);
Abhishek Singh67fa6bc2016-01-05 15:57:19 +053019674 hdd_wlan_tdls_enable_link_event(peer,
19675 pTdlsPeer->isOffChannelSupported,
19676 pTdlsPeer->isOffChannelConfigured,
19677 pTdlsPeer->isOffChannelEstablished);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019678 }
19679 break;
19680 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080019681 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019682 tANI_U16 numCurrTdlsPeers = 0;
19683 hddTdlsPeer_t *connPeer = NULL;
19684
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019685 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19686 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
19687 __func__, MAC_ADDR_ARRAY(peer));
19688
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019689 mutex_lock(&pHddCtx->tdls_lock);
19690 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Sunil Dutt41de4e22013-11-14 18:09:02 +053019691
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019692
Sunil Dutt41de4e22013-11-14 18:09:02 +053019693 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019694 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053019695 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
19696 " (oper %d) not exsting. ignored",
19697 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
19698 return -EINVAL;
19699 }
19700
19701 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19702 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
19703 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
19704 "NL80211_TDLS_DISABLE_LINK");
19705
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019706 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080019707 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019708 long status;
19709
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053019710 /* set tdls off channel status to false for this peer */
19711 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053019712 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
19713 eTDLS_LINK_TEARING,
19714 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
19715 eTDLS_LINK_UNSPECIFIED:
19716 eTDLS_LINK_DROPPED_BY_REMOTE);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019717 mutex_unlock(&pHddCtx->tdls_lock);
19718
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019719 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
19720
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019721 status = sme_DeleteTdlsPeerSta(
19722 WLAN_HDD_GET_HAL_CTX(pAdapter),
19723 pAdapter->sessionId, peer );
19724 if (status != VOS_STATUS_SUCCESS) {
19725 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
19726 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019727
19728 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
19729 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019730
19731 mutex_lock(&pHddCtx->tdls_lock);
19732 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
19733 if ( NULL == pTdlsPeer ) {
19734 mutex_unlock(&pHddCtx->tdls_lock);
19735 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
19736 " peer was freed in other context",
19737 __func__, MAC_ADDR_ARRAY(peer));
19738 return -EINVAL;
19739 }
19740
Atul Mittal271a7652014-09-12 13:18:22 +053019741 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053019742 eTDLS_LINK_IDLE,
19743 eTDLS_LINK_UNSPECIFIED);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019744 mutex_unlock(&pHddCtx->tdls_lock);
19745
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019746 if (status <= 0)
19747 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019748 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19749 "%s: Del station failed status %ld",
19750 __func__, status);
19751 return -EPERM;
19752 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019753
19754 /* TDLS Off Channel, Enable tdls channel switch,
19755 when their is only one tdls link and it supports */
19756 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
19757 if (numCurrTdlsPeers == 1)
19758 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019759 tSirMacAddr peerMac;
19760 int channel;
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053019761
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019762 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019763 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053019764
19765 if (connPeer == NULL) {
19766 mutex_unlock(&pHddCtx->tdls_lock);
19767 hddLog(VOS_TRACE_LEVEL_ERROR,
19768 "%s connPeer is NULL", __func__);
19769 return -EINVAL;
19770 }
19771
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019772 vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr));
19773 channel = connPeer->peerParams.channel;
19774
19775 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19776 "%s: TDLS channel switch "
19777 "isOffChannelSupported %d "
19778 "isOffChannelConfigured %d "
19779 "isOffChannelEstablished %d",
19780 __func__,
19781 (connPeer ? connPeer->isOffChannelSupported : -1),
19782 (connPeer ? connPeer->isOffChannelConfigured : -1),
19783 (connPeer ? connPeer->isOffChannelEstablished : -1));
19784
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019785 if ((connPeer) &&
19786 (connPeer->isOffChannelSupported == TRUE) &&
19787 (connPeer->isOffChannelConfigured == TRUE))
19788 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053019789 connPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019790 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019791 status = sme_SendTdlsChanSwitchReq(
19792 WLAN_HDD_GET_HAL_CTX(pAdapter),
19793 pAdapter->sessionId,
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019794 peerMac,
19795 channel,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019796 TDLS_OFF_CHANNEL_BW_OFFSET,
19797 TDLS_CHANNEL_SWITCH_ENABLE);
19798 if (status != VOS_STATUS_SUCCESS) {
19799 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
19800 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019801 }
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019802 else
19803 mutex_unlock(&pHddCtx->tdls_lock);
19804 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019805 else
19806 {
19807 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19808 "%s: TDLS channel switch request not sent "
19809 "numCurrTdlsPeers %d ",
19810 __func__, numCurrTdlsPeers);
19811 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080019812 }
19813 else
19814 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019815 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019816 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19817 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080019818 }
Bhargav Shah66896792015-10-01 18:17:37 +053019819 if (numCurrTdlsPeers == 0) {
19820 /* start TCP delack timer if TDLS is disable */
19821 clear_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
19822 hdd_manage_delack_timer(pHddCtx);
19823 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080019824 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019825 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019826 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053019827 {
Atul Mittal115287b2014-07-08 13:26:33 +053019828 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053019829
Atul Mittal115287b2014-07-08 13:26:33 +053019830 if (0 != status)
19831 {
19832 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019833 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053019834 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053019835 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053019836 break;
19837 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019838 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053019839 {
Atul Mittal115287b2014-07-08 13:26:33 +053019840 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
19841 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019842 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053019843 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053019844
Atul Mittal115287b2014-07-08 13:26:33 +053019845 if (0 != status)
19846 {
19847 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019848 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053019849 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053019850 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053019851 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053019852 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019853 case NL80211_TDLS_DISCOVERY_REQ:
19854 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019855 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019856 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019857 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019858 return -ENOTSUPP;
19859 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019860 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19861 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019862 return -ENOTSUPP;
19863 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019864
19865 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019866 return 0;
19867}
Chilam NG571c65a2013-01-19 12:27:36 +053019868
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019869static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019870#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19871 const u8 *peer,
19872#else
19873 u8 *peer,
19874#endif
19875 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019876{
19877 int ret;
19878
19879 vos_ssr_protect(__func__);
19880 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
19881 vos_ssr_unprotect(__func__);
19882
19883 return ret;
19884}
19885
Chilam NG571c65a2013-01-19 12:27:36 +053019886int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
19887 struct net_device *dev, u8 *peer)
19888{
Arif Hussaina7c8e412013-11-20 11:06:42 -080019889 hddLog(VOS_TRACE_LEVEL_INFO,
19890 "tdls send discover req: "MAC_ADDRESS_STR,
19891 MAC_ADDR_ARRAY(peer));
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019892#if TDLS_MGMT_VERSION2
19893 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19894 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
19895#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019896#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
19897 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19898 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
19899#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
19900 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19901 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
19902#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
19903 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19904 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
19905#else
Chilam NG571c65a2013-01-19 12:27:36 +053019906 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19907 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019908#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019909#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053019910}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019911#endif
19912
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019913#ifdef WLAN_FEATURE_GTK_OFFLOAD
19914/*
19915 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
19916 * Callback rountine called upon receiving response for
19917 * get offload info
19918 */
19919void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
19920 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
19921{
19922
19923 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019924 tANI_U8 tempReplayCounter[8];
19925 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019926
19927 ENTER();
19928
19929 if (NULL == pAdapter)
19930 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053019931 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019932 "%s: HDD adapter is Null", __func__);
19933 return ;
19934 }
19935
19936 if (NULL == pGtkOffloadGetInfoRsp)
19937 {
19938 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19939 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
19940 return ;
19941 }
19942
19943 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
19944 {
19945 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19946 "%s: wlan Failed to get replay counter value",
19947 __func__);
19948 return ;
19949 }
19950
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019951 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
19952 /* Update replay counter */
19953 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
19954 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
19955
19956 {
19957 /* changing from little to big endian since supplicant
19958 * works on big endian format
19959 */
19960 int i;
19961 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
19962
19963 for (i = 0; i < 8; i++)
19964 {
19965 tempReplayCounter[7-i] = (tANI_U8)p[i];
19966 }
19967 }
19968
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019969 /* Update replay counter to NL */
19970 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019971 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019972}
19973
19974/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019975 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019976 * This function is used to offload GTK rekeying job to the firmware.
19977 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019978int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019979 struct cfg80211_gtk_rekey_data *data)
19980{
19981 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19982 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
19983 hdd_station_ctx_t *pHddStaCtx;
19984 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019985 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019986 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019987 eHalStatus status = eHAL_STATUS_FAILURE;
19988
19989 ENTER();
19990
19991 if (NULL == pAdapter)
19992 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019993 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019994 "%s: HDD adapter is Null", __func__);
19995 return -ENODEV;
19996 }
19997
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019998 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19999 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
20000 pAdapter->sessionId, pAdapter->device_mode));
20001
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020002 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020003 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020004 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020005 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020006 }
20007
20008 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
20009 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
20010 if (NULL == hHal)
20011 {
20012 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20013 "%s: HAL context is Null!!!", __func__);
20014 return -EAGAIN;
20015 }
20016
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020017 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
20018 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
20019 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
20020 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020021 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020022 {
20023 /* changing from big to little endian since driver
20024 * works on little endian format
20025 */
20026 tANI_U8 *p =
20027 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
20028 int i;
20029
20030 for (i = 0; i < 8; i++)
20031 {
20032 p[7-i] = data->replay_ctr[i];
20033 }
20034 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020035
20036 if (TRUE == pHddCtx->hdd_wlan_suspended)
20037 {
20038 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020039 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
20040 sizeof (tSirGtkOffloadParams));
20041 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020042 pAdapter->sessionId);
20043
20044 if (eHAL_STATUS_SUCCESS != status)
20045 {
20046 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20047 "%s: sme_SetGTKOffload failed, returned %d",
20048 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053020049
20050 /* Need to clear any trace of key value in the memory.
20051 * Thus zero out the memory even though it is local
20052 * variable.
20053 */
20054 vos_mem_zero(&hddGtkOffloadReqParams,
20055 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020056 return status;
20057 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020058 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20059 "%s: sme_SetGTKOffload successfull", __func__);
20060 }
20061 else
20062 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020063 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20064 "%s: wlan not suspended GTKOffload request is stored",
20065 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020066 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020067
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053020068 /* Need to clear any trace of key value in the memory.
20069 * Thus zero out the memory even though it is local
20070 * variable.
20071 */
20072 vos_mem_zero(&hddGtkOffloadReqParams,
20073 sizeof(hddGtkOffloadReqParams));
20074
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020075 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020076 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020077}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020078
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020079int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
20080 struct cfg80211_gtk_rekey_data *data)
20081{
20082 int ret;
20083
20084 vos_ssr_protect(__func__);
20085 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
20086 vos_ssr_unprotect(__func__);
20087
20088 return ret;
20089}
20090#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020091/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020092 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020093 * This function is used to set access control policy
20094 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020095static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
20096 struct net_device *dev,
20097 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020098{
20099 int i;
20100 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20101 hdd_hostapd_state_t *pHostapdState;
20102 tsap_Config_t *pConfig;
20103 v_CONTEXT_t pVosContext = NULL;
20104 hdd_context_t *pHddCtx;
20105 int status;
20106
20107 ENTER();
20108
20109 if (NULL == pAdapter)
20110 {
20111 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20112 "%s: HDD adapter is Null", __func__);
20113 return -ENODEV;
20114 }
20115
20116 if (NULL == params)
20117 {
20118 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20119 "%s: params is Null", __func__);
20120 return -EINVAL;
20121 }
20122
20123 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
20124 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020125 if (0 != status)
20126 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020127 return status;
20128 }
20129
20130 pVosContext = pHddCtx->pvosContext;
20131 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
20132
20133 if (NULL == pHostapdState)
20134 {
20135 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20136 "%s: pHostapdState is Null", __func__);
20137 return -EINVAL;
20138 }
20139
20140 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
20141 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053020142 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20143 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
20144 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020145
20146 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
20147 {
20148 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
20149
20150 /* default value */
20151 pConfig->num_accept_mac = 0;
20152 pConfig->num_deny_mac = 0;
20153
20154 /**
20155 * access control policy
20156 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
20157 * listed in hostapd.deny file.
20158 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
20159 * listed in hostapd.accept file.
20160 */
20161 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
20162 {
20163 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
20164 }
20165 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
20166 {
20167 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
20168 }
20169 else
20170 {
20171 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20172 "%s:Acl Policy : %d is not supported",
20173 __func__, params->acl_policy);
20174 return -ENOTSUPP;
20175 }
20176
20177 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
20178 {
20179 pConfig->num_accept_mac = params->n_acl_entries;
20180 for (i = 0; i < params->n_acl_entries; i++)
20181 {
20182 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20183 "** Add ACL MAC entry %i in WhiletList :"
20184 MAC_ADDRESS_STR, i,
20185 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
20186
20187 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
20188 sizeof(qcmacaddr));
20189 }
20190 }
20191 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
20192 {
20193 pConfig->num_deny_mac = params->n_acl_entries;
20194 for (i = 0; i < params->n_acl_entries; i++)
20195 {
20196 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20197 "** Add ACL MAC entry %i in BlackList :"
20198 MAC_ADDRESS_STR, i,
20199 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
20200
20201 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
20202 sizeof(qcmacaddr));
20203 }
20204 }
20205
20206 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
20207 {
20208 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20209 "%s: SAP Set Mac Acl fail", __func__);
20210 return -EINVAL;
20211 }
20212 }
20213 else
20214 {
20215 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053020216 "%s: Invalid device_mode = %s (%d)",
20217 __func__, hdd_device_modetoString(pAdapter->device_mode),
20218 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020219 return -EINVAL;
20220 }
20221
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020222 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020223 return 0;
20224}
20225
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020226static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
20227 struct net_device *dev,
20228 const struct cfg80211_acl_data *params)
20229{
20230 int ret;
20231 vos_ssr_protect(__func__);
20232 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
20233 vos_ssr_unprotect(__func__);
20234
20235 return ret;
20236}
20237
Leo Chang9056f462013-08-01 19:21:11 -070020238#ifdef WLAN_NL80211_TESTMODE
20239#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070020240void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070020241(
20242 void *pAdapter,
20243 void *indCont
20244)
20245{
Leo Changd9df8aa2013-09-26 13:32:26 -070020246 tSirLPHBInd *lphbInd;
20247 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053020248 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070020249
20250 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070020251 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070020252
c_hpothu73f35e62014-04-18 13:40:08 +053020253 if (pAdapter == NULL)
20254 {
20255 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20256 "%s: pAdapter is NULL\n",__func__);
20257 return;
20258 }
20259
Leo Chang9056f462013-08-01 19:21:11 -070020260 if (NULL == indCont)
20261 {
20262 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070020263 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070020264 return;
20265 }
20266
c_hpothu73f35e62014-04-18 13:40:08 +053020267 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070020268 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070020269 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053020270 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070020271 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070020272 GFP_ATOMIC);
20273 if (!skb)
20274 {
20275 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20276 "LPHB timeout, NL buffer alloc fail");
20277 return;
20278 }
20279
Leo Changac3ba772013-10-07 09:47:04 -070020280 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070020281 {
20282 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20283 "WLAN_HDD_TM_ATTR_CMD put fail");
20284 goto nla_put_failure;
20285 }
Leo Changac3ba772013-10-07 09:47:04 -070020286 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070020287 {
20288 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20289 "WLAN_HDD_TM_ATTR_TYPE put fail");
20290 goto nla_put_failure;
20291 }
Leo Changac3ba772013-10-07 09:47:04 -070020292 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070020293 sizeof(tSirLPHBInd), lphbInd))
20294 {
20295 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20296 "WLAN_HDD_TM_ATTR_DATA put fail");
20297 goto nla_put_failure;
20298 }
Leo Chang9056f462013-08-01 19:21:11 -070020299 cfg80211_testmode_event(skb, GFP_ATOMIC);
20300 return;
20301
20302nla_put_failure:
20303 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20304 "NLA Put fail");
20305 kfree_skb(skb);
20306
20307 return;
20308}
20309#endif /* FEATURE_WLAN_LPHB */
20310
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020311static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070020312{
20313 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
20314 int err = 0;
20315#ifdef FEATURE_WLAN_LPHB
20316 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070020317 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020318
20319 ENTER();
20320
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053020321 err = wlan_hdd_validate_context(pHddCtx);
20322 if (0 != err)
20323 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053020324 return err;
20325 }
Leo Chang9056f462013-08-01 19:21:11 -070020326#endif /* FEATURE_WLAN_LPHB */
20327
20328 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
20329 if (err)
20330 {
20331 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20332 "%s Testmode INV ATTR", __func__);
20333 return err;
20334 }
20335
20336 if (!tb[WLAN_HDD_TM_ATTR_CMD])
20337 {
20338 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20339 "%s Testmode INV CMD", __func__);
20340 return -EINVAL;
20341 }
20342
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053020343 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20344 TRACE_CODE_HDD_CFG80211_TESTMODE,
20345 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070020346 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
20347 {
20348#ifdef FEATURE_WLAN_LPHB
20349 /* Low Power Heartbeat configuration request */
20350 case WLAN_HDD_TM_CMD_WLAN_HB:
20351 {
20352 int buf_len;
20353 void *buf;
20354 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080020355 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070020356
20357 if (!tb[WLAN_HDD_TM_ATTR_DATA])
20358 {
20359 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20360 "%s Testmode INV DATA", __func__);
20361 return -EINVAL;
20362 }
20363
20364 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
20365 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080020366
Manjeet Singh3c577442017-02-10 19:03:38 +053020367 if (buf_len > sizeof(*hb_params)) {
20368 hddLog(LOGE, FL("buf_len=%d exceeded hb_params size limit"),
20369 buf_len);
20370 return -ERANGE;
20371 }
20372
Amar Singhal05852702014-02-04 14:40:00 -080020373 hb_params_temp =(tSirLPHBReq *)buf;
20374 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
20375 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
20376 return -EINVAL;
20377
Leo Chang9056f462013-08-01 19:21:11 -070020378 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
20379 if (NULL == hb_params)
20380 {
20381 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20382 "%s Request Buffer Alloc Fail", __func__);
20383 return -EINVAL;
20384 }
20385
Ashish Kumar Dhanotiya3a8c0a72017-07-13 18:58:59 +053020386 vos_mem_zero(hb_params, sizeof(tSirLPHBReq));
Leo Chang9056f462013-08-01 19:21:11 -070020387 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070020388 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
20389 hb_params,
20390 wlan_hdd_cfg80211_lphb_ind_handler);
20391 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070020392 {
Leo Changd9df8aa2013-09-26 13:32:26 -070020393 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20394 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070020395 vos_mem_free(hb_params);
20396 }
Leo Chang9056f462013-08-01 19:21:11 -070020397 return 0;
20398 }
20399#endif /* FEATURE_WLAN_LPHB */
20400 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020401 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20402 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070020403 return -EOPNOTSUPP;
20404 }
20405
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020406 EXIT();
20407 return err;
Leo Chang9056f462013-08-01 19:21:11 -070020408}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020409
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053020410static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
20411#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
20412 struct wireless_dev *wdev,
20413#endif
20414 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020415{
20416 int ret;
20417
20418 vos_ssr_protect(__func__);
20419 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
20420 vos_ssr_unprotect(__func__);
20421
20422 return ret;
20423}
Leo Chang9056f462013-08-01 19:21:11 -070020424#endif /* CONFIG_NL80211_TESTMODE */
20425
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053020426extern void hdd_set_wlan_suspend_mode(bool suspend);
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020427static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020428 struct net_device *dev,
20429 int idx, struct survey_info *survey)
20430{
20431 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20432 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053020433 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020434 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053020435 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020436 v_S7_t snr,rssi;
20437 int status, i, j, filled = 0;
20438
20439 ENTER();
20440
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020441 if (NULL == pAdapter)
20442 {
20443 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20444 "%s: HDD adapter is Null", __func__);
20445 return -ENODEV;
20446 }
20447
20448 if (NULL == wiphy)
20449 {
20450 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20451 "%s: wiphy is Null", __func__);
20452 return -ENODEV;
20453 }
20454
20455 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
20456 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020457 if (0 != status)
20458 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020459 return status;
20460 }
20461
Mihir Sheted9072e02013-08-21 17:02:29 +053020462 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
20463
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020464 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053020465 0 != pAdapter->survey_idx ||
20466 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020467 {
20468 /* The survey dump ops when implemented completely is expected to
20469 * return a survey of all channels and the ops is called by the
20470 * kernel with incremental values of the argument 'idx' till it
20471 * returns -ENONET. But we can only support the survey for the
20472 * operating channel for now. survey_idx is used to track
20473 * that the ops is called only once and then return -ENONET for
20474 * the next iteration
20475 */
20476 pAdapter->survey_idx = 0;
20477 return -ENONET;
20478 }
20479
Mukul Sharma9d5233b2015-06-11 20:28:20 +053020480 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
20481 {
20482 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20483 "%s: Roaming in progress, hence return ", __func__);
20484 return -ENONET;
20485 }
20486
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020487 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
20488
20489 wlan_hdd_get_snr(pAdapter, &snr);
20490 wlan_hdd_get_rssi(pAdapter, &rssi);
20491
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053020492 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20493 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
20494 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020495 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
20496 hdd_wlan_get_freq(channel, &freq);
20497
20498
20499 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
20500 {
20501 if (NULL == wiphy->bands[i])
20502 {
20503 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
20504 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
20505 continue;
20506 }
20507
20508 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
20509 {
20510 struct ieee80211_supported_band *band = wiphy->bands[i];
20511
20512 if (band->channels[j].center_freq == (v_U16_t)freq)
20513 {
20514 survey->channel = &band->channels[j];
20515 /* The Rx BDs contain SNR values in dB for the received frames
20516 * while the supplicant expects noise. So we calculate and
20517 * return the value of noise (dBm)
20518 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
20519 */
20520 survey->noise = rssi - snr;
20521 survey->filled = SURVEY_INFO_NOISE_DBM;
20522 filled = 1;
20523 }
20524 }
20525 }
20526
20527 if (filled)
20528 pAdapter->survey_idx = 1;
20529 else
20530 {
20531 pAdapter->survey_idx = 0;
20532 return -ENONET;
20533 }
20534
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020535 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020536 return 0;
20537}
20538
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020539static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
20540 struct net_device *dev,
20541 int idx, struct survey_info *survey)
20542{
20543 int ret;
20544
20545 vos_ssr_protect(__func__);
20546 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
20547 vos_ssr_unprotect(__func__);
20548
20549 return ret;
20550}
20551
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020552/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053020553 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020554 * this is called when cfg80211 driver resume
20555 * driver updates latest sched_scan scan result(if any) to cfg80211 database
20556 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053020557int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020558{
20559 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
20560 hdd_adapter_t *pAdapter;
20561 hdd_adapter_list_node_t *pAdapterNode, *pNext;
20562 VOS_STATUS status = VOS_STATUS_SUCCESS;
20563
20564 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020565
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053020566 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020567 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020568 return 0;
20569 }
20570
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053020571 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
20572 NO_SESSION, pHddCtx->isWiphySuspended));
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053020573
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053020574 if (pHddCtx->is_ap_mode_wow_supported)
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053020575 {
20576 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20577 "%s: Resume SoftAP", __func__);
20578 hdd_set_wlan_suspend_mode(false);
20579 }
20580
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020581 spin_lock(&pHddCtx->schedScan_lock);
20582 pHddCtx->isWiphySuspended = FALSE;
20583 if (TRUE != pHddCtx->isSchedScanUpdatePending)
20584 {
20585 spin_unlock(&pHddCtx->schedScan_lock);
20586 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20587 "%s: Return resume is not due to PNO indication", __func__);
20588 return 0;
20589 }
20590 // Reset flag to avoid updatating cfg80211 data old results again
20591 pHddCtx->isSchedScanUpdatePending = FALSE;
20592 spin_unlock(&pHddCtx->schedScan_lock);
20593
20594 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
20595
20596 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
20597 {
20598 pAdapter = pAdapterNode->pAdapter;
20599 if ( (NULL != pAdapter) &&
20600 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
20601 {
20602 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053020603 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020604 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
20605 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053020606 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020607 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053020608 {
20609 /* Acquire wakelock to handle the case where APP's tries to
20610 * suspend immediately after updating the scan results. Whis
20611 * results in app's is in suspended state and not able to
20612 * process the connect request to AP
20613 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053020614 hdd_prevent_suspend_timeout(2000,
20615 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020616 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053020617 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020618
20619 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20620 "%s : cfg80211 scan result database updated", __func__);
20621
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020622 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020623 return 0;
20624
20625 }
20626 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
20627 pAdapterNode = pNext;
20628 }
20629
20630 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20631 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020632 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020633 return 0;
20634}
20635
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053020636int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
20637{
20638 int ret;
20639
20640 vos_ssr_protect(__func__);
20641 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
20642 vos_ssr_unprotect(__func__);
20643
20644 return ret;
20645}
20646
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020647/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053020648 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020649 * this is called when cfg80211 driver suspends
20650 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053020651int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020652 struct cfg80211_wowlan *wow)
20653{
20654 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053020655 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020656
20657 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020658
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053020659 ret = wlan_hdd_validate_context(pHddCtx);
20660 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020661 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053020662 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020663 }
20664
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053020665 if (pHddCtx->is_ap_mode_wow_supported) {
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053020666 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20667 "%s: Suspend SoftAP", __func__);
20668 hdd_set_wlan_suspend_mode(true);
20669 }
20670
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053020671
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053020672 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20673 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
20674 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020675 pHddCtx->isWiphySuspended = TRUE;
20676
20677 EXIT();
20678
20679 return 0;
20680}
20681
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053020682int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
20683 struct cfg80211_wowlan *wow)
20684{
20685 int ret;
20686
20687 vos_ssr_protect(__func__);
20688 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
20689 vos_ssr_unprotect(__func__);
20690
20691 return ret;
20692}
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053020693
20694#ifdef FEATURE_OEM_DATA_SUPPORT
20695static void wlan_hdd_cfg80211_oem_data_rsp_ind_new(void *ctx,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053020696 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053020697{
20698 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
20699
20700 ENTER();
20701
20702 if (wlan_hdd_validate_context(pHddCtx)) {
20703 return;
20704 }
20705 if (!pMsg)
20706 {
20707 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
20708 return;
20709 }
20710
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053020711 send_oem_data_rsp_msg(evLen, pMsg);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053020712
20713 EXIT();
20714 return;
20715
20716}
20717
20718void wlan_hdd_cfg80211_oemdata_callback(void *ctx, const tANI_U16 evType,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053020719 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053020720{
20721 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
20722
20723 ENTER();
20724
20725 if (wlan_hdd_validate_context(pHddCtx)) {
20726 return;
20727 }
20728
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053020729 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d) evLen %d"), evType, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053020730
20731 switch(evType) {
20732 case SIR_HAL_START_OEM_DATA_RSP_IND_NEW:
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053020733 wlan_hdd_cfg80211_oem_data_rsp_ind_new(ctx, pMsg, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053020734 break;
20735 default:
20736 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
20737 break;
20738 }
20739 EXIT();
20740}
20741#endif
20742
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053020743#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
20744 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053020745/**
20746 * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api
20747 * @wiphy: Pointer to wiphy
20748 * @wdev: Pointer to wireless device structure
20749 *
20750 * This function is used to abort an ongoing scan
20751 *
20752 * Return: None
20753 */
20754static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
20755 struct wireless_dev *wdev)
20756{
20757 struct net_device *dev = wdev->netdev;
20758 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
20759 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
20760 int ret;
20761
20762 ENTER();
20763
20764 if (NULL == adapter) {
20765 hddLog(VOS_TRACE_LEVEL_FATAL, FL("HDD adapter is NULL"));
20766 return;
20767 }
20768
20769 ret = wlan_hdd_validate_context(hdd_ctx);
20770 if (0 != ret)
20771 return;
20772
20773 wlan_hdd_scan_abort(adapter);
20774
20775 return;
20776}
20777
20778/**
20779 * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api
20780 * @wiphy: Pointer to wiphy
20781 * @wdev: Pointer to wireless device structure
20782 *
20783 * Return: None
20784 */
20785void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
20786 struct wireless_dev *wdev)
20787{
20788 vos_ssr_protect(__func__);
20789 __wlan_hdd_cfg80211_abort_scan(wiphy, wdev);
20790 vos_ssr_unprotect(__func__);
20791
20792 return;
20793}
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053020794#endif
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053020795
Abhishek Singh936c6932017-11-07 17:28:23 +053020796#ifdef CHANNEL_SWITCH_SUPPORTED
20797/**
20798 * __wlan_hdd_cfg80211_channel_switch()- function to switch
20799 * channel in SAP/GO
20800 * @wiphy: wiphy pointer
20801 * @dev: dev pointer.
20802 * @csa_params: Change channel params
20803 *
20804 * This function is called to switch channel in SAP/GO
20805 *
20806 * Return: 0 if success else return non zero
20807 */
20808static int __wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
20809 struct net_device *dev, struct cfg80211_csa_settings *csa_params)
20810{
20811 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
20812 hdd_context_t *hdd_ctx;
20813 uint8_t channel;
20814 int ret;
20815 v_CONTEXT_t vos_ctx;
20816
20817 hddLog(LOGE, FL("Set Freq %d"), csa_params->chandef.chan->center_freq);
20818
20819 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
20820 ret = wlan_hdd_validate_context(hdd_ctx);
20821 if (ret)
20822 return ret;
20823
20824 vos_ctx = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
20825 if (!vos_ctx) {
20826 hddLog(LOGE, FL("Vos ctx is null"));
20827 return -EINVAL;
20828 }
20829
20830 if ((WLAN_HDD_SOFTAP != adapter->device_mode) &&
20831 (WLAN_HDD_P2P_GO != adapter->device_mode))
20832 return -ENOTSUPP;
20833
20834 channel = vos_freq_to_chan(csa_params->chandef.chan->center_freq);
20835 ret = wlansap_set_channel_change(vos_ctx, channel);
20836
20837 return ret;
20838}
20839
20840/**
20841 * wlan_hdd_cfg80211_channel_switch()- function to switch
20842 * channel in SAP/GO
20843 * @wiphy: wiphy pointer
20844 * @dev: dev pointer.
20845 * @csa_params: Change channel params
20846 *
20847 * This function is called to switch channel in SAP/GO
20848 *
20849 * Return: 0 if success else return non zero
20850 */
20851static int wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
20852 struct net_device *dev, struct cfg80211_csa_settings *csa_params)
20853{
20854 int ret;
20855
20856 vos_ssr_protect(__func__);
20857 ret = __wlan_hdd_cfg80211_channel_switch(wiphy, dev, csa_params);
20858 vos_ssr_unprotect(__func__);
20859
20860 return ret;
20861}
20862#endif
20863
Jeff Johnson295189b2012-06-20 16:38:30 -070020864/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053020865static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070020866{
20867 .add_virtual_intf = wlan_hdd_add_virtual_intf,
20868 .del_virtual_intf = wlan_hdd_del_virtual_intf,
20869 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
20870 .change_station = wlan_hdd_change_station,
20871#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
20872 .add_beacon = wlan_hdd_cfg80211_add_beacon,
20873 .del_beacon = wlan_hdd_cfg80211_del_beacon,
20874 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070020875#else
20876 .start_ap = wlan_hdd_cfg80211_start_ap,
20877 .change_beacon = wlan_hdd_cfg80211_change_beacon,
20878 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070020879#endif
20880 .change_bss = wlan_hdd_cfg80211_change_bss,
20881 .add_key = wlan_hdd_cfg80211_add_key,
20882 .get_key = wlan_hdd_cfg80211_get_key,
20883 .del_key = wlan_hdd_cfg80211_del_key,
20884 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080020885#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070020886 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080020887#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070020888 .scan = wlan_hdd_cfg80211_scan,
20889 .connect = wlan_hdd_cfg80211_connect,
20890 .disconnect = wlan_hdd_cfg80211_disconnect,
20891 .join_ibss = wlan_hdd_cfg80211_join_ibss,
20892 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
20893 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
20894 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
20895 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070020896 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
20897 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053020898 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070020899#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
20900 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
20901 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
20902 .set_txq_params = wlan_hdd_set_txq_params,
20903#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070020904 .get_station = wlan_hdd_cfg80211_get_station,
20905 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
20906 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070020907 .add_station = wlan_hdd_cfg80211_add_station,
20908#ifdef FEATURE_WLAN_LFR
20909 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
20910 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
20911 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
20912#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070020913#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
20914 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
20915#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020916#ifdef FEATURE_WLAN_TDLS
20917 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
20918 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
20919#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020920#ifdef WLAN_FEATURE_GTK_OFFLOAD
20921 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
20922#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020923#ifdef FEATURE_WLAN_SCAN_PNO
20924 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
20925 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
20926#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020927 .resume = wlan_hdd_cfg80211_resume_wlan,
20928 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020929 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070020930#ifdef WLAN_NL80211_TESTMODE
20931 .testmode_cmd = wlan_hdd_cfg80211_testmode,
20932#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020933 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053020934#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
20935 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053020936 .abort_scan = wlan_hdd_cfg80211_abort_scan,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053020937#endif
Abhishek Singh936c6932017-11-07 17:28:23 +053020938#ifdef CHANNEL_SWITCH_SUPPORTED
20939 .channel_switch = wlan_hdd_cfg80211_channel_switch,
20940#endif
20941
Jeff Johnson295189b2012-06-20 16:38:30 -070020942};
20943