blob: 81336ccd020bcdc99e8e4bb747cf8100231cde88 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Abhishek Singhb3e376c2017-01-04 15:27:13 +05302 * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lama7f454d2014-07-24 12:04:06 -070023 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +053026 *
Kiet Lamaa8e15a2014-02-11 23:30:06 -080027 */
Kiet Lam842dad02014-02-18 18:44:02 -080028
29
Kiet Lama7f454d2014-07-24 12:04:06 -070030
31
Jeff Johnson295189b2012-06-20 16:38:30 -070032/**========================================================================
33
34 \file wlan_hdd_cfg80211.c
35
36 \brief WLAN Host Device Driver implementation
37
Jeff Johnson295189b2012-06-20 16:38:30 -070038 ========================================================================*/
39
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070040/**=========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -070041
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070042 EDIT HISTORY FOR FILE
Jeff Johnson295189b2012-06-20 16:38:30 -070043
44
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070045 This section contains comments describing changes made to the module.
46 Notice that changes are listed in reverse chronological order.
Jeff Johnson295189b2012-06-20 16:38:30 -070047
48
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070049 $Header:$ $DateTime: $ $Author: $
Jeff Johnson295189b2012-06-20 16:38:30 -070050
51
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070052 when who what, where, why
Jeff Johnson295189b2012-06-20 16:38:30 -070053 -------- --- --------------------------------------------------------
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070054 21/12/09 Ashwani Created module.
Jeff Johnson295189b2012-06-20 16:38:30 -070055
56 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070057 Ganesh K
Jeff Johnson295189b2012-06-20 16:38:30 -070058 ==========================================================================*/
59
Jeff Johnson295189b2012-06-20 16:38:30 -070060
61#include <linux/version.h>
62#include <linux/module.h>
63#include <linux/kernel.h>
64#include <linux/init.h>
65#include <linux/wireless.h>
66#include <wlan_hdd_includes.h>
67#include <net/arp.h>
68#include <net/cfg80211.h>
69#include <linux/wireless.h>
70#include <wlan_hdd_wowl.h>
71#include <aniGlobal.h>
72#include "ccmApi.h"
73#include "sirParams.h"
74#include "dot11f.h"
75#include "wlan_hdd_assoc.h"
76#include "wlan_hdd_wext.h"
77#include "sme_Api.h"
78#include "wlan_hdd_p2p.h"
79#include "wlan_hdd_cfg80211.h"
80#include "wlan_hdd_hostapd.h"
81#include "sapInternal.h"
82#include "wlan_hdd_softap_tx_rx.h"
83#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053084#include "wlan_hdd_assoc.h"
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053085#include "wlan_hdd_power.h"
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053086#include "wlan_hdd_trace.h"
87#include "vos_types.h"
88#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070089#ifdef WLAN_BTAMP_FEATURE
90#include "bap_hdd_misc.h"
91#endif
92#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080093#include "wlan_hdd_tdls.h"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053094#include "wlan_hdd_wmm.h"
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053095#include "wlan_qct_wda.h"
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053096#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070097#include "wlan_hdd_dev_pwr.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +053098#include "qwlan_version.h"
c_manjeecfd1efb2015-09-25 19:32:34 +053099#include "wlan_logging_sock_svc.h"
Agrawal Ashishcfe83282016-09-29 13:03:45 +0530100#include "wlan_hdd_misc.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +0530101
Jeff Johnson295189b2012-06-20 16:38:30 -0700102
103#define g_mode_rates_size (12)
104#define a_mode_rates_size (8)
105#define FREQ_BASE_80211G (2407)
106#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700107#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530108#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700109#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800110 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700111
112#define HDD2GHZCHAN(freq, chan, flag) { \
113 .band = IEEE80211_BAND_2GHZ, \
114 .center_freq = (freq), \
115 .hw_value = (chan),\
116 .flags = (flag), \
117 .max_antenna_gain = 0 ,\
118 .max_power = 30, \
119}
120
121#define HDD5GHZCHAN(freq, chan, flag) { \
122 .band = IEEE80211_BAND_5GHZ, \
123 .center_freq = (freq), \
124 .hw_value = (chan),\
125 .flags = (flag), \
126 .max_antenna_gain = 0 ,\
127 .max_power = 30, \
128}
129
130#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
131{\
132 .bitrate = rate, \
133 .hw_value = rate_id, \
134 .flags = flag, \
135}
136
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530137#ifdef WLAN_FEATURE_VOWIFI_11R
138#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
139#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
140#endif
141
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530142#define HDD_CHANNEL_14 14
Dasari Srinivase18b2cf2014-10-28 17:09:42 +0530143#define WLAN_HDD_MAX_FEATURE_SET 8
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530144
Sunil Duttc69bccb2014-05-26 21:30:20 +0530145#ifdef WLAN_FEATURE_LINK_LAYER_STATS
146/*
147 * Used to allocate the size of 4096 for the link layer stats.
148 * The size of 4096 is considered assuming that all data per
149 * respective event fit with in the limit.Please take a call
150 * on the limit based on the data requirements on link layer
151 * statistics.
152 */
153#define LL_STATS_EVENT_BUF_SIZE 4096
154#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +0530155#ifdef WLAN_FEATURE_EXTSCAN
156/*
157 * Used to allocate the size of 4096 for the EXTScan NL data.
158 * The size of 4096 is considered assuming that all data per
159 * respective event fit with in the limit.Please take a call
160 * on the limit based on the data requirements.
161 */
162
163#define EXTSCAN_EVENT_BUF_SIZE 4096
164#define EXTSCAN_MAX_CACHED_RESULTS_PER_IND 32
165#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +0530166
Atul Mittal115287b2014-07-08 13:26:33 +0530167/*EXT TDLS*/
168/*
169 * Used to allocate the size of 4096 for the TDLS.
170 * The size of 4096 is considered assuming that all data per
171 * respective event fit with in the limit.Please take a call
172 * on the limit based on the data requirements on link layer
173 * statistics.
174 */
175#define EXTTDLS_EVENT_BUF_SIZE 4096
176
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +0530177/*
178 * Values for Mac spoofing feature
179 *
180 */
181#define MAC_ADDR_SPOOFING_FW_HOST_DISABLE 0
182#define MAC_ADDR_SPOOFING_FW_HOST_ENABLE 1
183#define MAC_ADDR_SPOOFING_FW_ENABLE_HOST_DISABLE 2
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +0530184#define MAC_ADDR_SPOOFING_DEFER_INTERVAL 10 //in ms
185
Anurag Chouhan343af7e2016-12-16 13:11:19 +0530186/*
187 * max_sched_scan_plans defined to 10
188 */
189#define MAX_SCHED_SCAN_PLANS 10
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +0530190
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530191static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700192{
193 WLAN_CIPHER_SUITE_WEP40,
194 WLAN_CIPHER_SUITE_WEP104,
195 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800196#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700197#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
198 WLAN_CIPHER_SUITE_KRK,
199 WLAN_CIPHER_SUITE_CCMP,
200#else
201 WLAN_CIPHER_SUITE_CCMP,
202#endif
203#ifdef FEATURE_WLAN_WAPI
204 WLAN_CIPHER_SUITE_SMS4,
205#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700206#ifdef WLAN_FEATURE_11W
207 WLAN_CIPHER_SUITE_AES_CMAC,
208#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700209};
210
211static inline int is_broadcast_ether_addr(const u8 *addr)
212{
213 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
214 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
215}
216
Agrawal Ashish97dec502015-11-26 20:20:58 +0530217const static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530218{
Jeff Johnson295189b2012-06-20 16:38:30 -0700219 HDD2GHZCHAN(2412, 1, 0) ,
220 HDD2GHZCHAN(2417, 2, 0) ,
221 HDD2GHZCHAN(2422, 3, 0) ,
222 HDD2GHZCHAN(2427, 4, 0) ,
223 HDD2GHZCHAN(2432, 5, 0) ,
224 HDD2GHZCHAN(2437, 6, 0) ,
225 HDD2GHZCHAN(2442, 7, 0) ,
226 HDD2GHZCHAN(2447, 8, 0) ,
227 HDD2GHZCHAN(2452, 9, 0) ,
228 HDD2GHZCHAN(2457, 10, 0) ,
229 HDD2GHZCHAN(2462, 11, 0) ,
230 HDD2GHZCHAN(2467, 12, 0) ,
231 HDD2GHZCHAN(2472, 13, 0) ,
232 HDD2GHZCHAN(2484, 14, 0) ,
233};
234
Agrawal Ashish97dec502015-11-26 20:20:58 +0530235const static struct ieee80211_channel hdd_channels_5_GHZ[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700236{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700237 HDD5GHZCHAN(4920, 240, 0) ,
238 HDD5GHZCHAN(4940, 244, 0) ,
239 HDD5GHZCHAN(4960, 248, 0) ,
240 HDD5GHZCHAN(4980, 252, 0) ,
241 HDD5GHZCHAN(5040, 208, 0) ,
242 HDD5GHZCHAN(5060, 212, 0) ,
243 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700244 HDD5GHZCHAN(5180, 36, 0) ,
245 HDD5GHZCHAN(5200, 40, 0) ,
246 HDD5GHZCHAN(5220, 44, 0) ,
247 HDD5GHZCHAN(5240, 48, 0) ,
248 HDD5GHZCHAN(5260, 52, 0) ,
249 HDD5GHZCHAN(5280, 56, 0) ,
250 HDD5GHZCHAN(5300, 60, 0) ,
251 HDD5GHZCHAN(5320, 64, 0) ,
252 HDD5GHZCHAN(5500,100, 0) ,
253 HDD5GHZCHAN(5520,104, 0) ,
254 HDD5GHZCHAN(5540,108, 0) ,
255 HDD5GHZCHAN(5560,112, 0) ,
256 HDD5GHZCHAN(5580,116, 0) ,
257 HDD5GHZCHAN(5600,120, 0) ,
258 HDD5GHZCHAN(5620,124, 0) ,
259 HDD5GHZCHAN(5640,128, 0) ,
260 HDD5GHZCHAN(5660,132, 0) ,
261 HDD5GHZCHAN(5680,136, 0) ,
262 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800263#ifdef FEATURE_WLAN_CH144
264 HDD5GHZCHAN(5720,144, 0) ,
265#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700266 HDD5GHZCHAN(5745,149, 0) ,
267 HDD5GHZCHAN(5765,153, 0) ,
268 HDD5GHZCHAN(5785,157, 0) ,
269 HDD5GHZCHAN(5805,161, 0) ,
270 HDD5GHZCHAN(5825,165, 0) ,
271};
272
273static struct ieee80211_rate g_mode_rates[] =
274{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530275 HDD_G_MODE_RATETAB(10, 0x1, 0),
276 HDD_G_MODE_RATETAB(20, 0x2, 0),
277 HDD_G_MODE_RATETAB(55, 0x4, 0),
278 HDD_G_MODE_RATETAB(110, 0x8, 0),
279 HDD_G_MODE_RATETAB(60, 0x10, 0),
280 HDD_G_MODE_RATETAB(90, 0x20, 0),
281 HDD_G_MODE_RATETAB(120, 0x40, 0),
282 HDD_G_MODE_RATETAB(180, 0x80, 0),
283 HDD_G_MODE_RATETAB(240, 0x100, 0),
284 HDD_G_MODE_RATETAB(360, 0x200, 0),
285 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700286 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530287};
Jeff Johnson295189b2012-06-20 16:38:30 -0700288
289static struct ieee80211_rate a_mode_rates[] =
290{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530291 HDD_G_MODE_RATETAB(60, 0x10, 0),
292 HDD_G_MODE_RATETAB(90, 0x20, 0),
293 HDD_G_MODE_RATETAB(120, 0x40, 0),
294 HDD_G_MODE_RATETAB(180, 0x80, 0),
295 HDD_G_MODE_RATETAB(240, 0x100, 0),
296 HDD_G_MODE_RATETAB(360, 0x200, 0),
297 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700298 HDD_G_MODE_RATETAB(540, 0x800, 0),
299};
300
301static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
302{
Agrawal Ashish97dec502015-11-26 20:20:58 +0530303 .channels = NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700304 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
305 .band = IEEE80211_BAND_2GHZ,
306 .bitrates = g_mode_rates,
307 .n_bitrates = g_mode_rates_size,
308 .ht_cap.ht_supported = 1,
309 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
310 | IEEE80211_HT_CAP_GRN_FLD
311 | IEEE80211_HT_CAP_DSSSCCK40
312 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
313 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
314 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
315 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
316 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
317 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
318};
319
Jeff Johnson295189b2012-06-20 16:38:30 -0700320static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
321{
Agrawal Ashish97dec502015-11-26 20:20:58 +0530322 .channels = NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700323 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
324 .band = IEEE80211_BAND_5GHZ,
325 .bitrates = a_mode_rates,
326 .n_bitrates = a_mode_rates_size,
327 .ht_cap.ht_supported = 1,
328 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
329 | IEEE80211_HT_CAP_GRN_FLD
330 | IEEE80211_HT_CAP_DSSSCCK40
331 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
332 | IEEE80211_HT_CAP_SGI_40
333 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
334 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
335 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
336 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
337 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
338 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
339};
340
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530341/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700342 TX/RX direction for each kind of interface */
343static const struct ieee80211_txrx_stypes
344wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
345 [NL80211_IFTYPE_STATION] = {
346 .tx = 0xffff,
347 .rx = BIT(SIR_MAC_MGMT_ACTION) |
348 BIT(SIR_MAC_MGMT_PROBE_REQ),
349 },
350 [NL80211_IFTYPE_AP] = {
351 .tx = 0xffff,
352 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
353 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
354 BIT(SIR_MAC_MGMT_PROBE_REQ) |
355 BIT(SIR_MAC_MGMT_DISASSOC) |
356 BIT(SIR_MAC_MGMT_AUTH) |
357 BIT(SIR_MAC_MGMT_DEAUTH) |
358 BIT(SIR_MAC_MGMT_ACTION),
359 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700360 [NL80211_IFTYPE_ADHOC] = {
361 .tx = 0xffff,
362 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
363 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
364 BIT(SIR_MAC_MGMT_PROBE_REQ) |
365 BIT(SIR_MAC_MGMT_DISASSOC) |
366 BIT(SIR_MAC_MGMT_AUTH) |
367 BIT(SIR_MAC_MGMT_DEAUTH) |
368 BIT(SIR_MAC_MGMT_ACTION),
369 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700370 [NL80211_IFTYPE_P2P_CLIENT] = {
371 .tx = 0xffff,
372 .rx = BIT(SIR_MAC_MGMT_ACTION) |
373 BIT(SIR_MAC_MGMT_PROBE_REQ),
374 },
375 [NL80211_IFTYPE_P2P_GO] = {
376 /* This is also same as for SoftAP */
377 .tx = 0xffff,
378 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
379 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
380 BIT(SIR_MAC_MGMT_PROBE_REQ) |
381 BIT(SIR_MAC_MGMT_DISASSOC) |
382 BIT(SIR_MAC_MGMT_AUTH) |
383 BIT(SIR_MAC_MGMT_DEAUTH) |
384 BIT(SIR_MAC_MGMT_ACTION),
385 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700386};
387
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800388#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800389static const struct ieee80211_iface_limit
390wlan_hdd_iface_limit[] = {
391 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800392 /* max = 3 ; Our driver create two interfaces during driver init
393 * wlan0 and p2p0 interfaces. p2p0 is considered as station
394 * interface until a group is formed. In JB architecture, once the
395 * group is formed, interface type of p2p0 is changed to P2P GO or
396 * Client.
397 * When supplicant remove the group, it first issue a set interface
398 * cmd to change the mode back to Station. In JB this works fine as
399 * we advertize two station type interface during driver init.
400 * Some vendors create separate interface for P2P GO/Client,
401 * after group formation(Third one). But while group remove
402 * supplicant first tries to change the mode(3rd interface) to STATION
403 * But as we advertized only two sta type interfaces nl80211 was
404 * returning error for the third one which was leading to failure in
405 * delete interface. Ideally while removing the group, supplicant
406 * should not try to change the 3rd interface mode to Station type.
407 * Till we get a fix in wpa_supplicant, we advertize max STA
408 * interface type to 3
409 */
410 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800411 .types = BIT(NL80211_IFTYPE_STATION),
412 },
413 {
414 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700415 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800416 },
417 {
418 .max = 1,
419 .types = BIT(NL80211_IFTYPE_P2P_GO) |
420 BIT(NL80211_IFTYPE_P2P_CLIENT),
421 },
422};
423
424/* By default, only single channel concurrency is allowed */
425static struct ieee80211_iface_combination
426wlan_hdd_iface_combination = {
427 .limits = wlan_hdd_iface_limit,
428 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800429 /*
430 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
431 * and p2p0 interfaces during driver init
432 * Some vendors create separate interface for P2P operations.
433 * wlan0: STA interface
434 * p2p0: P2P Device interface, action frames goes
435 * through this interface.
436 * p2p-xx: P2P interface, After GO negotiation this interface is
437 * created for p2p operations(GO/CLIENT interface).
438 */
439 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800440 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
441 .beacon_int_infra_match = false,
442};
443#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800444
Jeff Johnson295189b2012-06-20 16:38:30 -0700445static struct cfg80211_ops wlan_hdd_cfg80211_ops;
446
447/* Data rate 100KBPS based on IE Index */
448struct index_data_rate_type
449{
450 v_U8_t beacon_rate_index;
451 v_U16_t supported_rate[4];
452};
453
454/* 11B, 11G Rate table include Basic rate and Extended rate
455 The IDX field is the rate index
456 The HI field is the rate when RSSI is strong or being ignored
457 (in this case we report actual rate)
458 The MID field is the rate when RSSI is moderate
459 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
460 The LO field is the rate when RSSI is low
461 (in this case we don't report rates, actual current rate used)
462 */
463static const struct
464{
465 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700466 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700467} supported_data_rate[] =
468{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700469/* IDX HI HM LM LO (RSSI-based index */
470 {2, { 10, 10, 10, 0}},
471 {4, { 20, 20, 10, 0}},
472 {11, { 55, 20, 10, 0}},
473 {12, { 60, 55, 20, 0}},
474 {18, { 90, 55, 20, 0}},
475 {22, {110, 55, 20, 0}},
476 {24, {120, 90, 60, 0}},
477 {36, {180, 120, 60, 0}},
478 {44, {220, 180, 60, 0}},
479 {48, {240, 180, 90, 0}},
480 {66, {330, 180, 90, 0}},
481 {72, {360, 240, 90, 0}},
482 {96, {480, 240, 120, 0}},
483 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700484};
485
486/* MCS Based rate table */
487static struct index_data_rate_type supported_mcs_rate[] =
488{
489/* MCS L20 L40 S20 S40 */
490 {0, {65, 135, 72, 150}},
491 {1, {130, 270, 144, 300}},
492 {2, {195, 405, 217, 450}},
493 {3, {260, 540, 289, 600}},
494 {4, {390, 810, 433, 900}},
495 {5, {520, 1080, 578, 1200}},
496 {6, {585, 1215, 650, 1350}},
497 {7, {650, 1350, 722, 1500}}
498};
499
Leo Chang6f8870f2013-03-26 18:11:36 -0700500#ifdef WLAN_FEATURE_11AC
501
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530502#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700503
504struct index_vht_data_rate_type
505{
506 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530507 v_U16_t supported_VHT80_rate[2];
508 v_U16_t supported_VHT40_rate[2];
509 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700510};
511
512typedef enum
513{
514 DATA_RATE_11AC_MAX_MCS_7,
515 DATA_RATE_11AC_MAX_MCS_8,
516 DATA_RATE_11AC_MAX_MCS_9,
517 DATA_RATE_11AC_MAX_MCS_NA
518} eDataRate11ACMaxMcs;
519
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530520/* SSID broadcast type */
521typedef enum eSSIDBcastType
522{
523 eBCAST_UNKNOWN = 0,
524 eBCAST_NORMAL = 1,
525 eBCAST_HIDDEN = 2,
526} tSSIDBcastType;
527
Leo Chang6f8870f2013-03-26 18:11:36 -0700528/* MCS Based VHT rate table */
529static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
530{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530531/* MCS L80 S80 L40 S40 L20 S40*/
532 {0, {293, 325}, {135, 150}, {65, 72}},
533 {1, {585, 650}, {270, 300}, {130, 144}},
534 {2, {878, 975}, {405, 450}, {195, 217}},
535 {3, {1170, 1300}, {540, 600}, {260, 289}},
536 {4, {1755, 1950}, {810, 900}, {390, 433}},
537 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
538 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
539 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
540 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
541 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700542};
543#endif /* WLAN_FEATURE_11AC */
544
c_hpothu79aab322014-07-14 21:11:01 +0530545/*array index points to MCS and array value points respective rssi*/
546static int rssiMcsTbl[][10] =
547{
548/*MCS 0 1 2 3 4 5 6 7 8 9*/
549 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
550 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
551 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
552};
553
Jeff Johnson295189b2012-06-20 16:38:30 -0700554extern struct net_device_ops net_ops_struct;
Dasari Srinivas7875a302014-09-26 17:50:57 +0530555#ifdef FEATURE_WLAN_SCAN_PNO
556static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
557#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700558
Leo Chang9056f462013-08-01 19:21:11 -0700559#ifdef WLAN_NL80211_TESTMODE
560enum wlan_hdd_tm_attr
561{
562 WLAN_HDD_TM_ATTR_INVALID = 0,
563 WLAN_HDD_TM_ATTR_CMD = 1,
564 WLAN_HDD_TM_ATTR_DATA = 2,
565 WLAN_HDD_TM_ATTR_TYPE = 3,
566 /* keep last */
567 WLAN_HDD_TM_ATTR_AFTER_LAST,
568 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
569};
570
571enum wlan_hdd_tm_cmd
572{
573 WLAN_HDD_TM_CMD_WLAN_HB = 1,
574};
575
576#define WLAN_HDD_TM_DATA_MAX_LEN 5000
577
578static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
579{
580 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
581 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
582 .len = WLAN_HDD_TM_DATA_MAX_LEN },
583};
584#endif /* WLAN_NL80211_TESTMODE */
585
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800586#ifdef FEATURE_WLAN_CH_AVOID
587/*
588 * FUNCTION: wlan_hdd_send_avoid_freq_event
589 * This is called when wlan driver needs to send vendor specific
590 * avoid frequency range event to userspace
591 */
592int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
593 tHddAvoidFreqList *pAvoidFreqList)
594{
595 struct sk_buff *vendor_event;
596
597 ENTER();
598
599 if (!pHddCtx)
600 {
601 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
602 "%s: HDD context is null", __func__);
603 return -1;
604 }
605
606 if (!pAvoidFreqList)
607 {
608 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
609 "%s: pAvoidFreqList is null", __func__);
610 return -1;
611 }
612
613 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530614#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
615 NULL,
616#endif
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800617 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530618 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800619 GFP_KERNEL);
620 if (!vendor_event)
621 {
622 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
623 "%s: cfg80211_vendor_event_alloc failed", __func__);
624 return -1;
625 }
626
627 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
628 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
629
630 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
631
632 EXIT();
633 return 0;
634}
635#endif /* FEATURE_WLAN_CH_AVOID */
636
Srinivas Dasari030bad32015-02-18 23:23:54 +0530637/*
638 * FUNCTION: __wlan_hdd_cfg80211_nan_request
639 * This is called when wlan driver needs to send vendor specific
640 * nan request event.
641 */
642static int __wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
643 struct wireless_dev *wdev,
644 const void *data, int data_len)
645{
646 tNanRequestReq nan_req;
647 VOS_STATUS status;
648 int ret_val = -1;
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530649 struct net_device *dev = wdev->netdev;
650 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
651 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530652 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
653
654 if (0 == data_len)
655 {
656 hddLog(VOS_TRACE_LEVEL_ERROR,
657 FL("NAN - Invalid Request, length = 0"));
658 return ret_val;
659 }
660
661 if (NULL == data)
662 {
663 hddLog(VOS_TRACE_LEVEL_ERROR,
664 FL("NAN - Invalid Request, data is NULL"));
665 return ret_val;
666 }
667
668 status = wlan_hdd_validate_context(pHddCtx);
669 if (0 != status)
670 {
671 hddLog(VOS_TRACE_LEVEL_ERROR,
672 FL("HDD context is not valid"));
673 return -EINVAL;
674 }
675
676 hddLog(LOG1, FL("Received NAN command"));
677 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
678 (tANI_U8 *)data, data_len);
679
680 /* check the NAN Capability */
681 if (TRUE != sme_IsFeatureSupportedByFW(NAN))
682 {
683 hddLog(VOS_TRACE_LEVEL_ERROR,
684 FL("NAN is not supported by Firmware"));
685 return -EINVAL;
686 }
687
688 nan_req.request_data_len = data_len;
689 nan_req.request_data = data;
690
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530691 status = sme_NanRequest(hHal, &nan_req, pAdapter->sessionId);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530692 if (VOS_STATUS_SUCCESS == status)
693 {
694 ret_val = 0;
695 }
696 return ret_val;
697}
698
699/*
700 * FUNCTION: wlan_hdd_cfg80211_nan_request
701 * Wrapper to protect the nan vendor command from ssr
702 */
703static int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
704 struct wireless_dev *wdev,
705 const void *data, int data_len)
706{
707 int ret;
708
709 vos_ssr_protect(__func__);
710 ret = __wlan_hdd_cfg80211_nan_request(wiphy, wdev, data, data_len);
711 vos_ssr_unprotect(__func__);
712
713 return ret;
714}
715
716/*
717 * FUNCTION: wlan_hdd_cfg80211_nan_callback
718 * This is a callback function and it gets called
719 * when we need to report nan response event to
720 * upper layers.
721 */
722static void wlan_hdd_cfg80211_nan_callback(void* ctx, tSirNanEvent* msg)
723{
724 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
725 struct sk_buff *vendor_event;
726 int status;
727 tSirNanEvent *data;
728
729 ENTER();
730 if (NULL == msg)
731 {
732 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
733 FL(" msg received here is null"));
734 return;
735 }
736 data = msg;
737
738 status = wlan_hdd_validate_context(pHddCtx);
739
740 if (0 != status)
741 {
742 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
743 FL("HDD context is not valid"));
744 return;
745 }
746
747 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530748#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
749 NULL,
750#endif
Srinivas Dasari030bad32015-02-18 23:23:54 +0530751 data->event_data_len +
752 NLMSG_HDRLEN,
753 QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX,
754 GFP_KERNEL);
755
756 if (!vendor_event)
757 {
758 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
759 FL("cfg80211_vendor_event_alloc failed"));
760 return;
761 }
762 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN,
763 data->event_data_len, data->event_data))
764 {
765 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
766 FL("QCA_WLAN_VENDOR_ATTR_NAN put fail"));
767 kfree_skb(vendor_event);
768 return;
769 }
770 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
771 EXIT();
772}
773
774/*
775 * FUNCTION: wlan_hdd_cfg80211_nan_init
776 * This function is called to register the callback to sme layer
777 */
778inline void wlan_hdd_cfg80211_nan_init(hdd_context_t *pHddCtx)
779{
780 sme_NanRegisterCallback(pHddCtx->hHal, wlan_hdd_cfg80211_nan_callback);
781}
782
Anurag Chouhanfcd20172017-07-19 17:25:19 +0530783/*
784 * define short names for the global vendor params
785 * used by __wlan_hdd_cfg80211_get_station_cmd()
786 */
787#define STATION_INVALID \
788 QCA_WLAN_VENDOR_ATTR_GET_STATION_INVALID
789#define STATION_INFO \
790 QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO
791#define STATION_ASSOC_FAIL_REASON \
792 QCA_WLAN_VENDOR_ATTR_GET_STATION_ASSOC_FAIL_REASON
793#define STATION_MAX \
794 QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX
795
796static const struct nla_policy
797hdd_get_station_policy[STATION_MAX + 1] = {
798 [STATION_INFO] = {.type = NLA_FLAG},
799 [STATION_ASSOC_FAIL_REASON] = {.type = NLA_FLAG},
800};
801
802/**
803 * hdd_get_station_assoc_fail() - Handle get station assoc fail
804 * @hdd_ctx: HDD context within host driver
805 * @wdev: wireless device
806 *
807 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION_ASSOC_FAIL.
808 * Validate cmd attributes and send the station info to upper layers.
809 *
810 * Return: Success(0) or reason code for failure
811 */
812static int hdd_get_station_assoc_fail(hdd_context_t *hdd_ctx,
813 hdd_adapter_t *adapter)
814{
815 struct sk_buff *skb = NULL;
816 uint32_t nl_buf_len;
817 hdd_station_ctx_t *hdd_sta_ctx;
818
819 nl_buf_len = NLMSG_HDRLEN;
820 nl_buf_len += sizeof(uint32_t);
821 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
822
823 if (!skb) {
824 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"cfg80211_vendor_cmd_alloc_reply_skb failed");
825 return -ENOMEM;
826 }
827
828 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
829
830 if (nla_put_u32(skb, INFO_ASSOC_FAIL_REASON,
831 hdd_sta_ctx->conn_info.assoc_status_code)) {
832 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
833 goto fail;
834 }
835 return cfg80211_vendor_cmd_reply(skb);
836fail:
837 if (skb)
838 kfree_skb(skb);
839 return -EINVAL;
840}
841
842/**
843 * hdd_map_auth_type() - transform auth type specific to
844 * vendor command
845 * @auth_type: csr auth type
846 *
847 * Return: Success(0) or reason code for failure
848 */
849static int hdd_convert_auth_type(uint32_t auth_type)
850{
851 uint32_t ret_val;
852
853 switch (auth_type) {
854 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
855 ret_val = QCA_WLAN_AUTH_TYPE_OPEN;
856 break;
857 case eCSR_AUTH_TYPE_SHARED_KEY:
858 ret_val = QCA_WLAN_AUTH_TYPE_SHARED;
859 break;
860 case eCSR_AUTH_TYPE_WPA:
861 ret_val = QCA_WLAN_AUTH_TYPE_WPA;
862 break;
863 case eCSR_AUTH_TYPE_WPA_PSK:
864 ret_val = QCA_WLAN_AUTH_TYPE_WPA_PSK;
865 break;
866 case eCSR_AUTH_TYPE_AUTOSWITCH:
867 ret_val = QCA_WLAN_AUTH_TYPE_AUTOSWITCH;
868 break;
869 case eCSR_AUTH_TYPE_WPA_NONE:
870 ret_val = QCA_WLAN_AUTH_TYPE_WPA_NONE;
871 break;
872 case eCSR_AUTH_TYPE_RSN:
873 ret_val = QCA_WLAN_AUTH_TYPE_RSN;
874 break;
875 case eCSR_AUTH_TYPE_RSN_PSK:
876 ret_val = QCA_WLAN_AUTH_TYPE_RSN_PSK;
877 break;
878 case eCSR_AUTH_TYPE_FT_RSN:
879 ret_val = QCA_WLAN_AUTH_TYPE_FT;
880 break;
881 case eCSR_AUTH_TYPE_FT_RSN_PSK:
882 ret_val = QCA_WLAN_AUTH_TYPE_FT_PSK;
883 break;
884 case eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE:
885 ret_val = QCA_WLAN_AUTH_TYPE_WAI;
886 break;
887 case eCSR_AUTH_TYPE_WAPI_WAI_PSK:
888 ret_val = QCA_WLAN_AUTH_TYPE_WAI_PSK;
889 break;
890#ifdef FEATURE_WLAN_ESE
891 case eCSR_AUTH_TYPE_CCKM_WPA:
892 ret_val = QCA_WLAN_AUTH_TYPE_CCKM_WPA;
893 break;
894 case eCSR_AUTH_TYPE_CCKM_RSN:
895 ret_val = QCA_WLAN_AUTH_TYPE_CCKM_RSN;
896 break;
897#endif
898 case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
899 ret_val = QCA_WLAN_AUTH_TYPE_SHA256_PSK;
900 break;
901 case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
902 ret_val = QCA_WLAN_AUTH_TYPE_SHA256;
903 break;
904 case eCSR_NUM_OF_SUPPORT_AUTH_TYPE:
905 case eCSR_AUTH_TYPE_FAILED:
906 case eCSR_AUTH_TYPE_NONE:
907 default:
908 ret_val = QCA_WLAN_AUTH_TYPE_INVALID;
909 break;
910 }
911 return ret_val;
912}
913
914/**
915 * hdd_map_dot_11_mode() - transform dot11mode type specific to
916 * vendor command
917 * @dot11mode: dot11mode
918 *
919 * Return: Success(0) or reason code for failure
920 */
921static int hdd_convert_dot11mode(uint32_t dot11mode)
922{
923 uint32_t ret_val;
924
925 switch (dot11mode) {
926 case eCSR_CFG_DOT11_MODE_11A:
927 ret_val = QCA_WLAN_802_11_MODE_11A;
928 break;
929 case eCSR_CFG_DOT11_MODE_11B:
930 ret_val = QCA_WLAN_802_11_MODE_11B;
931 break;
932 case eCSR_CFG_DOT11_MODE_11G:
933 ret_val = QCA_WLAN_802_11_MODE_11G;
934 break;
935 case eCSR_CFG_DOT11_MODE_11N:
936 ret_val = QCA_WLAN_802_11_MODE_11N;
937 break;
938 case eCSR_CFG_DOT11_MODE_11AC:
939 ret_val = QCA_WLAN_802_11_MODE_11AC;
940 break;
941 case eCSR_CFG_DOT11_MODE_AUTO:
942 case eCSR_CFG_DOT11_MODE_ABG:
943 default:
944 ret_val = QCA_WLAN_802_11_MODE_INVALID;
945 }
946 return ret_val;
947}
948
949/**
950 * hdd_add_tx_bitrate() - add tx bitrate attribute
951 * @skb: pointer to sk buff
952 * @hdd_sta_ctx: pointer to hdd station context
953 * @idx: attribute index
954 *
955 * Return: Success(0) or reason code for failure
956 */
957static int32_t hdd_add_tx_bitrate(struct sk_buff *skb,
958 hdd_station_ctx_t *hdd_sta_ctx,
959 int idx)
960{
961 struct nlattr *nla_attr;
962 uint32_t bitrate, bitrate_compat;
963
964 nla_attr = nla_nest_start(skb, idx);
965 if (!nla_attr)
966 goto fail;
967 /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
968 bitrate = cfg80211_calculate_bitrate(&hdd_sta_ctx->conn_info.txrate);
969
970 /* report 16-bit bitrate only if we can */
971 bitrate_compat = bitrate < (1UL << 16) ? bitrate : 0;
972 if (bitrate > 0 &&
973 nla_put_u32(skb, NL80211_RATE_INFO_BITRATE32, bitrate)) {
974 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
975 goto fail;
976 }
977 if (bitrate_compat > 0 &&
978 nla_put_u16(skb, NL80211_RATE_INFO_BITRATE, bitrate_compat)) {
979 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
980 goto fail;
981 }
982 if (nla_put_u8(skb, NL80211_RATE_INFO_VHT_NSS,
983 hdd_sta_ctx->conn_info.txrate.nss)) {
984 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
985 goto fail;
986 }
987 nla_nest_end(skb, nla_attr);
988 return 0;
989fail:
990 return -EINVAL;
991}
992
993/**
994 * hdd_add_sta_info() - add station info attribute
995 * @skb: pointer to sk buff
996 * @hdd_sta_ctx: pointer to hdd station context
997 * @idx: attribute index
998 *
999 * Return: Success(0) or reason code for failure
1000 */
1001static int32_t hdd_add_sta_info(struct sk_buff *skb,
1002 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1003{
1004 struct nlattr *nla_attr;
1005
1006 nla_attr = nla_nest_start(skb, idx);
1007 if (!nla_attr)
1008 goto fail;
1009 if (nla_put_u8(skb, NL80211_STA_INFO_SIGNAL,
1010 (hdd_sta_ctx->conn_info.signal + 100))) {
1011 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1012 goto fail;
1013 }
1014 if (hdd_add_tx_bitrate(skb, hdd_sta_ctx, NL80211_STA_INFO_TX_BITRATE))
1015 goto fail;
1016 nla_nest_end(skb, nla_attr);
1017 return 0;
1018fail:
1019 return -EINVAL;
1020}
1021
1022/**
1023 * hdd_add_survey_info() - add survey info attribute
1024 * @skb: pointer to sk buff
1025 * @hdd_sta_ctx: pointer to hdd station context
1026 * @idx: attribute index
1027 *
1028 * Return: Success(0) or reason code for failure
1029 */
1030static int32_t hdd_add_survey_info(struct sk_buff *skb,
1031 hdd_station_ctx_t *hdd_sta_ctx,
1032 int idx)
1033{
1034 struct nlattr *nla_attr;
1035
1036 nla_attr = nla_nest_start(skb, idx);
1037 if (!nla_attr)
1038 goto fail;
1039 if (nla_put_u32(skb, NL80211_SURVEY_INFO_FREQUENCY,
1040 hdd_sta_ctx->conn_info.freq) ||
1041 nla_put_u8(skb, NL80211_SURVEY_INFO_NOISE,
1042 (hdd_sta_ctx->conn_info.noise + 100))) {
1043 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1044 goto fail;
1045 }
1046 nla_nest_end(skb, nla_attr);
1047 return 0;
1048fail:
1049 return -EINVAL;
1050}
1051
1052/**
1053 * hdd_add_link_standard_info() - add link info attribute
1054 * @skb: pointer to sk buff
1055 * @hdd_sta_ctx: pointer to hdd station context
1056 * @idx: attribute index
1057 *
1058 * Return: Success(0) or reason code for failure
1059 */
1060static int32_t
1061hdd_add_link_standard_info(struct sk_buff *skb,
1062 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1063{
1064 struct nlattr *nla_attr;
1065
1066 nla_attr = nla_nest_start(skb, idx);
1067 if (!nla_attr)
1068 goto fail;
1069 if (nla_put(skb,
1070 NL80211_ATTR_SSID,
1071 hdd_sta_ctx->conn_info.SSID.SSID.length,
1072 hdd_sta_ctx->conn_info.SSID.SSID.ssId)) {
1073 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1074 goto fail;
1075 }
1076 if (hdd_add_survey_info(skb, hdd_sta_ctx, NL80211_ATTR_SURVEY_INFO))
1077 goto fail;
1078 if (hdd_add_sta_info(skb, hdd_sta_ctx, NL80211_ATTR_STA_INFO))
1079 goto fail;
1080 nla_nest_end(skb, nla_attr);
1081 return 0;
1082fail:
1083 return -EINVAL;
1084}
1085
1086/**
1087 * hdd_add_ap_standard_info() - add ap info attribute
1088 * @skb: pointer to sk buff
1089 * @hdd_sta_ctx: pointer to hdd station context
1090 * @idx: attribute index
1091 *
1092 * Return: Success(0) or reason code for failure
1093 */
1094static int32_t
1095hdd_add_ap_standard_info(struct sk_buff *skb,
1096 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1097{
1098 struct nlattr *nla_attr;
1099
1100 nla_attr = nla_nest_start(skb, idx);
1101 if (!nla_attr)
1102 goto fail;
1103 if (hdd_sta_ctx->conn_info.conn_flag.vht_present)
1104 if (nla_put(skb, NL80211_ATTR_VHT_CAPABILITY,
1105 sizeof(hdd_sta_ctx->conn_info.vht_caps),
1106 &hdd_sta_ctx->conn_info.vht_caps)) {
1107 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1108 goto fail;
1109 }
1110 if (hdd_sta_ctx->conn_info.conn_flag.ht_present)
1111 if (nla_put(skb, NL80211_ATTR_HT_CAPABILITY,
1112 sizeof(hdd_sta_ctx->conn_info.ht_caps),
1113 &hdd_sta_ctx->conn_info.ht_caps)) {
1114 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1115 goto fail;
1116 }
1117 nla_nest_end(skb, nla_attr);
1118 return 0;
1119fail:
1120 return -EINVAL;
1121}
1122
1123/**
1124 * hdd_get_station_info() - send BSS information to supplicant
1125 * @hdd_ctx: pointer to hdd context
1126 * @adapter: pointer to adapter
1127 *
1128 * Return: 0 if success else error status
1129 */
1130static int hdd_get_station_info(hdd_context_t *hdd_ctx,
1131 hdd_adapter_t *adapter)
1132{
1133 struct sk_buff *skb = NULL;
1134 uint8_t *tmp_hs20 = NULL;
1135 uint32_t nl_buf_len;
1136 hdd_station_ctx_t *hdd_sta_ctx;
1137
1138 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
1139
1140 nl_buf_len = NLMSG_HDRLEN;
1141 nl_buf_len += sizeof(hdd_sta_ctx->conn_info.SSID.SSID.length) +
1142 sizeof(hdd_sta_ctx->conn_info.freq) +
1143 sizeof(hdd_sta_ctx->conn_info.noise) +
1144 sizeof(hdd_sta_ctx->conn_info.signal) +
1145 (sizeof(uint32_t) * 2) +
1146 sizeof(hdd_sta_ctx->conn_info.txrate.nss) +
1147 sizeof(hdd_sta_ctx->conn_info.roam_count) +
1148 sizeof(hdd_sta_ctx->conn_info.authType) +
1149 sizeof(hdd_sta_ctx->conn_info.dot11Mode);
1150 if (hdd_sta_ctx->conn_info.conn_flag.vht_present)
1151 nl_buf_len += sizeof(hdd_sta_ctx->conn_info.vht_caps);
1152 if (hdd_sta_ctx->conn_info.conn_flag.ht_present)
1153 nl_buf_len += sizeof(hdd_sta_ctx->conn_info.ht_caps);
1154 if (hdd_sta_ctx->conn_info.conn_flag.hs20_present) {
1155 tmp_hs20 = (uint8_t *)&(hdd_sta_ctx->conn_info.hs20vendor_ie);
1156 nl_buf_len += (sizeof(hdd_sta_ctx->conn_info.hs20vendor_ie) -
1157 1);
1158 }
1159 if (hdd_sta_ctx->conn_info.conn_flag.ht_op_present)
1160 nl_buf_len += sizeof(hdd_sta_ctx->conn_info.ht_operation);
1161 if (hdd_sta_ctx->conn_info.conn_flag.vht_op_present)
1162 nl_buf_len += sizeof(hdd_sta_ctx->conn_info.vht_operation);
1163
1164
1165 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
1166 if (!skb) {
1167 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"%s: %d cfg80211_vendor_cmd_alloc_reply_skb failed",
1168 __func__, __LINE__);
1169 return -ENOMEM;
1170 }
1171
1172 if (hdd_add_link_standard_info(skb, hdd_sta_ctx,
1173 LINK_INFO_STANDARD_NL80211_ATTR)) {
1174 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1175 goto fail;
1176 }
1177 if (hdd_add_ap_standard_info(skb, hdd_sta_ctx,
1178 AP_INFO_STANDARD_NL80211_ATTR)) {
1179 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1180 goto fail;
1181 }
1182 if (nla_put_u32(skb, INFO_ROAM_COUNT,
1183 hdd_sta_ctx->conn_info.roam_count) ||
1184 nla_put_u32(skb, INFO_AKM,
1185 hdd_convert_auth_type(
1186 hdd_sta_ctx->conn_info.authType)) ||
1187 nla_put_u32(skb, WLAN802_11_MODE,
1188 hdd_convert_dot11mode(
1189 hdd_sta_ctx->conn_info.dot11Mode))) {
1190 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1191 goto fail;
1192 }
1193 if (hdd_sta_ctx->conn_info.conn_flag.ht_op_present)
1194 if (nla_put(skb, HT_OPERATION,
1195 (sizeof(hdd_sta_ctx->conn_info.ht_operation)),
1196 &hdd_sta_ctx->conn_info.ht_operation)) {
1197 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1198 goto fail;
1199 }
1200 if (hdd_sta_ctx->conn_info.conn_flag.vht_op_present)
1201 if (nla_put(skb, VHT_OPERATION,
1202 (sizeof(hdd_sta_ctx->conn_info.vht_operation)),
1203 &hdd_sta_ctx->conn_info.vht_operation)) {
1204 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1205 goto fail;
1206 }
1207 if (hdd_sta_ctx->conn_info.conn_flag.hs20_present)
1208 if (nla_put(skb, AP_INFO_HS20_INDICATION,
1209 (sizeof(hdd_sta_ctx->conn_info.hs20vendor_ie) - 1),
1210 tmp_hs20 + 1)) {
1211 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1212 goto fail;
1213 }
1214
1215 return cfg80211_vendor_cmd_reply(skb);
1216fail:
1217 if (skb)
1218 kfree_skb(skb);
1219 return -EINVAL;
1220}
1221
1222/**
1223 * __hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
1224 * @wiphy: corestack handler
1225 * @wdev: wireless device
1226 * @data: data
1227 * @data_len: data length
1228 *
1229 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
1230 * Validate cmd attributes and send the station info to upper layers.
1231 *
1232 * Return: Success(0) or reason code for failure
1233 */
1234static int32_t
1235__hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
1236 struct wireless_dev *wdev,
1237 const void *data,
1238 int data_len)
1239{
1240 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
1241 struct net_device *dev = wdev->netdev;
1242 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
1243 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX + 1];
1244 int32_t status;
1245
1246 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"Enter");
1247 if (VOS_FTM_MODE == hdd_get_conparam()) {
1248 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"Command not allowed in FTM mode");
1249 status = -EPERM;
1250 goto out;
1251 }
1252
1253 status = wlan_hdd_validate_context(hdd_ctx);
1254 if (0 != status)
1255 goto out;
1256
1257
1258 status = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX,
1259 data, data_len, NULL);
1260 if (status) {
1261 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"Invalid ATTR");
1262 goto out;
1263 }
1264
1265 /* Parse and fetch Command Type*/
1266 if (tb[STATION_INFO]) {
1267 status = hdd_get_station_info(hdd_ctx, adapter);
1268 } else if (tb[STATION_ASSOC_FAIL_REASON]) {
1269 status = hdd_get_station_assoc_fail(hdd_ctx, adapter);
1270 } else {
1271 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"get station info cmd type failed");
1272 status = -EINVAL;
1273 goto out;
1274 }
1275 EXIT();
1276out:
1277 return status;
1278}
1279
1280/**
1281 * wlan_hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
1282 * @wiphy: corestack handler
1283 * @wdev: wireless device
1284 * @data: data
1285 * @data_len: data length
1286 *
1287 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
1288 * Validate cmd attributes and send the station info to upper layers.
1289 *
1290 * Return: Success(0) or reason code for failure
1291 */
1292static int32_t
1293hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
1294 struct wireless_dev *wdev,
1295 const void *data,
1296 int data_len)
1297{
1298 int ret;
1299
1300 vos_ssr_protect(__func__);
1301 ret = __hdd_cfg80211_get_station_cmd(wiphy, wdev, data, data_len);
1302 vos_ssr_unprotect(__func__);
1303
1304 return ret;
1305}
1306
1307/*
1308 * undef short names defined for get station command
1309 * used by __wlan_hdd_cfg80211_get_station_cmd()
1310 */
1311#undef STATION_INVALID
1312#undef STATION_INFO
1313#undef STATION_ASSOC_FAIL_REASON
1314#undef STATION_MAX
Srinivas Dasari030bad32015-02-18 23:23:54 +05301315
Sunil Duttc69bccb2014-05-26 21:30:20 +05301316#ifdef WLAN_FEATURE_LINK_LAYER_STATS
1317
1318static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
1319 struct sk_buff *vendor_event)
1320{
1321 if (nla_put_u8(vendor_event,
1322 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
1323 stats->rate.preamble) ||
1324 nla_put_u8(vendor_event,
1325 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
1326 stats->rate.nss) ||
1327 nla_put_u8(vendor_event,
1328 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
1329 stats->rate.bw) ||
1330 nla_put_u8(vendor_event,
1331 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
1332 stats->rate.rateMcsIdx) ||
1333 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
1334 stats->rate.bitrate ) ||
1335 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
1336 stats->txMpdu ) ||
1337 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
1338 stats->rxMpdu ) ||
1339 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
1340 stats->mpduLost ) ||
1341 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
1342 stats->retries) ||
1343 nla_put_u32(vendor_event,
1344 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
1345 stats->retriesShort ) ||
1346 nla_put_u32(vendor_event,
1347 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
1348 stats->retriesLong))
1349 {
1350 hddLog(VOS_TRACE_LEVEL_ERROR,
1351 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1352 return FALSE;
1353 }
1354 return TRUE;
1355}
1356
1357static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
1358 struct sk_buff *vendor_event)
1359{
1360 u32 i = 0;
1361 struct nlattr *rateInfo;
1362 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
1363 stats->type) ||
1364 nla_put(vendor_event,
1365 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
1366 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
1367 nla_put_u32(vendor_event,
1368 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
1369 stats->capabilities) ||
1370 nla_put_u32(vendor_event,
1371 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
1372 stats->numRate))
1373 {
1374 hddLog(VOS_TRACE_LEVEL_ERROR,
1375 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1376 goto error;
1377 }
1378
1379 rateInfo = nla_nest_start(vendor_event,
1380 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301381 if(!rateInfo)
1382 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301383 for (i = 0; i < stats->numRate; i++)
1384 {
1385 struct nlattr *rates;
1386 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
1387 stats->rateStats +
1388 (i * sizeof(tSirWifiRateStat)));
1389 rates = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301390 if(!rates)
1391 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301392
1393 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
1394 {
1395 hddLog(VOS_TRACE_LEVEL_ERROR,
1396 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1397 return FALSE;
1398 }
1399 nla_nest_end(vendor_event, rates);
1400 }
1401 nla_nest_end(vendor_event, rateInfo);
1402
1403 return TRUE;
1404error:
1405 return FALSE;
1406}
1407
1408static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
1409 struct sk_buff *vendor_event)
1410{
1411 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
1412 stats->ac ) ||
1413 nla_put_u32(vendor_event,
1414 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
1415 stats->txMpdu ) ||
1416 nla_put_u32(vendor_event,
1417 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
1418 stats->rxMpdu ) ||
1419 nla_put_u32(vendor_event,
1420 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
1421 stats->txMcast ) ||
1422 nla_put_u32(vendor_event,
1423 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
1424 stats->rxMcast ) ||
1425 nla_put_u32(vendor_event,
1426 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
1427 stats->rxAmpdu ) ||
1428 nla_put_u32(vendor_event,
1429 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
1430 stats->txAmpdu ) ||
1431 nla_put_u32(vendor_event,
1432 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
1433 stats->mpduLost )||
1434 nla_put_u32(vendor_event,
1435 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
1436 stats->retries ) ||
1437 nla_put_u32(vendor_event,
1438 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
1439 stats->retriesShort ) ||
1440 nla_put_u32(vendor_event,
1441 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
1442 stats->retriesLong ) ||
1443 nla_put_u32(vendor_event,
1444 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
1445 stats->contentionTimeMin ) ||
1446 nla_put_u32(vendor_event,
1447 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
1448 stats->contentionTimeMax ) ||
1449 nla_put_u32(vendor_event,
1450 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
1451 stats->contentionTimeAvg ) ||
1452 nla_put_u32(vendor_event,
1453 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
1454 stats->contentionNumSamples ))
1455 {
1456 hddLog(VOS_TRACE_LEVEL_ERROR,
1457 FL("QCA_WLAN_VENDOR_ATTR put fail") );
1458 return FALSE;
1459 }
1460 return TRUE;
1461}
1462
1463static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
1464 struct sk_buff *vendor_event)
1465{
Dino Myclec8f3f332014-07-21 16:48:27 +05301466 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301467 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
1468 nla_put(vendor_event,
1469 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
1470 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
1471 nla_put_u32(vendor_event,
1472 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
1473 stats->state ) ||
1474 nla_put_u32(vendor_event,
1475 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
1476 stats->roaming ) ||
1477 nla_put_u32(vendor_event,
1478 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
1479 stats->capabilities ) ||
1480 nla_put(vendor_event,
1481 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
1482 strlen(stats->ssid), stats->ssid) ||
1483 nla_put(vendor_event,
1484 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
1485 WNI_CFG_BSSID_LEN, stats->bssid) ||
1486 nla_put(vendor_event,
1487 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
1488 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
1489 nla_put(vendor_event,
1490 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
1491 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
1492 )
1493 {
1494 hddLog(VOS_TRACE_LEVEL_ERROR,
1495 FL("QCA_WLAN_VENDOR_ATTR put fail") );
1496 return FALSE;
1497 }
1498 return TRUE;
1499}
1500
Dino Mycle3b9536d2014-07-09 22:05:24 +05301501static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
1502 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301503 struct sk_buff *vendor_event)
1504{
1505 int i = 0;
1506 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301507 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1508 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05301509 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301510
Sunil Duttc69bccb2014-05-26 21:30:20 +05301511 if (FALSE == put_wifi_interface_info(
1512 &pWifiIfaceStat->info,
1513 vendor_event))
1514 {
1515 hddLog(VOS_TRACE_LEVEL_ERROR,
1516 FL("QCA_WLAN_VENDOR_ATTR put fail") );
1517 return FALSE;
1518
1519 }
Dino Mycle3b9536d2014-07-09 22:05:24 +05301520 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
1521 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
1522 if (NULL == pWifiIfaceStatTL)
1523 {
1524 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
1525 return FALSE;
1526 }
1527
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05301528 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
1529 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
1530 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
1531 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
1532
1533 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
1534 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
1535 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
1536 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301537
1538 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
1539 {
1540 if (VOS_STATUS_SUCCESS ==
1541 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1542 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
1543 {
1544 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
1545 * obtained from TL structure
1546 */
1547
1548 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
1549 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301550 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
1551
Srinivas Dasari98947432014-11-07 19:41:24 +05301552 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
1553 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
1554 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
1555 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
1556 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
1557 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
1558 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
1559 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301560
Srinivas Dasari98947432014-11-07 19:41:24 +05301561 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
1562 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
1563 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
1564 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
1565 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
1566 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
1567 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
1568 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301569
Srinivas Dasari98947432014-11-07 19:41:24 +05301570 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
1571 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
1572 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
1573 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
1574 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
1575 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
1576 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
1577 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301578 }
1579 else
1580 {
1581 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
1582 }
1583
Dino Mycle3b9536d2014-07-09 22:05:24 +05301584 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
1585 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
1586 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
1587 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
1588 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
1589 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
1590 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
1591 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
1592 }
1593 else
1594 {
1595 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
1596 }
1597
1598
Sunil Duttc69bccb2014-05-26 21:30:20 +05301599
1600 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301601 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1602 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_IFACE) ||
1603 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301604 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
1605 pWifiIfaceStat->beaconRx) ||
1606 nla_put_u32(vendor_event,
1607 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
1608 pWifiIfaceStat->mgmtRx) ||
1609 nla_put_u32(vendor_event,
1610 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
1611 pWifiIfaceStat->mgmtActionRx) ||
1612 nla_put_u32(vendor_event,
1613 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
1614 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301615 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301616 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
1617 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301618 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301619 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
1620 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301621 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301622 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
1623 pWifiIfaceStat->rssiAck))
1624 {
1625 hddLog(VOS_TRACE_LEVEL_ERROR,
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05301626 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1627 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301628 return FALSE;
1629 }
1630
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05301631#ifdef FEATURE_EXT_LL_STAT
1632 /*
1633 * Ensure when EXT_LL_STAT is supported by both host and fwr,
1634 * then host should send Leaky AP stats to upper layer,
1635 * otherwise no need to send these stats.
1636 */
1637 if(sme_IsFeatureSupportedByFW(EXT_LL_STAT) &&
1638 sme_IsFeatureSupportedByDriver(EXT_LL_STAT)
1639 )
1640 {
1641 hddLog(VOS_TRACE_LEVEL_INFO,
1642 FL("EXT_LL_STAT is supported by fwr and host %u %u %u %llu"),
1643 pWifiIfaceStat->leakyApStat.is_leaky_ap,
1644 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked,
1645 pWifiIfaceStat->leakyApStat.rx_leak_window,
1646 pWifiIfaceStat->leakyApStat.avg_bcn_spread);
1647 if (nla_put_u32(vendor_event,
1648 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_DETECTED,
1649 pWifiIfaceStat->leakyApStat.is_leaky_ap) ||
1650 nla_put_u32(vendor_event,
1651 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_AVG_NUM_FRAMES_LEAKED,
1652 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked) ||
1653 nla_put_u32(vendor_event,
1654 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_GUARD_TIME,
1655 pWifiIfaceStat->leakyApStat.rx_leak_window) ||
1656 nla_put_u64(vendor_event,
1657 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_AVERAGE_TSF_OFFSET,
1658 pWifiIfaceStat->leakyApStat.avg_bcn_spread))
1659 {
1660 hddLog(VOS_TRACE_LEVEL_ERROR,
1661 FL("EXT_LL_STAT put fail"));
1662 vos_mem_free(pWifiIfaceStatTL);
1663 return FALSE;
1664 }
1665 }
1666#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +05301667 wmmInfo = nla_nest_start(vendor_event,
1668 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301669 if(!wmmInfo)
1670 {
1671 vos_mem_free(pWifiIfaceStatTL);
1672 return FALSE;
1673 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301674 for (i = 0; i < WIFI_AC_MAX; i++)
1675 {
1676 struct nlattr *wmmStats;
1677 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301678 if(!wmmStats)
1679 {
1680 vos_mem_free(pWifiIfaceStatTL);
1681 return FALSE;
1682 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301683 if (FALSE == put_wifi_wmm_ac_stat(
1684 &pWifiIfaceStat->AccessclassStats[i],
1685 vendor_event))
1686 {
1687 hddLog(VOS_TRACE_LEVEL_ERROR,
1688 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05301689 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301690 return FALSE;
1691 }
1692
1693 nla_nest_end(vendor_event, wmmStats);
1694 }
1695 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +05301696 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301697 return TRUE;
1698}
1699
1700static tSirWifiInterfaceMode
1701 hdd_map_device_to_ll_iface_mode ( int deviceMode )
1702{
1703 switch (deviceMode)
1704 {
1705 case WLAN_HDD_INFRA_STATION:
1706 return WIFI_INTERFACE_STA;
1707 case WLAN_HDD_SOFTAP:
1708 return WIFI_INTERFACE_SOFTAP;
1709 case WLAN_HDD_P2P_CLIENT:
1710 return WIFI_INTERFACE_P2P_CLIENT;
1711 case WLAN_HDD_P2P_GO:
1712 return WIFI_INTERFACE_P2P_GO;
1713 case WLAN_HDD_IBSS:
1714 return WIFI_INTERFACE_IBSS;
1715 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05301716 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301717 }
1718}
1719
1720static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
1721 tpSirWifiInterfaceInfo pInfo)
1722{
1723 v_U8_t *staMac = NULL;
1724 hdd_station_ctx_t *pHddStaCtx;
1725 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1726 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
1727
1728 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
1729
1730 vos_mem_copy(pInfo->macAddr,
1731 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1732
1733 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1734 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
1735 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
1736 {
1737 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1738 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
1739 {
1740 pInfo->state = WIFI_DISCONNECTED;
1741 }
1742 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
1743 {
1744 hddLog(VOS_TRACE_LEVEL_ERROR,
1745 "%s: Session ID %d, Connection is in progress", __func__,
1746 pAdapter->sessionId);
1747 pInfo->state = WIFI_ASSOCIATING;
1748 }
1749 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1750 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
1751 {
1752 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
1753 hddLog(VOS_TRACE_LEVEL_ERROR,
1754 "%s: client " MAC_ADDRESS_STR
1755 " is in the middle of WPS/EAPOL exchange.", __func__,
1756 MAC_ADDR_ARRAY(staMac));
1757 pInfo->state = WIFI_AUTHENTICATING;
1758 }
1759 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
1760 {
1761 pInfo->state = WIFI_ASSOCIATED;
1762 vos_mem_copy(pInfo->bssid,
1763 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
1764 vos_mem_copy(pInfo->ssid,
1765 pHddStaCtx->conn_info.SSID.SSID.ssId,
1766 pHddStaCtx->conn_info.SSID.SSID.length);
1767 //NULL Terminate the string.
1768 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
1769 }
1770 }
1771 vos_mem_copy(pInfo->countryStr,
1772 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1773
1774 vos_mem_copy(pInfo->apCountryStr,
1775 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1776
1777 return TRUE;
1778}
1779
1780/*
1781 * hdd_link_layer_process_peer_stats () - This function is called after
1782 * receiving Link Layer Peer statistics from FW.This function converts
1783 * the firmware data to the NL data and sends the same to the kernel/upper
1784 * layers.
1785 */
1786static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
1787 v_VOID_t *pData)
1788{
1789 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301790 tpSirWifiPeerStat pWifiPeerStat;
1791 tpSirWifiPeerInfo pWifiPeerInfo;
1792 struct nlattr *peerInfo;
1793 struct sk_buff *vendor_event;
1794 int status, i;
1795
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301796 ENTER();
1797
Sunil Duttc69bccb2014-05-26 21:30:20 +05301798 status = wlan_hdd_validate_context(pHddCtx);
1799 if (0 != status)
1800 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301801 return;
1802 }
1803
1804 pWifiPeerStat = (tpSirWifiPeerStat) pData;
1805
1806 hddLog(VOS_TRACE_LEVEL_INFO,
1807 "LL_STATS_PEER_ALL : numPeers %u",
1808 pWifiPeerStat->numPeers);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301809 /*
1810 * Allocate a size of 4096 for the peer stats comprising
1811 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1812 * sizeof (tSirWifiRateStat).Each field is put with an
1813 * NL attribute.The size of 4096 is considered assuming
1814 * that number of rates shall not exceed beyond 50 with
1815 * the sizeof (tSirWifiRateStat) being 32.
1816 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301817 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1818 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301819 if (!vendor_event)
1820 {
1821 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301822 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
Sunil Duttc69bccb2014-05-26 21:30:20 +05301823 __func__);
1824 return;
1825 }
1826 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301827 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1828 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_PEER) ||
1829 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301830 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1831 pWifiPeerStat->numPeers))
1832 {
1833 hddLog(VOS_TRACE_LEVEL_ERROR,
1834 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1835 kfree_skb(vendor_event);
1836 return;
1837 }
1838
1839 peerInfo = nla_nest_start(vendor_event,
1840 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301841 if(!peerInfo)
1842 {
1843 hddLog(VOS_TRACE_LEVEL_ERROR,
1844 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
1845 __func__);
1846 kfree_skb(vendor_event);
1847 return;
1848 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301849
1850 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1851 pWifiPeerStat->peerInfo);
1852
1853 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1854 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301855 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301856 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301857
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301858 if(!peers)
1859 {
1860 hddLog(VOS_TRACE_LEVEL_ERROR,
1861 "%s: peer stats put fail",
1862 __func__);
1863 kfree_skb(vendor_event);
1864 return;
1865 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301866 if (FALSE == put_wifi_peer_info(
1867 pWifiPeerInfo, vendor_event))
1868 {
1869 hddLog(VOS_TRACE_LEVEL_ERROR,
1870 "%s: put_wifi_peer_info put fail", __func__);
1871 kfree_skb(vendor_event);
1872 return;
1873 }
1874
1875 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1876 pWifiPeerStat->peerInfo +
1877 (i * sizeof(tSirWifiPeerInfo)) +
1878 (numRate * sizeof (tSirWifiRateStat)));
1879 nla_nest_end(vendor_event, peers);
1880 }
1881 nla_nest_end(vendor_event, peerInfo);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301882 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301883 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301884}
1885
1886/*
1887 * hdd_link_layer_process_iface_stats () - This function is called after
1888 * receiving Link Layer Interface statistics from FW.This function converts
1889 * the firmware data to the NL data and sends the same to the kernel/upper
1890 * layers.
1891 */
1892static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1893 v_VOID_t *pData)
1894{
1895 tpSirWifiIfaceStat pWifiIfaceStat;
1896 struct sk_buff *vendor_event;
1897 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1898 int status;
1899
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301900 ENTER();
1901
Sunil Duttc69bccb2014-05-26 21:30:20 +05301902 status = wlan_hdd_validate_context(pHddCtx);
1903 if (0 != status)
1904 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301905 return;
1906 }
1907 /*
1908 * Allocate a size of 4096 for the interface stats comprising
1909 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1910 * assuming that all these fit with in the limit.Please take
1911 * a call on the limit based on the data requirements on
1912 * interface statistics.
1913 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301914 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1915 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301916 if (!vendor_event)
1917 {
1918 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301919 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301920 return;
1921 }
1922
1923 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1924
Dino Mycle3b9536d2014-07-09 22:05:24 +05301925
1926 if (FALSE == hdd_get_interface_info( pAdapter,
1927 &pWifiIfaceStat->info))
1928 {
1929 hddLog(VOS_TRACE_LEVEL_ERROR,
1930 FL("hdd_get_interface_info get fail") );
1931 kfree_skb(vendor_event);
1932 return;
1933 }
1934
1935 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
1936 vendor_event))
1937 {
1938 hddLog(VOS_TRACE_LEVEL_ERROR,
1939 FL("put_wifi_iface_stats fail") );
1940 kfree_skb(vendor_event);
1941 return;
1942 }
1943
Sunil Duttc69bccb2014-05-26 21:30:20 +05301944 hddLog(VOS_TRACE_LEVEL_INFO,
1945 "WMI_LINK_STATS_IFACE Data");
1946
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301947 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301948
1949 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301950}
1951
1952/*
1953 * hdd_link_layer_process_radio_stats () - This function is called after
1954 * receiving Link Layer Radio statistics from FW.This function converts
1955 * the firmware data to the NL data and sends the same to the kernel/upper
1956 * layers.
1957 */
1958static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1959 v_VOID_t *pData)
1960{
1961 int status, i;
1962 tpSirWifiRadioStat pWifiRadioStat;
1963 tpSirWifiChannelStats pWifiChannelStats;
1964 struct sk_buff *vendor_event;
1965 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1966 struct nlattr *chList;
1967
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301968 ENTER();
1969
Sunil Duttc69bccb2014-05-26 21:30:20 +05301970 status = wlan_hdd_validate_context(pHddCtx);
1971 if (0 != status)
1972 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301973 return;
1974 }
1975 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1976
1977 hddLog(VOS_TRACE_LEVEL_INFO,
1978 "LL_STATS_RADIO"
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05301979 " number of radios = %u"
Sunil Duttc69bccb2014-05-26 21:30:20 +05301980 " radio is %d onTime is %u "
1981 " txTime is %u rxTime is %u "
1982 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301983 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301984 " onTimePnoScan is %u onTimeHs20 is %u "
1985 " numChannels is %u",
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05301986 NUM_RADIOS,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301987 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1988 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1989 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301990 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301991 pWifiRadioStat->onTimeRoamScan,
1992 pWifiRadioStat->onTimePnoScan,
1993 pWifiRadioStat->onTimeHs20,
1994 pWifiRadioStat->numChannels);
1995 /*
1996 * Allocate a size of 4096 for the Radio stats comprising
1997 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1998 * (tSirWifiChannelStats).Each channel data is put with an
1999 * NL attribute.The size of 4096 is considered assuming that
2000 * number of channels shall not exceed beyond 60 with the
2001 * sizeof (tSirWifiChannelStats) being 24 bytes.
2002 */
2003
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302004 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2005 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302006 if (!vendor_event)
2007 {
2008 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302009 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05302010 return;
2011 }
2012
2013 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302014 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2015 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO) ||
2016 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302017 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
2018 pWifiRadioStat->radio) ||
2019 nla_put_u32(vendor_event,
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302020 QCA_WLAN_VENDOR_ATTR_LL_STATS_NUM_RADIOS,
2021 NUM_RADIOS) ||
2022 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302023 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
2024 pWifiRadioStat->onTime) ||
2025 nla_put_u32(vendor_event,
2026 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
2027 pWifiRadioStat->txTime) ||
2028 nla_put_u32(vendor_event,
2029 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
2030 pWifiRadioStat->rxTime) ||
2031 nla_put_u32(vendor_event,
2032 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
2033 pWifiRadioStat->onTimeScan) ||
2034 nla_put_u32(vendor_event,
2035 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
2036 pWifiRadioStat->onTimeNbd) ||
2037 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302038 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
2039 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05302040 nla_put_u32(vendor_event,
2041 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
2042 pWifiRadioStat->onTimeRoamScan) ||
2043 nla_put_u32(vendor_event,
2044 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
2045 pWifiRadioStat->onTimePnoScan) ||
2046 nla_put_u32(vendor_event,
2047 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
2048 pWifiRadioStat->onTimeHs20) ||
2049 nla_put_u32(vendor_event,
2050 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
2051 pWifiRadioStat->numChannels))
2052 {
2053 hddLog(VOS_TRACE_LEVEL_ERROR,
2054 FL("QCA_WLAN_VENDOR_ATTR put fail"));
2055 kfree_skb(vendor_event);
2056 return ;
2057 }
2058
2059 chList = nla_nest_start(vendor_event,
2060 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302061 if(!chList)
2062 {
2063 hddLog(VOS_TRACE_LEVEL_ERROR,
2064 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
2065 __func__);
2066 kfree_skb(vendor_event);
2067 return;
2068 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302069 for (i = 0; i < pWifiRadioStat->numChannels; i++)
2070 {
2071 struct nlattr *chInfo;
2072
2073 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
2074 pWifiRadioStat->channels +
2075 (i * sizeof(tSirWifiChannelStats)));
2076
Sunil Duttc69bccb2014-05-26 21:30:20 +05302077 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302078 if(!chInfo)
2079 {
2080 hddLog(VOS_TRACE_LEVEL_ERROR,
2081 "%s: failed to put chInfo",
2082 __func__);
2083 kfree_skb(vendor_event);
2084 return;
2085 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302086
2087 if (nla_put_u32(vendor_event,
2088 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
2089 pWifiChannelStats->channel.width) ||
2090 nla_put_u32(vendor_event,
2091 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
2092 pWifiChannelStats->channel.centerFreq) ||
2093 nla_put_u32(vendor_event,
2094 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
2095 pWifiChannelStats->channel.centerFreq0) ||
2096 nla_put_u32(vendor_event,
2097 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
2098 pWifiChannelStats->channel.centerFreq1) ||
2099 nla_put_u32(vendor_event,
2100 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
2101 pWifiChannelStats->onTime) ||
2102 nla_put_u32(vendor_event,
2103 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
2104 pWifiChannelStats->ccaBusyTime))
2105 {
2106 hddLog(VOS_TRACE_LEVEL_ERROR,
2107 FL("cfg80211_vendor_event_alloc failed") );
2108 kfree_skb(vendor_event);
2109 return ;
2110 }
2111 nla_nest_end(vendor_event, chInfo);
2112 }
2113 nla_nest_end(vendor_event, chList);
2114
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302115 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302116
2117 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302118 return;
2119}
2120
2121/*
2122 * hdd_link_layer_stats_ind_callback () - This function is called after
2123 * receiving Link Layer indications from FW.This callback converts the firmware
2124 * data to the NL data and send the same to the kernel/upper layers.
2125 */
2126static void hdd_link_layer_stats_ind_callback ( void *pCtx,
2127 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05302128 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302129{
Dino Mycled3d50022014-07-07 12:58:25 +05302130 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
2131 hdd_adapter_t *pAdapter = NULL;
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302132 struct hdd_ll_stats_context *context;
Dino Mycled3d50022014-07-07 12:58:25 +05302133 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302134 int status;
2135
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302136 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302137
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302138 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302139 if (0 != status)
2140 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302141 return;
2142 }
2143
Dino Mycled3d50022014-07-07 12:58:25 +05302144 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
2145 if (NULL == pAdapter)
2146 {
2147 hddLog(VOS_TRACE_LEVEL_ERROR,
2148 FL(" MAC address %pM does not exist with host"),
2149 macAddr);
2150 return;
2151 }
2152
Sunil Duttc69bccb2014-05-26 21:30:20 +05302153 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05302154 "%s: Interface: %s LLStats indType: %d", __func__,
2155 pAdapter->dev->name, indType);
2156
Sunil Duttc69bccb2014-05-26 21:30:20 +05302157 switch (indType)
2158 {
2159 case SIR_HAL_LL_STATS_RESULTS_RSP:
2160 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302161 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302162 "LL_STATS RESP paramID = 0x%x, ifaceId = %u MAC: %pM "
2163 "respId = %u, moreResultToFollow = %u",
2164 linkLayerStatsResults->paramId, linkLayerStatsResults->ifaceId,
2165 macAddr, linkLayerStatsResults->respId,
2166 linkLayerStatsResults->moreResultToFollow);
2167
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302168 spin_lock(&hdd_context_lock);
2169 context = &pHddCtx->ll_stats_context;
2170 /* validate response received from target */
2171 if ((context->request_id != linkLayerStatsResults->respId) ||
2172 !(context->request_bitmap & linkLayerStatsResults->paramId))
2173 {
2174 spin_unlock(&hdd_context_lock);
2175 hddLog(LOGE,
2176 FL("Error : Request id %d response id %d request bitmap 0x%x"
2177 "response bitmap 0x%x"),
2178 context->request_id, linkLayerStatsResults->respId,
2179 context->request_bitmap, linkLayerStatsResults->paramId);
2180 return;
2181 }
2182 spin_unlock(&hdd_context_lock);
2183
Sunil Duttc69bccb2014-05-26 21:30:20 +05302184 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
2185 {
2186 hdd_link_layer_process_radio_stats(pAdapter,
2187 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302188 spin_lock(&hdd_context_lock);
2189 context->request_bitmap &= ~(WMI_LINK_STATS_RADIO);
2190 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302191 }
2192 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
2193 {
2194 hdd_link_layer_process_iface_stats(pAdapter,
2195 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302196 spin_lock(&hdd_context_lock);
2197 context->request_bitmap &= ~(WMI_LINK_STATS_IFACE);
2198 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302199 }
2200 else if ( linkLayerStatsResults->paramId &
2201 WMI_LINK_STATS_ALL_PEER )
2202 {
2203 hdd_link_layer_process_peer_stats(pAdapter,
2204 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302205 spin_lock(&hdd_context_lock);
2206 context->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER);
2207 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302208 } /* WMI_LINK_STATS_ALL_PEER */
2209 else
2210 {
2211 hddLog(VOS_TRACE_LEVEL_ERROR,
2212 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
2213 }
2214
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302215 spin_lock(&hdd_context_lock);
2216 /* complete response event if all requests are completed */
2217 if (0 == context->request_bitmap)
2218 complete(&context->response_event);
2219 spin_unlock(&hdd_context_lock);
2220
Sunil Duttc69bccb2014-05-26 21:30:20 +05302221 break;
2222 }
2223 default:
2224 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
2225 break;
2226 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302227
2228 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302229 return;
2230}
2231
2232const struct
2233nla_policy
2234qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
2235{
2236 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
2237 { .type = NLA_U32 },
2238 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
2239 { .type = NLA_U32 },
2240};
2241
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302242static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
2243 struct wireless_dev *wdev,
2244 const void *data,
2245 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302246{
2247 int status;
2248 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302249 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302250 struct net_device *dev = wdev->netdev;
2251 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2252 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2253
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302254 ENTER();
2255
Sunil Duttc69bccb2014-05-26 21:30:20 +05302256 status = wlan_hdd_validate_context(pHddCtx);
2257 if (0 != status)
2258 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302259 return -EINVAL;
2260 }
2261
2262 if (NULL == pAdapter)
2263 {
2264 hddLog(VOS_TRACE_LEVEL_ERROR,
2265 FL("HDD adapter is Null"));
2266 return -ENODEV;
2267 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302268 /* check the LLStats Capability */
2269 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2270 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2271 {
Anurag Chouhan65ea6dc2016-10-25 19:59:14 +05302272 hddLog(VOS_TRACE_LEVEL_WARN,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302273 FL("Link Layer Statistics not supported by Firmware"));
2274 return -EINVAL;
2275 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302276
2277 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
2278 (struct nlattr *)data,
2279 data_len, qca_wlan_vendor_ll_set_policy))
2280 {
2281 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2282 return -EINVAL;
2283 }
2284 if (!tb_vendor
2285 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
2286 {
2287 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
2288 return -EINVAL;
2289 }
2290 if (!tb_vendor[
2291 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
2292 {
2293 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
2294 return -EINVAL;
2295 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302296 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302297 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302298
Dino Mycledf0a5d92014-07-04 09:41:55 +05302299 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302300 nla_get_u32(
2301 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
2302
Dino Mycledf0a5d92014-07-04 09:41:55 +05302303 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302304 nla_get_u32(
2305 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
2306
Dino Mycled3d50022014-07-07 12:58:25 +05302307 vos_mem_copy(linkLayerStatsSetReq.macAddr,
2308 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302309
2310
2311 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302312 "LL_STATS_SET reqId = %d, MAC = %pM, mpduSizeThreshold = %d "
2313 "Statistics Gathering = %d ",
2314 linkLayerStatsSetReq.reqId, linkLayerStatsSetReq.macAddr,
2315 linkLayerStatsSetReq.mpduSizeThreshold,
2316 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302317
2318 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
2319 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05302320 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302321 {
2322 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2323 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302324 return -EINVAL;
2325
2326 }
Srinivas Dasari98947432014-11-07 19:41:24 +05302327
Sunil Duttc69bccb2014-05-26 21:30:20 +05302328 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302329 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302330 {
2331 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2332 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302333 return -EINVAL;
2334 }
2335
2336 pAdapter->isLinkLayerStatsSet = 1;
2337
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302338 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302339 return 0;
2340}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302341static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
2342 struct wireless_dev *wdev,
2343 const void *data,
2344 int data_len)
2345{
2346 int ret = 0;
2347
2348 vos_ssr_protect(__func__);
2349 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
2350 vos_ssr_unprotect(__func__);
2351
2352 return ret;
2353}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302354
2355const struct
2356nla_policy
2357qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
2358{
2359 /* Unsigned 32bit value provided by the caller issuing the GET stats
2360 * command. When reporting
2361 * the stats results, the driver uses the same value to indicate
2362 * which GET request the results
2363 * correspond to.
2364 */
2365 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
2366
2367 /* Unsigned 32bit value . bit mask to identify what statistics are
2368 requested for retrieval */
2369 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
2370};
2371
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302372static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
2373 struct wireless_dev *wdev,
2374 const void *data,
2375 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302376{
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302377 unsigned long rc;
2378 struct hdd_ll_stats_context *context;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302379 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2380 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302381 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302382 struct net_device *dev = wdev->netdev;
2383 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma10313ba2015-07-29 19:14:39 +05302384 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302385 int status;
2386
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302387 ENTER();
2388
Sunil Duttc69bccb2014-05-26 21:30:20 +05302389 status = wlan_hdd_validate_context(pHddCtx);
2390 if (0 != status)
2391 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302392 return -EINVAL ;
2393 }
2394
2395 if (NULL == pAdapter)
2396 {
2397 hddLog(VOS_TRACE_LEVEL_FATAL,
2398 "%s: HDD adapter is Null", __func__);
2399 return -ENODEV;
2400 }
Mukul Sharma10313ba2015-07-29 19:14:39 +05302401
2402 if (pHddStaCtx == NULL)
2403 {
2404 hddLog(VOS_TRACE_LEVEL_FATAL,
2405 "%s: HddStaCtx is Null", __func__);
2406 return -ENODEV;
2407 }
2408
Dino Mycledf0a5d92014-07-04 09:41:55 +05302409 /* check the LLStats Capability */
2410 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2411 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2412 {
2413 hddLog(VOS_TRACE_LEVEL_ERROR,
2414 FL("Link Layer Statistics not supported by Firmware"));
2415 return -EINVAL;
2416 }
2417
Sunil Duttc69bccb2014-05-26 21:30:20 +05302418
2419 if (!pAdapter->isLinkLayerStatsSet)
2420 {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05302421 hddLog(VOS_TRACE_LEVEL_ERROR,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302422 "%s: isLinkLayerStatsSet : %d",
2423 __func__, pAdapter->isLinkLayerStatsSet);
2424 return -EINVAL;
2425 }
2426
Mukul Sharma10313ba2015-07-29 19:14:39 +05302427 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
2428 {
2429 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2430 "%s: Roaming in progress, so unable to proceed this request", __func__);
2431 return -EBUSY;
2432 }
2433
Sunil Duttc69bccb2014-05-26 21:30:20 +05302434 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
2435 (struct nlattr *)data,
2436 data_len, qca_wlan_vendor_ll_get_policy))
2437 {
2438 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2439 return -EINVAL;
2440 }
2441
2442 if (!tb_vendor
2443 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
2444 {
2445 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
2446 return -EINVAL;
2447 }
2448
2449 if (!tb_vendor
2450 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
2451 {
2452 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
2453 return -EINVAL;
2454 }
2455
Sunil Duttc69bccb2014-05-26 21:30:20 +05302456
Dino Mycledf0a5d92014-07-04 09:41:55 +05302457 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302458 nla_get_u32( tb_vendor[
2459 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05302460 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302461 nla_get_u32( tb_vendor[
2462 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
2463
Dino Mycled3d50022014-07-07 12:58:25 +05302464 vos_mem_copy(linkLayerStatsGetReq.macAddr,
2465 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302466
2467 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302468 "LL_STATS_GET reqId = %d, MAC = %pM, paramIdMask = %d",
2469 linkLayerStatsGetReq.reqId, linkLayerStatsGetReq.macAddr,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302470 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302471
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302472 spin_lock(&hdd_context_lock);
2473 context = &pHddCtx->ll_stats_context;
2474 context->request_id = linkLayerStatsGetReq.reqId;
2475 context->request_bitmap = linkLayerStatsGetReq.paramIdMask;
2476 INIT_COMPLETION(context->response_event);
2477 spin_unlock(&hdd_context_lock);
2478
Sunil Duttc69bccb2014-05-26 21:30:20 +05302479 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302480 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302481 {
2482 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2483 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302484 return -EINVAL;
2485 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302486
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302487 rc = wait_for_completion_timeout(&context->response_event,
2488 msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS));
2489 if (!rc)
2490 {
2491 hddLog(LOGE,
2492 FL("Target response timed out request id %d request bitmap 0x%x"),
2493 context->request_id, context->request_bitmap);
2494 return -ETIMEDOUT;
2495 }
2496
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302497 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302498 return 0;
2499}
2500
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302501static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
2502 struct wireless_dev *wdev,
2503 const void *data,
2504 int data_len)
2505{
2506 int ret = 0;
2507
2508 vos_ssr_protect(__func__);
2509 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
2510 vos_ssr_unprotect(__func__);
2511
2512 return ret;
2513}
2514
Sunil Duttc69bccb2014-05-26 21:30:20 +05302515const struct
2516nla_policy
2517qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
2518{
2519 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
2520 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
2521 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
2522 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
2523};
2524
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302525static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2526 struct wireless_dev *wdev,
2527 const void *data,
2528 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302529{
2530 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2531 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302532 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302533 struct net_device *dev = wdev->netdev;
2534 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2535 u32 statsClearReqMask;
2536 u8 stopReq;
2537 int status;
2538
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302539 ENTER();
2540
Sunil Duttc69bccb2014-05-26 21:30:20 +05302541 status = wlan_hdd_validate_context(pHddCtx);
2542 if (0 != status)
2543 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302544 return -EINVAL;
2545 }
2546
2547 if (NULL == pAdapter)
2548 {
2549 hddLog(VOS_TRACE_LEVEL_FATAL,
2550 "%s: HDD adapter is Null", __func__);
2551 return -ENODEV;
2552 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302553 /* check the LLStats Capability */
2554 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2555 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2556 {
2557 hddLog(VOS_TRACE_LEVEL_ERROR,
2558 FL("Enable LLStats Capability"));
2559 return -EINVAL;
2560 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302561
2562 if (!pAdapter->isLinkLayerStatsSet)
2563 {
2564 hddLog(VOS_TRACE_LEVEL_FATAL,
2565 "%s: isLinkLayerStatsSet : %d",
2566 __func__, pAdapter->isLinkLayerStatsSet);
2567 return -EINVAL;
2568 }
2569
2570 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
2571 (struct nlattr *)data,
2572 data_len, qca_wlan_vendor_ll_clr_policy))
2573 {
2574 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2575 return -EINVAL;
2576 }
2577
2578 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
2579
2580 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
2581 {
2582 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
2583 return -EINVAL;
2584
2585 }
2586
Sunil Duttc69bccb2014-05-26 21:30:20 +05302587
Dino Mycledf0a5d92014-07-04 09:41:55 +05302588 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302589 nla_get_u32(
2590 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
2591
Dino Mycledf0a5d92014-07-04 09:41:55 +05302592 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302593 nla_get_u8(
2594 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
2595
2596 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302597 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302598
Dino Mycled3d50022014-07-07 12:58:25 +05302599 vos_mem_copy(linkLayerStatsClearReq.macAddr,
2600 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302601
2602 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302603 "LL_STATS_CLEAR reqId = %d, MAC = %pM,"
2604 "statsClearReqMask = 0x%X, stopReq = %d",
2605 linkLayerStatsClearReq.reqId,
2606 linkLayerStatsClearReq.macAddr,
2607 linkLayerStatsClearReq.statsClearReqMask,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302608 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302609
2610 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302611 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302612 {
2613 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05302614 hdd_station_ctx_t *pHddStaCtx;
2615
2616 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2617 if (VOS_STATUS_SUCCESS !=
2618 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2619 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
2620 {
2621 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2622 "WLANTL_ClearInterfaceStats Failed", __func__);
2623 return -EINVAL;
2624 }
2625 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
2626 (statsClearReqMask & WIFI_STATS_IFACE)) {
2627 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
2628 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
2629 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
2630 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
2631 }
2632
Sunil Duttc69bccb2014-05-26 21:30:20 +05302633 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
2634 2 * sizeof(u32) +
2635 NLMSG_HDRLEN);
2636
2637 if (temp_skbuff != NULL)
2638 {
2639
2640 if (nla_put_u32(temp_skbuff,
2641 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
2642 statsClearReqMask) ||
2643 nla_put_u32(temp_skbuff,
2644 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
2645 stopReq))
2646 {
2647 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
2648 kfree_skb(temp_skbuff);
2649 return -EINVAL;
2650 }
2651 /* If the ask is to stop the stats collection as part of clear
2652 * (stopReq = 1) , ensure that no further requests of get
2653 * go to the firmware by having isLinkLayerStatsSet set to 0.
2654 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302655 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05302656 * case the firmware is just asked to clear the statistics.
2657 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05302658 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302659 pAdapter->isLinkLayerStatsSet = 0;
2660 return cfg80211_vendor_cmd_reply(temp_skbuff);
2661 }
2662 return -ENOMEM;
2663 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302664
2665 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302666 return -EINVAL;
2667}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302668static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2669 struct wireless_dev *wdev,
2670 const void *data,
2671 int data_len)
2672{
2673 int ret = 0;
2674
2675 vos_ssr_protect(__func__);
2676 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
2677 vos_ssr_unprotect(__func__);
2678
2679 return ret;
2680
2681
2682}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302683#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
2684
Dino Mycle6fb96c12014-06-10 11:52:40 +05302685#ifdef WLAN_FEATURE_EXTSCAN
2686static const struct nla_policy
2687wlan_hdd_extscan_config_policy
2688 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
2689{
2690 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
2691 { .type = NLA_U32 },
2692 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
2693 { .type = NLA_U32 },
2694 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
2695 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
2696 { .type = NLA_U32 },
2697 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
2698 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
2699
2700 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
2701 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
2702 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
2703 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
2704 { .type = NLA_U8 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302705 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] =
2706 { .type = NLA_U32 },
2707 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT] =
2708 { .type = NLA_U32 },
2709 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] =
2710 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302711 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
2712 { .type = NLA_U32 },
2713 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
2714 { .type = NLA_U32 },
2715 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
2716 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302717 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] =
2718 { .type = NLA_U8 },
2719 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302720 { .type = NLA_U8 },
2721 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
2722 { .type = NLA_U8 },
2723 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
2724 { .type = NLA_U8 },
2725
2726 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
2727 { .type = NLA_U32 },
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05302728 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] = {
2729 .type = NLA_UNSPEC,
2730 .len = HDD_MAC_ADDR_LEN},
Dino Mycle6fb96c12014-06-10 11:52:40 +05302731 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
2732 { .type = NLA_S32 },
2733 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
2734 { .type = NLA_S32 },
2735 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
2736 { .type = NLA_U32 },
2737 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
2738 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302739 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] =
2740 { .type = NLA_U32 },
2741 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] =
2742 { .type = NLA_BINARY,
2743 .len = IEEE80211_MAX_SSID_LEN + 1 },
2744 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302745 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302746 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] =
2747 { .type = NLA_U32 },
2748 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] =
2749 { .type = NLA_U8 },
2750 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] =
2751 { .type = NLA_S32 },
2752 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] =
2753 { .type = NLA_S32 },
2754 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] =
2755 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302756};
2757
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302758/**
2759 * wlan_hdd_cfg80211_extscan_get_capabilities_rsp() - response from target
2760 * @ctx: hdd global context
2761 * @data: capabilities data
2762 *
2763 * Return: none
2764 */
2765static void
2766wlan_hdd_cfg80211_extscan_get_capabilities_rsp(void *ctx, void *pMsg)
Dino Mycle6fb96c12014-06-10 11:52:40 +05302767{
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302768 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302769 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302770 tSirEXTScanCapabilitiesEvent *data =
2771 (tSirEXTScanCapabilitiesEvent *) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302772
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302773 ENTER();
2774
2775 if (wlan_hdd_validate_context(pHddCtx))
2776 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302777 return;
2778 }
2779
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302780 if (!pMsg)
2781 {
2782 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2783 return;
2784 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302785
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302786 vos_spin_lock_acquire(&hdd_context_lock);
2787
2788 context = &pHddCtx->ext_scan_context;
2789 /* validate response received from target*/
2790 if (context->request_id != data->requestId)
2791 {
2792 vos_spin_lock_release(&hdd_context_lock);
2793 hddLog(LOGE,
2794 FL("Target response id did not match: request_id %d resposne_id %d"),
2795 context->request_id, data->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302796 return;
2797 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302798 else
2799 {
2800 context->capability_response = *data;
2801 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302802 }
2803
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302804 vos_spin_lock_release(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302805
Dino Mycle6fb96c12014-06-10 11:52:40 +05302806 return;
2807}
2808
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302809/*
2810 * define short names for the global vendor params
2811 * used by wlan_hdd_send_ext_scan_capability()
2812 */
2813#define PARAM_REQUEST_ID \
2814 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
2815#define PARAM_STATUS \
2816 QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS
2817#define MAX_SCAN_CACHE_SIZE \
2818 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE
2819#define MAX_SCAN_BUCKETS \
2820 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS
2821#define MAX_AP_CACHE_PER_SCAN \
2822 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN
2823#define MAX_RSSI_SAMPLE_SIZE \
2824 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE
2825#define MAX_SCAN_RPT_THRHOLD \
2826 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
2827#define MAX_HOTLIST_BSSIDS \
2828 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS
2829#define MAX_BSSID_HISTORY_ENTRIES \
2830 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
2831#define MAX_HOTLIST_SSIDS \
2832 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302833#define MAX_SIGNIFICANT_WIFI_CHANGE_APS \
2834 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302835
2836static int wlan_hdd_send_ext_scan_capability(void *ctx)
2837{
2838 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2839 struct sk_buff *skb = NULL;
2840 int ret;
2841 tSirEXTScanCapabilitiesEvent *data;
2842 tANI_U32 nl_buf_len;
2843
2844 ret = wlan_hdd_validate_context(pHddCtx);
2845 if (0 != ret)
2846 {
2847 return ret;
2848 }
2849
2850 data = &(pHddCtx->ext_scan_context.capability_response);
2851
2852 nl_buf_len = NLMSG_HDRLEN;
2853 nl_buf_len += (sizeof(data->requestId) + NLA_HDRLEN) +
2854 (sizeof(data->status) + NLA_HDRLEN) +
2855 (sizeof(data->scanCacheSize) + NLA_HDRLEN) +
2856 (sizeof(data->scanBuckets) + NLA_HDRLEN) +
2857 (sizeof(data->maxApPerScan) + NLA_HDRLEN) +
2858 (sizeof(data->maxRssiSampleSize) + NLA_HDRLEN) +
2859 (sizeof(data->maxScanReportingThreshold) + NLA_HDRLEN) +
2860 (sizeof(data->maxHotlistAPs) + NLA_HDRLEN) +
2861 (sizeof(data->maxBsidHistoryEntries) + NLA_HDRLEN) +
2862 (sizeof(data->maxHotlistSSIDs) + NLA_HDRLEN);
2863
2864 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, nl_buf_len);
2865
2866 if (!skb)
2867 {
2868 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
2869 return -ENOMEM;
2870 }
2871
2872 hddLog(LOG1, "Req Id (%u) Status (%u)", data->requestId, data->status);
2873 hddLog(LOG1, "Scan cache size (%u) Scan buckets (%u) Max AP per scan (%u)",
2874 data->scanCacheSize, data->scanBuckets, data->maxApPerScan);
2875 hddLog(LOG1, "max_rssi_sample_size (%u) max_scan_reporting_threshold (%u)",
2876 data->maxRssiSampleSize, data->maxScanReportingThreshold);
2877 hddLog(LOG1, "max_hotlist_bssids (%u) max_bssid_history_entries (%u)"
2878 "max_hotlist_ssids (%u)", data->maxHotlistAPs,
2879 data->maxBsidHistoryEntries, data->maxHotlistSSIDs);
2880
2881 if (nla_put_u32(skb, PARAM_REQUEST_ID, data->requestId) ||
2882 nla_put_u32(skb, PARAM_STATUS, data->status) ||
2883 nla_put_u32(skb, MAX_SCAN_CACHE_SIZE, data->scanCacheSize) ||
2884 nla_put_u32(skb, MAX_SCAN_BUCKETS, data->scanBuckets) ||
2885 nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN,
2886 data->maxApPerScan) ||
2887 nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE,
2888 data->maxRssiSampleSize) ||
2889 nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD,
2890 data->maxScanReportingThreshold) ||
2891 nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->maxHotlistAPs) ||
2892 nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES,
2893 data->maxBsidHistoryEntries) ||
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302894 nla_put_u32(skb, MAX_HOTLIST_SSIDS, data->maxHotlistSSIDs) ||
2895 nla_put_u32(skb, MAX_SIGNIFICANT_WIFI_CHANGE_APS, 0))
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302896 {
2897 hddLog(LOGE, FL("nla put fail"));
2898 goto nla_put_failure;
2899 }
2900
2901 cfg80211_vendor_cmd_reply(skb);
2902 return 0;
2903
2904nla_put_failure:
2905 kfree_skb(skb);
2906 return -EINVAL;;
2907}
2908
2909/*
2910 * done with short names for the global vendor params
2911 * used by wlan_hdd_send_ext_scan_capability()
2912 */
2913#undef PARAM_REQUEST_ID
2914#undef PARAM_STATUS
2915#undef MAX_SCAN_CACHE_SIZE
2916#undef MAX_SCAN_BUCKETS
2917#undef MAX_AP_CACHE_PER_SCAN
2918#undef MAX_RSSI_SAMPLE_SIZE
2919#undef MAX_SCAN_RPT_THRHOLD
2920#undef MAX_HOTLIST_BSSIDS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302921#undef MAX_BSSID_HISTORY_ENTRIES
2922#undef MAX_HOTLIST_SSIDS
Dino Mycle6fb96c12014-06-10 11:52:40 +05302923
2924static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
2925{
2926 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
2927 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302928 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302929 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302930
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302931 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302932
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302933 if (wlan_hdd_validate_context(pHddCtx))
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302934 return;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302935
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302936 if (!pMsg)
2937 {
2938 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302939 return;
2940 }
2941
Dino Mycle6fb96c12014-06-10 11:52:40 +05302942 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2943 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2944
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302945 context = &pHddCtx->ext_scan_context;
2946 spin_lock(&hdd_context_lock);
2947 if (context->request_id == pData->requestId) {
2948 context->response_status = pData->status ? -EINVAL : 0;
2949 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302950 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302951 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302952
2953 /*
2954 * Store the Request ID for comparing with the requestID obtained
2955 * in other requests.HDD shall return a failure is the extscan_stop
2956 * request is issued with a different requestId as that of the
2957 * extscan_start request. Also, This requestId shall be used while
2958 * indicating the full scan results to the upper layers.
2959 * The requestId is stored with the assumption that the firmware
2960 * shall return the ext scan start request's requestId in ext scan
2961 * start response.
2962 */
2963 if (pData->status == 0)
2964 pMac->sme.extScanStartReqId = pData->requestId;
2965
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302966 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302967 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302968}
2969
2970
2971static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2972{
2973 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2974 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302975 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302976
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302977 ENTER();
2978
2979 if (wlan_hdd_validate_context(pHddCtx)){
2980 return;
2981 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302982
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302983 if (!pMsg)
2984 {
2985 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302986 return;
2987 }
2988
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302989 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2990 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302991
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302992 context = &pHddCtx->ext_scan_context;
2993 spin_lock(&hdd_context_lock);
2994 if (context->request_id == pData->requestId) {
2995 context->response_status = pData->status ? -EINVAL : 0;
2996 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302997 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302998 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302999
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303000 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303001 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303002}
3003
Dino Mycle6fb96c12014-06-10 11:52:40 +05303004static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
3005 void *pMsg)
3006{
3007 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303008 tpSirEXTScanSetBssidHotListRspParams pData =
3009 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303010 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303011
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303012 ENTER();
3013
3014 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05303015 return;
3016 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303017
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303018 if (!pMsg)
3019 {
3020 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3021 return;
3022 }
3023
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303024 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3025 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303026
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303027 context = &pHddCtx->ext_scan_context;
3028 spin_lock(&hdd_context_lock);
3029 if (context->request_id == pData->requestId) {
3030 context->response_status = pData->status ? -EINVAL : 0;
3031 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303032 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303033 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303034
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303035 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303036 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303037}
3038
3039static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
3040 void *pMsg)
3041{
3042 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303043 tpSirEXTScanResetBssidHotlistRspParams pData =
3044 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303045 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303046
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303047 ENTER();
3048
3049 if (wlan_hdd_validate_context(pHddCtx)) {
3050 return;
3051 }
3052 if (!pMsg)
3053 {
3054 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303055 return;
3056 }
3057
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303058 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3059 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303060
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303061 context = &pHddCtx->ext_scan_context;
3062 spin_lock(&hdd_context_lock);
3063 if (context->request_id == pData->requestId) {
3064 context->response_status = pData->status ? -EINVAL : 0;
3065 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303066 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303067 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303068
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303069 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303070 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303071}
3072
Dino Mycle6fb96c12014-06-10 11:52:40 +05303073static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
3074 void *pMsg)
3075{
3076 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3077 struct sk_buff *skb = NULL;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303078 tANI_U32 i = 0, j, resultsPerEvent, scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303079 tANI_S32 totalResults;
3080 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303081 tpSirWifiScanResult pSirWifiScanResult, head_ptr;
3082 struct hdd_ext_scan_context *context;
3083 bool ignore_cached_results = false;
3084 tExtscanCachedScanResult *result;
3085 struct nlattr *nla_results;
3086 tANI_U16 ieLength= 0;
3087 tANI_U8 *ie = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303088
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303089 ENTER();
3090
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303091 if (wlan_hdd_validate_context(pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303092 return;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303093
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303094 if (!pMsg)
3095 {
3096 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3097 return;
3098 }
3099
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303100 spin_lock(&hdd_context_lock);
3101 context = &pHddCtx->ext_scan_context;
3102 ignore_cached_results = context->ignore_cached_results;
3103 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303104
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303105 if (ignore_cached_results) {
3106 hddLog(LOGE,
3107 FL("Ignore the cached results received after timeout"));
3108 return;
3109 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303110
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303111 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u More Data %u No of scan ids %u",
3112 pData->requestId, pData->moreData, pData->scanResultSize);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303113
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303114 result = (tExtscanCachedScanResult *)&(pData->result);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303115
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303116 for (scan_id_index = 0; scan_id_index < pData->scanResultSize;
3117 scan_id_index++) {
3118 result+= scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303119
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303120 totalResults = result->num_results;
3121 hddLog(VOS_TRACE_LEVEL_INFO, "scan_id %u flags %u Num results %u",
3122 result->scan_id, result->flags, totalResults);
3123 i = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303124
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303125 do{
3126 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
3127 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
3128 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303129
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303130 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
3131 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN);
3132
3133 if (!skb) {
3134 hddLog(VOS_TRACE_LEVEL_ERROR,
3135 FL("cfg80211_vendor_event_alloc failed"));
3136 return;
3137 }
3138
3139 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
3140
3141 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3142 pData->requestId) ||
3143 nla_put_u32(skb,
3144 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3145 resultsPerEvent)) {
3146 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3147 goto fail;
3148 }
3149 if (nla_put_u8(skb,
3150 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3151 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303152 {
3153 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3154 goto fail;
3155 }
3156
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303157 if (nla_put_u32(skb,
3158 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
3159 result->scan_id)) {
3160 hddLog(LOGE, FL("put fail"));
3161 goto fail;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303162 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303163
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303164 nla_results = nla_nest_start(skb,
3165 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_LIST);
3166 if (!nla_results)
3167 goto fail;
3168
3169 if (resultsPerEvent) {
3170 struct nlattr *aps;
3171 struct nlattr *nla_result;
3172
3173 nla_result = nla_nest_start(skb, scan_id_index);
3174 if(!nla_result)
3175 goto fail;
3176
3177 if (nla_put_u32(skb,
3178 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
3179 result->scan_id) ||
3180 nla_put_u32(skb,
3181 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_FLAGS,
3182 result->flags) ||
3183 nla_put_u32(skb,
3184 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3185 totalResults)) {
3186 hddLog(LOGE, FL("put fail"));
3187 goto fail;
3188 }
3189
3190 aps = nla_nest_start(skb,
3191 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3192 if (!aps)
3193 {
3194 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3195 goto fail;
3196 }
3197
3198 head_ptr = (tpSirWifiScanResult) &(result->ap);
3199
3200 for (j = 0; j < resultsPerEvent; j++, i++) {
3201 struct nlattr *ap;
3202 pSirWifiScanResult = head_ptr + i;
3203
3204 /*
Srinivas Dasari91727c12016-03-23 17:59:06 +05303205 * Firmware returns timestamp from extscan_start till
3206 * BSSID was cached (in micro seconds). Add this with
3207 * time gap between system boot up to extscan_start
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303208 * to derive the time since boot when the
3209 * BSSID was cached.
3210 */
Srinivas Dasari91727c12016-03-23 17:59:06 +05303211 pSirWifiScanResult->ts +=
3212 pHddCtx->extscan_start_time_since_boot;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303213 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
3214 "Ssid (%s)"
3215 "Bssid: %pM "
3216 "Channel (%u)"
3217 "Rssi (%d)"
3218 "RTT (%u)"
3219 "RTT_SD (%u)"
3220 "Beacon Period %u"
3221 "Capability 0x%x "
3222 "Ie length %d",
3223 i,
3224 pSirWifiScanResult->ts,
3225 pSirWifiScanResult->ssid,
3226 pSirWifiScanResult->bssid,
3227 pSirWifiScanResult->channel,
3228 pSirWifiScanResult->rssi,
3229 pSirWifiScanResult->rtt,
3230 pSirWifiScanResult->rtt_sd,
3231 pSirWifiScanResult->beaconPeriod,
3232 pSirWifiScanResult->capability,
3233 ieLength);
3234
3235 ap = nla_nest_start(skb, j + 1);
3236 if (!ap)
3237 {
3238 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3239 goto fail;
3240 }
3241
3242 if (nla_put_u64(skb,
3243 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3244 pSirWifiScanResult->ts) )
3245 {
3246 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3247 goto fail;
3248 }
3249 if (nla_put(skb,
3250 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3251 sizeof(pSirWifiScanResult->ssid),
3252 pSirWifiScanResult->ssid) )
3253 {
3254 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3255 goto fail;
3256 }
3257 if (nla_put(skb,
3258 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3259 sizeof(pSirWifiScanResult->bssid),
3260 pSirWifiScanResult->bssid) )
3261 {
3262 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3263 goto fail;
3264 }
3265 if (nla_put_u32(skb,
3266 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3267 pSirWifiScanResult->channel) )
3268 {
3269 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3270 goto fail;
3271 }
3272 if (nla_put_s32(skb,
3273 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
3274 pSirWifiScanResult->rssi) )
3275 {
3276 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3277 goto fail;
3278 }
3279 if (nla_put_u32(skb,
3280 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3281 pSirWifiScanResult->rtt) )
3282 {
3283 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3284 goto fail;
3285 }
3286 if (nla_put_u32(skb,
3287 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3288 pSirWifiScanResult->rtt_sd))
3289 {
3290 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3291 goto fail;
3292 }
3293 if (nla_put_u32(skb,
3294 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3295 pSirWifiScanResult->beaconPeriod))
3296 {
3297 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3298 goto fail;
3299 }
3300 if (nla_put_u32(skb,
3301 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3302 pSirWifiScanResult->capability))
3303 {
3304 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3305 goto fail;
3306 }
3307 if (nla_put_u32(skb,
3308 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
3309 ieLength))
3310 {
3311 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3312 goto fail;
3313 }
3314
3315 if (ieLength)
3316 if (nla_put(skb,
3317 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3318 ieLength, ie)) {
3319 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3320 goto fail;
3321 }
3322
3323 nla_nest_end(skb, ap);
3324 }
3325 nla_nest_end(skb, aps);
3326 nla_nest_end(skb, nla_result);
3327 }
3328
3329 nla_nest_end(skb, nla_results);
3330
3331 cfg80211_vendor_cmd_reply(skb);
3332
3333 } while (totalResults > 0);
3334 }
3335
3336 if (!pData->moreData) {
3337 spin_lock(&hdd_context_lock);
3338 context->response_status = 0;
3339 complete(&context->response_event);
3340 spin_unlock(&hdd_context_lock);
3341 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303342
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303343 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303344 return;
3345fail:
3346 kfree_skb(skb);
3347 return;
3348}
3349
3350static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
3351 void *pMsg)
3352{
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303353 tpSirEXTScanHotlistMatch pData = (tpSirEXTScanHotlistMatch) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303354 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3355 struct sk_buff *skb = NULL;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303356 tANI_U32 i, index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303357
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303358 ENTER();
3359
3360 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303361 hddLog(LOGE,
3362 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303363 return;
3364 }
3365 if (!pMsg)
3366 {
3367 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303368 return;
3369 }
3370
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303371 if (pData->bss_found)
3372 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX;
3373 else
3374 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX;
3375
Dino Mycle6fb96c12014-06-10 11:52:40 +05303376 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303377#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3378 NULL,
3379#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303380 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303381 index, GFP_KERNEL);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303382
3383 if (!skb) {
3384 hddLog(VOS_TRACE_LEVEL_ERROR,
3385 FL("cfg80211_vendor_event_alloc failed"));
3386 return;
3387 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303388
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303389 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3390 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numHotlistBss);
3391 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
3392 hddLog(VOS_TRACE_LEVEL_INFO, "ap_found %u", pData->bss_found);
3393
3394 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303395 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
3396 "Ssid (%s) "
3397 "Bssid (" MAC_ADDRESS_STR ") "
3398 "Channel (%u) "
3399 "Rssi (%d) "
3400 "RTT (%u) "
3401 "RTT_SD (%u) ",
3402 i,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303403 pData->bssHotlist[i].ts,
3404 pData->bssHotlist[i].ssid,
3405 MAC_ADDR_ARRAY(pData->bssHotlist[i].bssid),
3406 pData->bssHotlist[i].channel,
3407 pData->bssHotlist[i].rssi,
3408 pData->bssHotlist[i].rtt,
3409 pData->bssHotlist[i].rtt_sd);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303410 }
3411
3412 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3413 pData->requestId) ||
3414 nla_put_u32(skb,
3415 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303416 pData->numHotlistBss)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303417 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3418 goto fail;
3419 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303420 if (pData->numHotlistBss) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303421 struct nlattr *aps;
3422
3423 aps = nla_nest_start(skb,
3424 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3425 if (!aps)
3426 goto fail;
3427
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303428 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303429 struct nlattr *ap;
3430
3431 ap = nla_nest_start(skb, i + 1);
3432 if (!ap)
3433 goto fail;
3434
3435 if (nla_put_u64(skb,
3436 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303437 pData->bssHotlist[i].ts) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303438 nla_put(skb,
3439 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303440 sizeof(pData->bssHotlist[i].ssid),
3441 pData->bssHotlist[i].ssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303442 nla_put(skb,
3443 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303444 sizeof(pData->bssHotlist[i].bssid),
3445 pData->bssHotlist[i].bssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303446 nla_put_u32(skb,
3447 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303448 pData->bssHotlist[i].channel) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303449 nla_put_s32(skb,
3450 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303451 pData->bssHotlist[i].rssi) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303452 nla_put_u32(skb,
3453 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303454 pData->bssHotlist[i].rtt) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303455 nla_put_u32(skb,
3456 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303457 pData->bssHotlist[i].rtt_sd))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303458 goto fail;
3459
3460 nla_nest_end(skb, ap);
3461 }
3462 nla_nest_end(skb, aps);
3463
3464 if (nla_put_u8(skb,
3465 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3466 pData->moreData))
3467 goto fail;
3468 }
3469
3470 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303471 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303472 return;
3473
3474fail:
3475 kfree_skb(skb);
3476 return;
3477
3478}
Dino Mycle6fb96c12014-06-10 11:52:40 +05303479
3480static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
3481 void *pMsg)
3482{
3483 struct sk_buff *skb;
3484 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3485 tpSirWifiFullScanResultEvent pData =
3486 (tpSirWifiFullScanResultEvent) (pMsg);
3487
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303488 ENTER();
3489
3490 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303491 hddLog(LOGE,
3492 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303493 return;
3494 }
3495 if (!pMsg)
3496 {
3497 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303498 return;
3499 }
3500
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303501 /*
3502 * If the full scan result including IE data exceeds NL 4K size
3503 * limitation, drop that beacon/probe rsp frame.
3504 */
3505 if ((sizeof(*pData) + pData->ieLength) >= EXTSCAN_EVENT_BUF_SIZE) {
3506 hddLog(LOGE, FL("Frame exceeded NL size limilation, drop it!"));
3507 return;
3508 }
3509
Dino Mycle6fb96c12014-06-10 11:52:40 +05303510 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303511#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3512 NULL,
3513#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303514 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3515 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
3516 GFP_KERNEL);
3517
3518 if (!skb) {
3519 hddLog(VOS_TRACE_LEVEL_ERROR,
3520 FL("cfg80211_vendor_event_alloc failed"));
3521 return;
3522 }
3523
Dino Mycle6fb96c12014-06-10 11:52:40 +05303524 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
3525 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
3526 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
3527 "Ssid (%s)"
3528 "Bssid (" MAC_ADDRESS_STR ")"
3529 "Channel (%u)"
3530 "Rssi (%d)"
3531 "RTT (%u)"
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303532 "RTT_SD (%u)"
3533 "Bcn Period %d"
3534 "Capability 0x%X "),
Dino Mycle6fb96c12014-06-10 11:52:40 +05303535 pData->ap.ts,
3536 pData->ap.ssid,
3537 MAC_ADDR_ARRAY(pData->ap.bssid),
3538 pData->ap.channel,
3539 pData->ap.rssi,
3540 pData->ap.rtt,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303541 pData->ap.rtt_sd,
3542 pData->ap.beaconPeriod,
3543 pData->ap.capability);
3544
Dino Mycle6fb96c12014-06-10 11:52:40 +05303545 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
3546 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3547 pData->requestId) ||
3548 nla_put_u64(skb,
3549 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3550 pData->ap.ts) ||
3551 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3552 sizeof(pData->ap.ssid),
3553 pData->ap.ssid) ||
3554 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3555 WNI_CFG_BSSID_LEN,
3556 pData->ap.bssid) ||
3557 nla_put_u32(skb,
3558 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3559 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05303560 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303561 pData->ap.rssi) ||
3562 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3563 pData->ap.rtt) ||
3564 nla_put_u32(skb,
3565 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3566 pData->ap.rtt_sd) ||
3567 nla_put_u16(skb,
3568 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3569 pData->ap.beaconPeriod) ||
3570 nla_put_u16(skb,
3571 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3572 pData->ap.capability) ||
3573 nla_put_u32(skb,
3574 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303575 pData->ieLength) ||
3576 nla_put_u8(skb,
3577 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3578 pData->moreData))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303579 {
3580 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3581 goto nla_put_failure;
3582 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303583
3584 if (pData->ieLength) {
3585 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3586 pData->ieLength,
3587 pData->ie))
3588 {
3589 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3590 goto nla_put_failure;
3591 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303592 }
3593
3594 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303595 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303596 return;
3597
3598nla_put_failure:
3599 kfree_skb(skb);
3600 return;
3601}
3602
3603static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
3604 void *pMsg)
3605{
3606 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3607 struct sk_buff *skb = NULL;
3608 tpSirEXTScanResultsAvailableIndParams pData =
3609 (tpSirEXTScanResultsAvailableIndParams) pMsg;
3610
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303611 ENTER();
3612
3613 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303614 hddLog(LOGE,
3615 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303616 return;
3617 }
3618 if (!pMsg)
3619 {
3620 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303621 return;
3622 }
3623
3624 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303625#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3626 NULL,
3627#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303628 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3629 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
3630 GFP_KERNEL);
3631
3632 if (!skb) {
3633 hddLog(VOS_TRACE_LEVEL_ERROR,
3634 FL("cfg80211_vendor_event_alloc failed"));
3635 return;
3636 }
3637
Dino Mycle6fb96c12014-06-10 11:52:40 +05303638 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3639 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
3640 pData->numResultsAvailable);
3641 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3642 pData->requestId) ||
3643 nla_put_u32(skb,
3644 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3645 pData->numResultsAvailable)) {
3646 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3647 goto nla_put_failure;
3648 }
3649
3650 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303651 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303652 return;
3653
3654nla_put_failure:
3655 kfree_skb(skb);
3656 return;
3657}
3658
3659static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
3660{
3661 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3662 struct sk_buff *skb = NULL;
3663 tpSirEXTScanProgressIndParams pData =
3664 (tpSirEXTScanProgressIndParams) pMsg;
3665
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303666 ENTER();
3667
3668 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303669 hddLog(LOGE,
3670 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303671 return;
3672 }
3673 if (!pMsg)
3674 {
3675 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303676 return;
3677 }
3678
3679 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303680#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3681 NULL,
3682#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303683 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3684 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
3685 GFP_KERNEL);
3686
3687 if (!skb) {
3688 hddLog(VOS_TRACE_LEVEL_ERROR,
3689 FL("cfg80211_vendor_event_alloc failed"));
3690 return;
3691 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303692 hddLog(VOS_TRACE_LEVEL_INFO, FL("Request Id (%u) "), pData->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303693 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
3694 pData->extScanEventType);
3695 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
3696 pData->status);
3697
3698 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
3699 pData->extScanEventType) ||
3700 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05303701 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3702 pData->requestId) ||
3703 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303704 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
3705 pData->status)) {
3706 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3707 goto nla_put_failure;
3708 }
3709
3710 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303711 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303712 return;
3713
3714nla_put_failure:
3715 kfree_skb(skb);
3716 return;
3717}
3718
3719void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
3720 void *pMsg)
3721{
3722 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3723
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303724 ENTER();
3725
Dino Mycle6fb96c12014-06-10 11:52:40 +05303726 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303727 return;
3728 }
3729
3730 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
3731
3732
3733 switch(evType) {
3734 case SIR_HAL_EXTSCAN_START_RSP:
3735 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
3736 break;
3737
3738 case SIR_HAL_EXTSCAN_STOP_RSP:
3739 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
3740 break;
3741 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
3742 /* There is no need to send this response to upper layer
3743 Just log the message */
3744 hddLog(VOS_TRACE_LEVEL_INFO,
3745 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
3746 break;
3747 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
3748 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
3749 break;
3750
3751 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
3752 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
3753 break;
3754
Dino Mycle6fb96c12014-06-10 11:52:40 +05303755 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303756 wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx, pMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303757 break;
3758 case SIR_HAL_EXTSCAN_PROGRESS_IND:
3759 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
3760 break;
3761 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
3762 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
3763 break;
3764 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
3765 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
3766 break;
3767 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
3768 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
3769 break;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303770 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
3771 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
3772 break;
3773 default:
3774 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
3775 break;
3776 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303777 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303778}
3779
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303780static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3781 struct wireless_dev *wdev,
3782 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303783{
Dino Myclee8843b32014-07-04 14:21:45 +05303784 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303785 struct net_device *dev = wdev->netdev;
3786 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3787 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3788 struct nlattr
3789 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3790 eHalStatus status;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303791 struct hdd_ext_scan_context *context;
3792 unsigned long rc;
3793 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303794
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303795 ENTER();
3796
Dino Mycle6fb96c12014-06-10 11:52:40 +05303797 status = wlan_hdd_validate_context(pHddCtx);
3798 if (0 != status)
3799 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303800 return -EINVAL;
3801 }
Dino Myclee8843b32014-07-04 14:21:45 +05303802 /* check the EXTScan Capability */
3803 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303804 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3805 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303806 {
3807 hddLog(VOS_TRACE_LEVEL_ERROR,
3808 FL("EXTScan not enabled/supported by Firmware"));
3809 return -EINVAL;
3810 }
3811
Dino Mycle6fb96c12014-06-10 11:52:40 +05303812 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3813 data, dataLen,
3814 wlan_hdd_extscan_config_policy)) {
3815 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3816 return -EINVAL;
3817 }
3818
3819 /* Parse and fetch request Id */
3820 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3821 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3822 return -EINVAL;
3823 }
3824
Dino Myclee8843b32014-07-04 14:21:45 +05303825 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303826 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303827 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303828
Dino Myclee8843b32014-07-04 14:21:45 +05303829 reqMsg.sessionId = pAdapter->sessionId;
3830 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303831
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303832 vos_spin_lock_acquire(&hdd_context_lock);
3833 context = &pHddCtx->ext_scan_context;
3834 context->request_id = reqMsg.requestId;
3835 INIT_COMPLETION(context->response_event);
3836 vos_spin_lock_release(&hdd_context_lock);
3837
Dino Myclee8843b32014-07-04 14:21:45 +05303838 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303839 if (!HAL_STATUS_SUCCESS(status)) {
3840 hddLog(VOS_TRACE_LEVEL_ERROR,
3841 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303842 return -EINVAL;
3843 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303844
3845 rc = wait_for_completion_timeout(&context->response_event,
3846 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3847 if (!rc) {
3848 hddLog(LOGE, FL("Target response timed out"));
3849 return -ETIMEDOUT;
3850 }
3851
3852 ret = wlan_hdd_send_ext_scan_capability(pHddCtx);
3853 if (ret)
3854 hddLog(LOGE, FL("Failed to send ext scan capability to user space"));
3855
3856 return ret;
3857
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303858 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303859 return 0;
3860}
3861
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303862static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3863 struct wireless_dev *wdev,
3864 const void *data, int dataLen)
3865{
3866 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303867
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303868 vos_ssr_protect(__func__);
3869 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
3870 vos_ssr_unprotect(__func__);
3871
3872 return ret;
3873}
3874
3875static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3876 struct wireless_dev *wdev,
3877 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303878{
Dino Myclee8843b32014-07-04 14:21:45 +05303879 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303880 struct net_device *dev = wdev->netdev;
3881 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3882 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3883 struct nlattr
3884 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3885 eHalStatus status;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303886 struct hdd_ext_scan_context *context;
3887 unsigned long rc;
3888 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303889
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303890 ENTER();
3891
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303892 if (VOS_FTM_MODE == hdd_get_conparam()) {
3893 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3894 return -EINVAL;
3895 }
3896
Dino Mycle6fb96c12014-06-10 11:52:40 +05303897 status = wlan_hdd_validate_context(pHddCtx);
3898 if (0 != status)
3899 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303900 return -EINVAL;
3901 }
Dino Myclee8843b32014-07-04 14:21:45 +05303902 /* check the EXTScan Capability */
3903 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303904 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3905 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303906 {
3907 hddLog(VOS_TRACE_LEVEL_ERROR,
3908 FL("EXTScan not enabled/supported by Firmware"));
3909 return -EINVAL;
3910 }
3911
Dino Mycle6fb96c12014-06-10 11:52:40 +05303912 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3913 data, dataLen,
3914 wlan_hdd_extscan_config_policy)) {
3915 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3916 return -EINVAL;
3917 }
3918 /* Parse and fetch request Id */
3919 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3920 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3921 return -EINVAL;
3922 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303923
Dino Myclee8843b32014-07-04 14:21:45 +05303924 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303925 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3926
Dino Myclee8843b32014-07-04 14:21:45 +05303927 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303928
Dino Myclee8843b32014-07-04 14:21:45 +05303929 reqMsg.sessionId = pAdapter->sessionId;
3930 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303931
3932 /* Parse and fetch flush parameter */
3933 if (!tb
3934 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3935 {
3936 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3937 goto failed;
3938 }
Dino Myclee8843b32014-07-04 14:21:45 +05303939 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303940 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3941
Dino Myclee8843b32014-07-04 14:21:45 +05303942 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303943
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303944 spin_lock(&hdd_context_lock);
3945 context = &pHddCtx->ext_scan_context;
3946 context->request_id = reqMsg.requestId;
3947 context->ignore_cached_results = false;
3948 INIT_COMPLETION(context->response_event);
3949 spin_unlock(&hdd_context_lock);
3950
Dino Myclee8843b32014-07-04 14:21:45 +05303951 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303952 if (!HAL_STATUS_SUCCESS(status)) {
3953 hddLog(VOS_TRACE_LEVEL_ERROR,
3954 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303955 return -EINVAL;
3956 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303957
3958 rc = wait_for_completion_timeout(&context->response_event,
3959 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3960 if (!rc) {
3961 hddLog(LOGE, FL("Target response timed out"));
3962 retval = -ETIMEDOUT;
3963 spin_lock(&hdd_context_lock);
3964 context->ignore_cached_results = true;
3965 spin_unlock(&hdd_context_lock);
3966 } else {
3967 spin_lock(&hdd_context_lock);
3968 retval = context->response_status;
3969 spin_unlock(&hdd_context_lock);
3970 }
3971
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303972 EXIT();
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303973 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303974
3975failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303976 return -EINVAL;
3977}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303978static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3979 struct wireless_dev *wdev,
3980 const void *data, int dataLen)
3981{
3982 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303983
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303984 vos_ssr_protect(__func__);
3985 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
3986 vos_ssr_unprotect(__func__);
3987
3988 return ret;
3989}
3990
3991static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303992 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05303993 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303994{
3995 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3996 struct net_device *dev = wdev->netdev;
3997 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3998 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3999 struct nlattr
4000 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4001 struct nlattr
4002 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4003 struct nlattr *apTh;
4004 eHalStatus status;
4005 tANI_U8 i = 0;
4006 int rem;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304007 struct hdd_ext_scan_context *context;
4008 tANI_U32 request_id;
4009 unsigned long rc;
4010 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304011
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304012 ENTER();
4013
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304014 if (VOS_FTM_MODE == hdd_get_conparam()) {
4015 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4016 return -EINVAL;
4017 }
4018
Dino Mycle6fb96c12014-06-10 11:52:40 +05304019 status = wlan_hdd_validate_context(pHddCtx);
4020 if (0 != status)
4021 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304022 return -EINVAL;
4023 }
Dino Myclee8843b32014-07-04 14:21:45 +05304024 /* check the EXTScan Capability */
4025 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304026 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4027 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304028 {
4029 hddLog(VOS_TRACE_LEVEL_ERROR,
4030 FL("EXTScan not enabled/supported by Firmware"));
4031 return -EINVAL;
4032 }
4033
Dino Mycle6fb96c12014-06-10 11:52:40 +05304034 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4035 data, dataLen,
4036 wlan_hdd_extscan_config_policy)) {
4037 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4038 return -EINVAL;
4039 }
4040
4041 /* Parse and fetch request Id */
4042 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4043 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4044 return -EINVAL;
4045 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304046 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
4047 vos_mem_malloc(sizeof(*pReqMsg));
4048 if (!pReqMsg) {
4049 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4050 return -ENOMEM;
4051 }
4052
Dino Myclee8843b32014-07-04 14:21:45 +05304053
Dino Mycle6fb96c12014-06-10 11:52:40 +05304054 pReqMsg->requestId = nla_get_u32(
4055 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4056 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4057
4058 /* Parse and fetch number of APs */
4059 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
4060 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
4061 goto fail;
4062 }
4063
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304064 /* Parse and fetch lost ap sample size */
4065 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]) {
4066 hddLog(LOGE, FL("attr lost ap sample size failed"));
4067 goto fail;
4068 }
4069
4070 pReqMsg->lostBssidSampleSize = nla_get_u32(
4071 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]);
4072 hddLog(LOG1, FL("Lost ap sample size %d"), pReqMsg->lostBssidSampleSize);
4073
Dino Mycle6fb96c12014-06-10 11:52:40 +05304074 pReqMsg->sessionId = pAdapter->sessionId;
4075 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4076
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304077 pReqMsg->numBssid = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304078 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304079 if (pReqMsg->numBssid > WLAN_EXTSCAN_MAX_HOTLIST_APS) {
4080 hddLog(LOGE, FL("Number of AP: %u exceeds max: %u"),
4081 pReqMsg->numBssid, WLAN_EXTSCAN_MAX_HOTLIST_APS);
4082 goto fail;
4083 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304084 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numBssid);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304085
4086 nla_for_each_nested(apTh,
4087 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304088 if (i == pReqMsg->numBssid) {
4089 hddLog(LOGW, FL("Ignoring excess AP"));
4090 break;
4091 }
4092
Dino Mycle6fb96c12014-06-10 11:52:40 +05304093 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4094 nla_data(apTh), nla_len(apTh),
4095 NULL)) {
4096 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
4097 goto fail;
4098 }
4099
4100 /* Parse and fetch MAC address */
4101 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
4102 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
4103 goto fail;
4104 }
4105 memcpy(pReqMsg->ap[i].bssid, nla_data(
4106 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
4107 sizeof(tSirMacAddr));
4108 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
4109
4110 /* Parse and fetch low RSSI */
4111 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
4112 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
4113 goto fail;
4114 }
4115 pReqMsg->ap[i].low = nla_get_s32(
4116 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
4117 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
4118
4119 /* Parse and fetch high RSSI */
4120 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
4121 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
4122 goto fail;
4123 }
4124 pReqMsg->ap[i].high = nla_get_s32(
4125 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
4126 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
4127 pReqMsg->ap[i].high);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304128 i++;
4129 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304130
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304131 if (i < pReqMsg->numBssid) {
4132 hddLog(LOGW, FL("Number of AP %u less than expected %u"),
4133 i, pReqMsg->numBssid);
4134 pReqMsg->numBssid = i;
4135 }
4136
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304137 context = &pHddCtx->ext_scan_context;
4138 spin_lock(&hdd_context_lock);
4139 INIT_COMPLETION(context->response_event);
4140 context->request_id = request_id = pReqMsg->requestId;
4141 spin_unlock(&hdd_context_lock);
4142
Dino Mycle6fb96c12014-06-10 11:52:40 +05304143 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
4144 if (!HAL_STATUS_SUCCESS(status)) {
4145 hddLog(VOS_TRACE_LEVEL_ERROR,
4146 FL("sme_SetBssHotlist failed(err=%d)"), status);
4147 vos_mem_free(pReqMsg);
4148 return -EINVAL;
4149 }
4150
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304151 /* request was sent -- wait for the response */
4152 rc = wait_for_completion_timeout(&context->response_event,
4153 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4154
4155 if (!rc) {
4156 hddLog(LOGE, FL("sme_SetBssHotlist timed out"));
4157 retval = -ETIMEDOUT;
4158 } else {
4159 spin_lock(&hdd_context_lock);
4160 if (context->request_id == request_id)
4161 retval = context->response_status;
4162 else
4163 retval = -EINVAL;
4164 spin_unlock(&hdd_context_lock);
4165 }
4166
Dino Myclee8843b32014-07-04 14:21:45 +05304167 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304168 EXIT();
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304169 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304170
4171fail:
4172 vos_mem_free(pReqMsg);
4173 return -EINVAL;
4174}
4175
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304176static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
4177 struct wireless_dev *wdev,
4178 const void *data, int dataLen)
4179{
4180 int ret = 0;
4181
4182 vos_ssr_protect(__func__);
4183 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
4184 dataLen);
4185 vos_ssr_unprotect(__func__);
4186
4187 return ret;
4188}
4189
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304190static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304191 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304192 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304193{
Agrawal Ashish16abf782016-08-18 22:42:59 +05304194 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4195 struct net_device *dev = wdev->netdev;
4196 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4197 uint32_t chan_list[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4198 uint8_t num_channels = 0;
4199 uint8_t num_chan_new = 0;
4200 uint8_t buf[256] = {0};
Dino Mycle6fb96c12014-06-10 11:52:40 +05304201 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304202 tANI_U32 requestId, maxChannels;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304203 tWifiBand wifiBand;
4204 eHalStatus status;
4205 struct sk_buff *replySkb;
Agrawal Ashish16abf782016-08-18 22:42:59 +05304206 tANI_U8 i,j,k;
4207 int ret,len = 0;;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304208
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304209 ENTER();
4210
Dino Mycle6fb96c12014-06-10 11:52:40 +05304211 status = wlan_hdd_validate_context(pHddCtx);
4212 if (0 != status)
4213 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304214 return -EINVAL;
4215 }
Dino Myclee8843b32014-07-04 14:21:45 +05304216
Dino Mycle6fb96c12014-06-10 11:52:40 +05304217 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4218 data, dataLen,
4219 wlan_hdd_extscan_config_policy)) {
4220 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4221 return -EINVAL;
4222 }
4223
4224 /* Parse and fetch request Id */
4225 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4226 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4227 return -EINVAL;
4228 }
4229 requestId = nla_get_u32(
4230 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4231 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
4232
4233 /* Parse and fetch wifi band */
4234 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
4235 {
4236 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4237 return -EINVAL;
4238 }
4239 wifiBand = nla_get_u32(
4240 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
4241 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
4242
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304243 /* Parse and fetch max channels */
4244 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
4245 {
4246 hddLog(LOGE, FL("attr max channels failed"));
4247 return -EINVAL;
4248 }
4249 maxChannels = nla_get_u32(
4250 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
4251 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);
4252
Dino Mycle6fb96c12014-06-10 11:52:40 +05304253 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
Agrawal Ashish16abf782016-08-18 22:42:59 +05304254 wifiBand, chan_list,
4255 &num_channels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304256 if (eHAL_STATUS_SUCCESS != status) {
4257 hddLog(VOS_TRACE_LEVEL_ERROR,
4258 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
4259 return -EINVAL;
4260 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304261
Agrawal Ashish16abf782016-08-18 22:42:59 +05304262 num_channels = VOS_MIN(num_channels, maxChannels);
4263 num_chan_new = num_channels;
4264 /* remove the indoor only channels if iface is SAP */
4265 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
4266 {
4267 num_chan_new = 0;
4268 for (i = 0; i < num_channels; i++)
4269 for (j = 0; j < IEEE80211_NUM_BANDS; j++) {
4270 if (wiphy->bands[j] == NULL)
4271 continue;
4272 for (k = 0; k < wiphy->bands[j]->n_channels; k++) {
4273 if ((chan_list[i] ==
4274 wiphy->bands[j]->channels[k].center_freq) &&
4275 (!(wiphy->bands[j]->channels[k].flags &
4276 IEEE80211_CHAN_INDOOR_ONLY))) {
4277 chan_list[num_chan_new] = chan_list[i];
4278 num_chan_new++;
4279 }
4280 }
4281 }
4282 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304283
Agrawal Ashish16abf782016-08-18 22:42:59 +05304284 hddLog(LOG1, FL("Number of channels: %d"), num_chan_new);
4285 for (i = 0; i < num_chan_new; i++)
4286 len += scnprintf(buf + len, sizeof(buf) - len, "%u ", chan_list[i]);
4287 hddLog(LOG1, "Channels: %s", buf);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304288
4289 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
Agrawal Ashish16abf782016-08-18 22:42:59 +05304290 sizeof(u32) * num_chan_new +
Dino Mycle6fb96c12014-06-10 11:52:40 +05304291 NLMSG_HDRLEN);
4292
4293 if (!replySkb) {
4294 hddLog(VOS_TRACE_LEVEL_ERROR,
4295 FL("valid channels: buffer alloc fail"));
4296 return -EINVAL;
4297 }
4298 if (nla_put_u32(replySkb,
4299 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304300 num_chan_new) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05304301 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304302 sizeof(u32) * num_chan_new, chan_list)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304303
4304 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4305 kfree_skb(replySkb);
4306 return -EINVAL;
4307 }
4308
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304309 ret = cfg80211_vendor_cmd_reply(replySkb);
4310
4311 EXIT();
4312 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304313}
4314
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304315static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
4316 struct wireless_dev *wdev,
4317 const void *data, int dataLen)
4318{
4319 int ret = 0;
4320
4321 vos_ssr_protect(__func__);
4322 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
4323 dataLen);
4324 vos_ssr_unprotect(__func__);
4325
4326 return ret;
4327}
4328
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304329static int hdd_extscan_start_fill_bucket_channel_spec(
4330 hdd_context_t *pHddCtx,
4331 tpSirEXTScanStartReqParams pReqMsg,
4332 struct nlattr **tb)
4333{
4334 struct nlattr *bucket[
4335 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4336 struct nlattr *channel[
4337 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4338 struct nlattr *buckets;
4339 struct nlattr *channels;
4340 int rem1, rem2;
4341 eHalStatus status;
4342 tANI_U8 bktIndex, j, numChannels;
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304343 uint32_t expected_buckets;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304344 tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4345 tANI_U32 passive_max_chn_time, active_max_chn_time;
4346
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304347 expected_buckets = pReqMsg->numBuckets;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304348 bktIndex = 0;
4349
4350 nla_for_each_nested(buckets,
4351 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304352 if (bktIndex >= expected_buckets) {
4353 hddLog(LOGW, FL("ignoring excess buckets"));
4354 break;
4355 }
4356
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304357 if (nla_parse(bucket,
Ashish Kumar Dhanotiya9c93f562017-06-20 12:13:33 +05304358 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4359 nla_data(buckets), nla_len(buckets),
4360 wlan_hdd_extscan_config_policy)) {
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304361 hddLog(LOGE, FL("nla_parse failed"));
4362 return -EINVAL;
4363 }
4364
4365 /* Parse and fetch bucket spec */
4366 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4367 hddLog(LOGE, FL("attr bucket index failed"));
4368 return -EINVAL;
4369 }
4370 pReqMsg->buckets[bktIndex].bucket = nla_get_u8(
4371 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4372 hddLog(LOG1, FL("Bucket spec Index %d"),
4373 pReqMsg->buckets[bktIndex].bucket);
4374
4375 /* Parse and fetch wifi band */
4376 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4377 hddLog(LOGE, FL("attr wifi band failed"));
4378 return -EINVAL;
4379 }
4380 pReqMsg->buckets[bktIndex].band = nla_get_u8(
4381 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4382 hddLog(LOG1, FL("Wifi band %d"),
4383 pReqMsg->buckets[bktIndex].band);
4384
4385 /* Parse and fetch period */
4386 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4387 hddLog(LOGE, FL("attr period failed"));
4388 return -EINVAL;
4389 }
4390 pReqMsg->buckets[bktIndex].period = nla_get_u32(
4391 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4392 hddLog(LOG1, FL("period %d"),
4393 pReqMsg->buckets[bktIndex].period);
4394
4395 /* Parse and fetch report events */
4396 if (!bucket[
4397 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4398 hddLog(LOGE, FL("attr report events failed"));
4399 return -EINVAL;
4400 }
4401 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
4402 bucket[
4403 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4404 hddLog(LOG1, FL("report events %d"),
4405 pReqMsg->buckets[bktIndex].reportEvents);
4406
4407 /* Parse and fetch max period */
4408 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
4409 hddLog(LOGE, FL("attr max period failed"));
4410 return -EINVAL;
4411 }
4412 pReqMsg->buckets[bktIndex].max_period = nla_get_u32(
4413 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);
4414 hddLog(LOG1, FL("max period %u"),
4415 pReqMsg->buckets[bktIndex].max_period);
4416
4417 /* Parse and fetch exponent */
4418 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
4419 hddLog(LOGE, FL("attr exponent failed"));
4420 return -EINVAL;
4421 }
4422 pReqMsg->buckets[bktIndex].exponent = nla_get_u32(
4423 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
4424 hddLog(LOG1, FL("exponent %u"),
4425 pReqMsg->buckets[bktIndex].exponent);
4426
4427 /* Parse and fetch step count */
4428 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
4429 hddLog(LOGE, FL("attr step count failed"));
4430 return -EINVAL;
4431 }
4432 pReqMsg->buckets[bktIndex].step_count = nla_get_u32(
4433 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
4434 hddLog(LOG1, FL("Step count %u"),
4435 pReqMsg->buckets[bktIndex].step_count);
4436
4437 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time);
4438 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time);
4439
4440 /* Framework shall pass the channel list if the input WiFi band is
4441 * WIFI_BAND_UNSPECIFIED.
4442 * If the input WiFi band is specified (any value other than
4443 * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
4444 */
4445 if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) {
4446 numChannels = 0;
4447 hddLog(LOG1, "WiFi band is specified, driver to fill channel list");
4448 status = sme_GetValidChannelsByBand(pHddCtx->hHal,
4449 pReqMsg->buckets[bktIndex].band,
4450 chanList, &numChannels);
4451 if (!HAL_STATUS_SUCCESS(status)) {
4452 hddLog(LOGE,
4453 FL("sme_GetValidChannelsByBand failed (err=%d)"),
4454 status);
4455 return -EINVAL;
4456 }
4457
4458 pReqMsg->buckets[bktIndex].numChannels =
4459 VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS);
4460 hddLog(LOG1, FL("Num channels %d"),
4461 pReqMsg->buckets[bktIndex].numChannels);
4462
4463 for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels;
4464 j++) {
4465 pReqMsg->buckets[bktIndex].channels[j].channel =
4466 chanList[j];
4467 pReqMsg->buckets[bktIndex].channels[j].
4468 chnlClass = 0;
4469 if (CSR_IS_CHANNEL_DFS(
4470 vos_freq_to_chan(chanList[j]))) {
4471 pReqMsg->buckets[bktIndex].channels[j].
4472 passive = 1;
4473 pReqMsg->buckets[bktIndex].channels[j].
4474 dwellTimeMs = passive_max_chn_time;
4475 } else {
4476 pReqMsg->buckets[bktIndex].channels[j].
4477 passive = 0;
4478 pReqMsg->buckets[bktIndex].channels[j].
4479 dwellTimeMs = active_max_chn_time;
4480 }
4481
4482 hddLog(LOG1,
4483 "Channel %u Passive %u Dwell time %u ms",
4484 pReqMsg->buckets[bktIndex].channels[j].channel,
4485 pReqMsg->buckets[bktIndex].channels[j].passive,
4486 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4487 }
4488
4489 bktIndex++;
4490 continue;
4491 }
4492
4493 /* Parse and fetch number of channels */
4494 if (!bucket[
4495 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
4496 hddLog(LOGE, FL("attr num channels failed"));
4497 return -EINVAL;
4498 }
4499
4500 pReqMsg->buckets[bktIndex].numChannels =
4501 nla_get_u32(bucket[
4502 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
4503 hddLog(LOG1, FL("num channels %d"),
4504 pReqMsg->buckets[bktIndex].numChannels);
4505
4506 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
4507 hddLog(LOGE, FL("attr channel spec failed"));
4508 return -EINVAL;
4509 }
4510
4511 j = 0;
4512 nla_for_each_nested(channels,
4513 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
4514 if (nla_parse(channel,
4515 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4516 nla_data(channels), nla_len(channels),
4517 wlan_hdd_extscan_config_policy)) {
4518 hddLog(LOGE, FL("nla_parse failed"));
4519 return -EINVAL;
4520 }
4521
4522 /* Parse and fetch channel */
4523 if (!channel[
4524 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
4525 hddLog(LOGE, FL("attr channel failed"));
4526 return -EINVAL;
4527 }
4528 pReqMsg->buckets[bktIndex].channels[j].channel =
4529 nla_get_u32(channel[
4530 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
4531 hddLog(LOG1, FL("channel %u"),
4532 pReqMsg->buckets[bktIndex].channels[j].channel);
4533
4534 /* Parse and fetch dwell time */
4535 if (!channel[
4536 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
4537 hddLog(LOGE, FL("attr dwelltime failed"));
4538 return -EINVAL;
4539 }
4540 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
4541 nla_get_u32(channel[
4542 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
4543
4544 hddLog(LOG1, FL("Dwell time (%u ms)"),
4545 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4546
4547
4548 /* Parse and fetch channel spec passive */
4549 if (!channel[
4550 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
4551 hddLog(LOGE,
4552 FL("attr channel spec passive failed"));
4553 return -EINVAL;
4554 }
4555 pReqMsg->buckets[bktIndex].channels[j].passive =
4556 nla_get_u8(channel[
4557 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
4558 hddLog(LOG1, FL("Chnl spec passive %u"),
4559 pReqMsg->buckets[bktIndex].channels[j].passive);
4560
4561 j++;
4562 }
4563
4564 bktIndex++;
4565 }
4566
4567 return 0;
4568}
4569
4570
4571/*
4572 * define short names for the global vendor params
4573 * used by wlan_hdd_cfg80211_extscan_start()
4574 */
4575#define PARAM_MAX \
4576QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
4577#define PARAM_REQUEST_ID \
4578QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
4579#define PARAM_BASE_PERIOD \
4580QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
4581#define PARAM_MAX_AP_PER_SCAN \
4582QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
4583#define PARAM_RPT_THRHLD_PERCENT \
4584QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
4585#define PARAM_RPT_THRHLD_NUM_SCANS \
4586QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
4587#define PARAM_NUM_BUCKETS \
4588QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
4589
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304590static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304591 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304592 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304593{
Dino Myclee8843b32014-07-04 14:21:45 +05304594 tpSirEXTScanStartReqParams pReqMsg = NULL;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304595 struct net_device *dev = wdev->netdev;
4596 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4597 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4598 struct nlattr *tb[PARAM_MAX + 1];
4599 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304600 eHalStatus status;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304601 tANI_U32 request_id;
4602 struct hdd_ext_scan_context *context;
4603 unsigned long rc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304604
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304605 ENTER();
4606
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304607 if (VOS_FTM_MODE == hdd_get_conparam()) {
4608 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4609 return -EINVAL;
4610 }
4611
Dino Mycle6fb96c12014-06-10 11:52:40 +05304612 status = wlan_hdd_validate_context(pHddCtx);
4613 if (0 != status)
4614 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304615 return -EINVAL;
4616 }
Dino Myclee8843b32014-07-04 14:21:45 +05304617 /* check the EXTScan Capability */
4618 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304619 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4620 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304621 {
4622 hddLog(VOS_TRACE_LEVEL_ERROR,
4623 FL("EXTScan not enabled/supported by Firmware"));
4624 return -EINVAL;
4625 }
4626
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304627 if (nla_parse(tb, PARAM_MAX,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304628 data, dataLen,
4629 wlan_hdd_extscan_config_policy)) {
4630 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4631 return -EINVAL;
4632 }
4633
4634 /* Parse and fetch request Id */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304635 if (!tb[PARAM_REQUEST_ID]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304636 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4637 return -EINVAL;
4638 }
4639
Dino Myclee8843b32014-07-04 14:21:45 +05304640 pReqMsg = (tpSirEXTScanStartReqParams)
4641 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304642 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05304643 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4644 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304645 }
4646
4647 pReqMsg->requestId = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304648 tb[PARAM_REQUEST_ID]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304649 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4650
4651 pReqMsg->sessionId = pAdapter->sessionId;
4652 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4653
4654 /* Parse and fetch base period */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304655 if (!tb[PARAM_BASE_PERIOD]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304656 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
4657 goto fail;
4658 }
4659 pReqMsg->basePeriod = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304660 tb[PARAM_BASE_PERIOD]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304661 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
4662 pReqMsg->basePeriod);
4663
4664 /* Parse and fetch max AP per scan */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304665 if (!tb[PARAM_MAX_AP_PER_SCAN]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304666 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
4667 goto fail;
4668 }
4669 pReqMsg->maxAPperScan = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304670 tb[PARAM_MAX_AP_PER_SCAN]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304671 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
4672 pReqMsg->maxAPperScan);
4673
4674 /* Parse and fetch report threshold */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304675 if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304676 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
4677 goto fail;
4678 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304679 pReqMsg->reportThresholdPercent = nla_get_u8(
4680 tb[PARAM_RPT_THRHLD_PERCENT]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304681 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304682 pReqMsg->reportThresholdPercent);
4683
4684 /* Parse and fetch report threshold num scans */
4685 if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
4686 hddLog(LOGE, FL("attr report_threshold num scans failed"));
4687 goto fail;
4688 }
4689 pReqMsg->reportThresholdNumScans = nla_get_u8(
4690 tb[PARAM_RPT_THRHLD_NUM_SCANS]);
4691 hddLog(LOG1, FL("Report Threshold num scans %d"),
4692 pReqMsg->reportThresholdNumScans);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304693
4694 /* Parse and fetch number of buckets */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304695 if (!tb[PARAM_NUM_BUCKETS]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304696 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
4697 goto fail;
4698 }
4699 pReqMsg->numBuckets = nla_get_u8(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304700 tb[PARAM_NUM_BUCKETS]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304701 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
4702 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
4703 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
4704 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
4705 }
4706 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
4707 pReqMsg->numBuckets);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304708
Dino Mycle6fb96c12014-06-10 11:52:40 +05304709 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
4710 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
4711 goto fail;
4712 }
4713
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304714 pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304715
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304716 if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
4717 goto fail;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304718
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304719 context = &pHddCtx->ext_scan_context;
4720 spin_lock(&hdd_context_lock);
4721 INIT_COMPLETION(context->response_event);
4722 context->request_id = request_id = pReqMsg->requestId;
4723 spin_unlock(&hdd_context_lock);
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304724
Dino Mycle6fb96c12014-06-10 11:52:40 +05304725 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
4726 if (!HAL_STATUS_SUCCESS(status)) {
4727 hddLog(VOS_TRACE_LEVEL_ERROR,
4728 FL("sme_EXTScanStart failed(err=%d)"), status);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304729 goto fail;
4730 }
4731
Srinivas Dasari91727c12016-03-23 17:59:06 +05304732 pHddCtx->extscan_start_time_since_boot = vos_get_monotonic_boottime();
4733
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304734 /* request was sent -- wait for the response */
4735 rc = wait_for_completion_timeout(&context->response_event,
4736 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4737
4738 if (!rc) {
4739 hddLog(LOGE, FL("sme_ExtScanStart timed out"));
4740 retval = -ETIMEDOUT;
4741 } else {
4742 spin_lock(&hdd_context_lock);
4743 if (context->request_id == request_id)
4744 retval = context->response_status;
4745 else
4746 retval = -EINVAL;
4747 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304748 }
4749
Dino Myclee8843b32014-07-04 14:21:45 +05304750 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304751 EXIT();
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304752 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304753
4754fail:
4755 vos_mem_free(pReqMsg);
4756 return -EINVAL;
4757}
4758
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304759/*
4760 * done with short names for the global vendor params
4761 * used by wlan_hdd_cfg80211_extscan_start()
4762 */
4763#undef PARAM_MAX
4764#undef PARAM_REQUEST_ID
4765#undef PARAM_BASE_PERIOD
4766#undef PARAMS_MAX_AP_PER_SCAN
4767#undef PARAMS_RPT_THRHLD_PERCENT
4768#undef PARAMS_RPT_THRHLD_NUM_SCANS
4769#undef PARAMS_NUM_BUCKETS
4770
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304771static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
4772 struct wireless_dev *wdev,
4773 const void *data, int dataLen)
4774{
4775 int ret = 0;
4776
4777 vos_ssr_protect(__func__);
4778 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
4779 vos_ssr_unprotect(__func__);
4780
4781 return ret;
4782}
4783
4784static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304785 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304786 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304787{
Dino Myclee8843b32014-07-04 14:21:45 +05304788 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304789 struct net_device *dev = wdev->netdev;
4790 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4791 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4792 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4793 eHalStatus status;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304794 int retval;
4795 unsigned long rc;
4796 struct hdd_ext_scan_context *context;
4797 tANI_U32 request_id;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304798
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304799 ENTER();
4800
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304801 if (VOS_FTM_MODE == hdd_get_conparam()) {
4802 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4803 return -EINVAL;
4804 }
4805
Dino Mycle6fb96c12014-06-10 11:52:40 +05304806 status = wlan_hdd_validate_context(pHddCtx);
4807 if (0 != status)
4808 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304809 return -EINVAL;
4810 }
Dino Myclee8843b32014-07-04 14:21:45 +05304811 /* check the EXTScan Capability */
4812 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304813 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4814 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304815 {
4816 hddLog(VOS_TRACE_LEVEL_ERROR,
4817 FL("EXTScan not enabled/supported by Firmware"));
4818 return -EINVAL;
4819 }
4820
Dino Mycle6fb96c12014-06-10 11:52:40 +05304821 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4822 data, dataLen,
4823 wlan_hdd_extscan_config_policy)) {
4824 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4825 return -EINVAL;
4826 }
4827
4828 /* Parse and fetch request Id */
4829 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4830 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4831 return -EINVAL;
4832 }
4833
Dino Myclee8843b32014-07-04 14:21:45 +05304834 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304835 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304836 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304837
Dino Myclee8843b32014-07-04 14:21:45 +05304838 reqMsg.sessionId = pAdapter->sessionId;
4839 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304840
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304841 context = &pHddCtx->ext_scan_context;
4842 spin_lock(&hdd_context_lock);
4843 INIT_COMPLETION(context->response_event);
Sravanti Palakonda7539fb92016-02-26 17:49:21 +05304844 context->request_id = request_id = reqMsg.requestId;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304845 spin_unlock(&hdd_context_lock);
4846
Dino Myclee8843b32014-07-04 14:21:45 +05304847 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304848 if (!HAL_STATUS_SUCCESS(status)) {
4849 hddLog(VOS_TRACE_LEVEL_ERROR,
4850 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304851 return -EINVAL;
4852 }
4853
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304854 /* request was sent -- wait for the response */
4855 rc = wait_for_completion_timeout(&context->response_event,
4856 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4857
4858 if (!rc) {
4859 hddLog(LOGE, FL("sme_ExtScanStop timed out"));
4860 retval = -ETIMEDOUT;
4861 } else {
4862 spin_lock(&hdd_context_lock);
4863 if (context->request_id == request_id)
4864 retval = context->response_status;
4865 else
4866 retval = -EINVAL;
4867 spin_unlock(&hdd_context_lock);
4868 }
4869
4870 return retval;
4871
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304872 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304873 return 0;
4874}
4875
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304876static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
4877 struct wireless_dev *wdev,
4878 const void *data, int dataLen)
4879{
4880 int ret = 0;
4881
4882 vos_ssr_protect(__func__);
4883 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
4884 vos_ssr_unprotect(__func__);
4885
4886 return ret;
4887}
4888
4889static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304890 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304891 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304892{
Dino Myclee8843b32014-07-04 14:21:45 +05304893 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304894 struct net_device *dev = wdev->netdev;
4895 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4896 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4897 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4898 eHalStatus status;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304899 struct hdd_ext_scan_context *context;
4900 tANI_U32 request_id;
4901 unsigned long rc;
4902 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304903
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304904 ENTER();
4905
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304906 if (VOS_FTM_MODE == hdd_get_conparam()) {
4907 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4908 return -EINVAL;
4909 }
4910
Dino Mycle6fb96c12014-06-10 11:52:40 +05304911 status = wlan_hdd_validate_context(pHddCtx);
4912 if (0 != status)
4913 {
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304914 hddLog(LOGE, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304915 return -EINVAL;
4916 }
Dino Myclee8843b32014-07-04 14:21:45 +05304917 /* check the EXTScan Capability */
4918 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304919 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4920 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304921 {
4922 hddLog(VOS_TRACE_LEVEL_ERROR,
4923 FL("EXTScan not enabled/supported by Firmware"));
4924 return -EINVAL;
4925 }
4926
Dino Mycle6fb96c12014-06-10 11:52:40 +05304927 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4928 data, dataLen,
4929 wlan_hdd_extscan_config_policy)) {
4930 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4931 return -EINVAL;
4932 }
4933
4934 /* Parse and fetch request Id */
4935 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4936 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4937 return -EINVAL;
4938 }
4939
Dino Myclee8843b32014-07-04 14:21:45 +05304940 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304941 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304942 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304943
Dino Myclee8843b32014-07-04 14:21:45 +05304944 reqMsg.sessionId = pAdapter->sessionId;
4945 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304946
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304947 context = &pHddCtx->ext_scan_context;
4948 spin_lock(&hdd_context_lock);
4949 INIT_COMPLETION(context->response_event);
4950 context->request_id = request_id = reqMsg.requestId;
4951 spin_unlock(&hdd_context_lock);
4952
Dino Myclee8843b32014-07-04 14:21:45 +05304953 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304954 if (!HAL_STATUS_SUCCESS(status)) {
4955 hddLog(VOS_TRACE_LEVEL_ERROR,
4956 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304957 return -EINVAL;
4958 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304959
4960 /* request was sent -- wait for the response */
4961 rc = wait_for_completion_timeout(&context->response_event,
4962 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4963 if (!rc) {
4964 hddLog(LOGE, FL("sme_ResetBssHotlist timed out"));
4965 retval = -ETIMEDOUT;
4966 } else {
4967 spin_lock(&hdd_context_lock);
4968 if (context->request_id == request_id)
4969 retval = context->response_status;
4970 else
4971 retval = -EINVAL;
4972 spin_unlock(&hdd_context_lock);
4973 }
4974
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304975 EXIT();
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304976 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304977}
4978
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304979static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
4980 struct wireless_dev *wdev,
4981 const void *data, int dataLen)
4982{
4983 int ret = 0;
4984
4985 vos_ssr_protect(__func__);
4986 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
4987 vos_ssr_unprotect(__func__);
4988
4989 return ret;
4990}
Dino Mycle6fb96c12014-06-10 11:52:40 +05304991#endif /* WLAN_FEATURE_EXTSCAN */
4992
Atul Mittal115287b2014-07-08 13:26:33 +05304993/*EXT TDLS*/
4994static const struct nla_policy
4995wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
4996{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05304997 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {
4998 .type = NLA_UNSPEC,
4999 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305000 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
5001 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
5002 {.type = NLA_S32 },
5003 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
5004 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
5005
5006};
5007
5008static const struct nla_policy
5009wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
5010{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305011 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {
5012 .type = NLA_UNSPEC,
5013 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305014
5015};
5016
5017static const struct nla_policy
5018wlan_hdd_tdls_config_state_change_policy[
5019 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
5020{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305021 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {
5022 .type = NLA_UNSPEC,
5023 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305024 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
5025 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305026 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
5027 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
5028 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305029
5030};
5031
5032static const struct nla_policy
5033wlan_hdd_tdls_config_get_status_policy[
5034 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
5035{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305036 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {
5037 .type = NLA_UNSPEC,
5038 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305039 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
5040 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305041 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
5042 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
5043 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305044
5045};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305046
5047static const struct nla_policy
5048wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
5049{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305050 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {
5051 .type = NLA_UNSPEC,
5052 .len = VOS_MAC_ADDR_FIRST_3_BYTES},
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305053};
5054
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305055static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305056 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305057 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305058 int data_len)
5059{
5060
5061 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5062 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
5063
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305064 ENTER();
5065
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305066 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305067 return -EINVAL;
5068 }
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +05305069 if (0 == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05305070 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305071 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05305072 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305073 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05305074 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305075 return -ENOTSUPP;
5076 }
5077
5078 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
5079 data, data_len, wlan_hdd_mac_config)) {
5080 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5081 return -EINVAL;
5082 }
5083
5084 /* Parse and fetch mac address */
5085 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
5086 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5087 return -EINVAL;
5088 }
5089
5090 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
5091 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5092 VOS_MAC_ADDR_LAST_3_BYTES);
5093
Siddharth Bhal76972212014-10-15 16:22:51 +05305094 pHddCtx->spoofMacAddr.isEnabled = TRUE;
5095
5096 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305097 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5098 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05305099 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
5100 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
5101 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
5102 {
5103 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
5104 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
5105 VOS_MAC_ADDRESS_LEN);
5106 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305107 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305108
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +05305109 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
5110 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305111
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305112 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305113 return 0;
5114}
5115
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305116static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
5117 struct wireless_dev *wdev,
5118 const void *data,
5119 int data_len)
5120{
5121 int ret = 0;
5122
5123 vos_ssr_protect(__func__);
5124 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
5125 vos_ssr_unprotect(__func__);
5126
5127 return ret;
5128}
5129
5130static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305131 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305132 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305133 int data_len)
5134{
5135 u8 peer[6] = {0};
5136 struct net_device *dev = wdev->netdev;
5137 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5138 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5139 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
5140 eHalStatus ret;
5141 tANI_S32 state;
5142 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305143 tANI_S32 global_operating_class = 0;
5144 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05305145 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305146 int retVal;
5147
5148 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305149
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305150 if (!pAdapter) {
5151 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5152 return -EINVAL;
5153 }
5154
Atul Mittal115287b2014-07-08 13:26:33 +05305155 ret = wlan_hdd_validate_context(pHddCtx);
5156 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305157 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305158 return -EINVAL;
5159 }
5160 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305161 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305162 return -ENOTSUPP;
5163 }
5164 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
5165 data, data_len,
5166 wlan_hdd_tdls_config_get_status_policy)) {
5167 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5168 return -EINVAL;
5169 }
5170
5171 /* Parse and fetch mac address */
5172 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
5173 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5174 return -EINVAL;
5175 }
5176
5177 memcpy(peer, nla_data(
5178 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
5179 sizeof(peer));
5180 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5181
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05305182 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05305183
Atul Mittal115287b2014-07-08 13:26:33 +05305184 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305185 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05305186 NLMSG_HDRLEN);
5187
5188 if (!skb) {
5189 hddLog(VOS_TRACE_LEVEL_ERROR,
5190 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5191 return -EINVAL;
5192 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305193 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 +05305194 reason,
5195 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305196 global_operating_class,
5197 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05305198 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305199 if (nla_put_s32(skb,
5200 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
5201 state) ||
5202 nla_put_s32(skb,
5203 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
5204 reason) ||
5205 nla_put_s32(skb,
5206 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
5207 global_operating_class) ||
5208 nla_put_s32(skb,
5209 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
5210 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05305211
5212 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5213 goto nla_put_failure;
5214 }
5215
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305216 retVal = cfg80211_vendor_cmd_reply(skb);
5217 EXIT();
5218 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05305219
5220nla_put_failure:
5221 kfree_skb(skb);
5222 return -EINVAL;
5223}
5224
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305225static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
5226 struct wireless_dev *wdev,
5227 const void *data,
5228 int data_len)
5229{
5230 int ret = 0;
5231
5232 vos_ssr_protect(__func__);
5233 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
5234 vos_ssr_unprotect(__func__);
5235
5236 return ret;
5237}
5238
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05305239static int wlan_hdd_cfg80211_exttdls_callback(
5240#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
5241 const tANI_U8* mac,
5242#else
5243 tANI_U8* mac,
5244#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305245 tANI_S32 state,
5246 tANI_S32 reason,
5247 void *ctx)
5248{
5249 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05305250 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305251 tANI_S32 global_operating_class = 0;
5252 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305253 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05305254
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305255 ENTER();
5256
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305257 if (!pAdapter) {
5258 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5259 return -EINVAL;
5260 }
5261
5262 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05305263 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305264 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305265 return -EINVAL;
5266 }
5267
5268 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305269 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305270 return -ENOTSUPP;
5271 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05305272 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
5273#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
5274 NULL,
5275#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305276 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
5277 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
5278 GFP_KERNEL);
5279
5280 if (!skb) {
5281 hddLog(VOS_TRACE_LEVEL_ERROR,
5282 FL("cfg80211_vendor_event_alloc failed"));
5283 return -EINVAL;
5284 }
5285 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305286 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
5287 reason,
5288 state,
5289 global_operating_class,
5290 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05305291 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
5292 MAC_ADDR_ARRAY(mac));
5293
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305294 if (nla_put(skb,
5295 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
5296 VOS_MAC_ADDR_SIZE, mac) ||
5297 nla_put_s32(skb,
5298 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
5299 state) ||
5300 nla_put_s32(skb,
5301 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
5302 reason) ||
5303 nla_put_s32(skb,
5304 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
5305 channel) ||
5306 nla_put_s32(skb,
5307 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
5308 global_operating_class)
5309 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05305310 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5311 goto nla_put_failure;
5312 }
5313
5314 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305315 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05305316 return (0);
5317
5318nla_put_failure:
5319 kfree_skb(skb);
5320 return -EINVAL;
5321}
5322
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305323static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305324 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305325 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305326 int data_len)
5327{
5328 u8 peer[6] = {0};
5329 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305330 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5331 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
5332 eHalStatus status;
5333 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305334 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305335 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305336
5337 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305338
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305339 if (!dev) {
5340 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5341 return -EINVAL;
5342 }
5343
5344 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5345 if (!pAdapter) {
5346 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5347 return -EINVAL;
5348 }
5349
Atul Mittal115287b2014-07-08 13:26:33 +05305350 status = wlan_hdd_validate_context(pHddCtx);
5351 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305352 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305353 return -EINVAL;
5354 }
5355 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305356 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305357 return -ENOTSUPP;
5358 }
5359 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
5360 data, data_len,
5361 wlan_hdd_tdls_config_enable_policy)) {
5362 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5363 return -EINVAL;
5364 }
5365
5366 /* Parse and fetch mac address */
5367 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
5368 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5369 return -EINVAL;
5370 }
5371
5372 memcpy(peer, nla_data(
5373 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
5374 sizeof(peer));
5375 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5376
5377 /* Parse and fetch channel */
5378 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
5379 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
5380 return -EINVAL;
5381 }
5382 pReqMsg.channel = nla_get_s32(
5383 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
5384 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
5385
5386 /* Parse and fetch global operating class */
5387 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
5388 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
5389 return -EINVAL;
5390 }
5391 pReqMsg.global_operating_class = nla_get_s32(
5392 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
5393 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
5394 pReqMsg.global_operating_class);
5395
5396 /* Parse and fetch latency ms */
5397 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
5398 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
5399 return -EINVAL;
5400 }
5401 pReqMsg.max_latency_ms = nla_get_s32(
5402 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
5403 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
5404 pReqMsg.max_latency_ms);
5405
5406 /* Parse and fetch required bandwidth kbps */
5407 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
5408 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
5409 return -EINVAL;
5410 }
5411
5412 pReqMsg.min_bandwidth_kbps = nla_get_s32(
5413 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
5414 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
5415 pReqMsg.min_bandwidth_kbps);
5416
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305417 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05305418 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05305419 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305420 wlan_hdd_cfg80211_exttdls_callback);
5421
5422 EXIT();
5423 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305424}
5425
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305426static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
5427 struct wireless_dev *wdev,
5428 const void *data,
5429 int data_len)
5430{
5431 int ret = 0;
5432
5433 vos_ssr_protect(__func__);
5434 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
5435 vos_ssr_unprotect(__func__);
5436
5437 return ret;
5438}
5439
5440static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305441 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305442 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305443 int data_len)
5444{
5445 u8 peer[6] = {0};
5446 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305447 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5448 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
5449 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305450 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305451 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305452
5453 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305454
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305455 if (!dev) {
5456 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5457 return -EINVAL;
5458 }
5459
5460 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5461 if (!pAdapter) {
5462 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
5463 return -EINVAL;
5464 }
5465
Atul Mittal115287b2014-07-08 13:26:33 +05305466 status = wlan_hdd_validate_context(pHddCtx);
5467 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305468 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305469 return -EINVAL;
5470 }
5471 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305472 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305473 return -ENOTSUPP;
5474 }
5475 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
5476 data, data_len,
5477 wlan_hdd_tdls_config_disable_policy)) {
5478 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5479 return -EINVAL;
5480 }
5481 /* Parse and fetch mac address */
5482 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
5483 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5484 return -EINVAL;
5485 }
5486
5487 memcpy(peer, nla_data(
5488 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
5489 sizeof(peer));
5490 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5491
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305492 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
5493
5494 EXIT();
5495 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305496}
5497
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305498static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
5499 struct wireless_dev *wdev,
5500 const void *data,
5501 int data_len)
5502{
5503 int ret = 0;
5504
5505 vos_ssr_protect(__func__);
5506 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
5507 vos_ssr_unprotect(__func__);
5508
5509 return ret;
5510}
5511
Dasari Srinivas7875a302014-09-26 17:50:57 +05305512static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305513__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05305514 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305515 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05305516{
5517 struct net_device *dev = wdev->netdev;
5518 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5519 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5520 struct sk_buff *skb = NULL;
5521 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305522 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305523
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305524 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305525
5526 ret = wlan_hdd_validate_context(pHddCtx);
5527 if (0 != ret)
5528 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305529 return ret;
5530 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305531 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
5532 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
5533 fset |= WIFI_FEATURE_INFRA;
5534 }
5535
5536 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
5537 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
5538 fset |= WIFI_FEATURE_INFRA_5G;
5539 }
5540
5541#ifdef WLAN_FEATURE_P2P
5542 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
5543 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
5544 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
5545 fset |= WIFI_FEATURE_P2P;
5546 }
5547#endif
5548
5549 /* Soft-AP is supported currently by default */
5550 fset |= WIFI_FEATURE_SOFT_AP;
5551
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05305552 /* HOTSPOT is a supplicant feature, enable it by default */
5553 fset |= WIFI_FEATURE_HOTSPOT;
5554
Dasari Srinivas7875a302014-09-26 17:50:57 +05305555#ifdef WLAN_FEATURE_EXTSCAN
5556 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305557 sme_IsFeatureSupportedByFW(EXTENDED_SCAN) &&
5558 sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)) {
5559 hddLog(LOG1, FL("Enhanced EXTScan is supported by firmware"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05305560 fset |= WIFI_FEATURE_EXTSCAN;
5561 }
5562#endif
5563
Dasari Srinivas7875a302014-09-26 17:50:57 +05305564 if (sme_IsFeatureSupportedByFW(NAN)) {
5565 hddLog(LOG1, FL("NAN is supported by firmware"));
5566 fset |= WIFI_FEATURE_NAN;
5567 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305568
5569 /* D2D RTT is not supported currently by default */
5570 if (sme_IsFeatureSupportedByFW(RTT)) {
5571 hddLog(LOG1, FL("RTT is supported by firmware"));
5572 fset |= WIFI_FEATURE_D2AP_RTT;
5573 }
5574
Padma, Santhosh Kumaraac4c4d2015-12-08 16:07:47 +05305575 if (sme_IsFeatureSupportedByFW(RTT3)) {
5576 hddLog(LOG1, FL("RTT3 is supported by firmware"));
5577 fset |= WIFI_FEATURE_RTT3;
5578 }
5579
Dasari Srinivas7875a302014-09-26 17:50:57 +05305580#ifdef FEATURE_WLAN_BATCH_SCAN
5581 if (fset & WIFI_FEATURE_EXTSCAN) {
5582 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
5583 fset &= ~WIFI_FEATURE_BATCH_SCAN;
5584 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
5585 hddLog(LOG1, FL("Batch scan is supported by firmware"));
5586 fset |= WIFI_FEATURE_BATCH_SCAN;
5587 }
5588#endif
5589
5590#ifdef FEATURE_WLAN_SCAN_PNO
5591 if (pHddCtx->cfg_ini->configPNOScanSupport &&
5592 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
5593 hddLog(LOG1, FL("PNO is supported by firmware"));
5594 fset |= WIFI_FEATURE_PNO;
5595 }
5596#endif
5597
5598 /* STA+STA is supported currently by default */
5599 fset |= WIFI_FEATURE_ADDITIONAL_STA;
5600
5601#ifdef FEATURE_WLAN_TDLS
5602 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
5603 sme_IsFeatureSupportedByFW(TDLS)) {
5604 hddLog(LOG1, FL("TDLS is supported by firmware"));
5605 fset |= WIFI_FEATURE_TDLS;
5606 }
5607
5608 /* TDLS_OFFCHANNEL is not supported currently by default */
5609#endif
5610
5611#ifdef WLAN_AP_STA_CONCURRENCY
5612 /* AP+STA concurrency is supported currently by default */
5613 fset |= WIFI_FEATURE_AP_STA;
5614#endif
5615
Mukul Sharma5add0532015-08-17 15:57:47 +05305616#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5617 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
5618 hddLog(LOG1, FL("Link layer stats is supported by driver"));
5619#endif
5620
Dasari Srinivas7875a302014-09-26 17:50:57 +05305621 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
5622 NLMSG_HDRLEN);
5623
5624 if (!skb) {
5625 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5626 return -EINVAL;
5627 }
5628 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
5629
5630 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
5631 hddLog(LOGE, FL("nla put fail"));
5632 goto nla_put_failure;
5633 }
5634
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305635 ret = cfg80211_vendor_cmd_reply(skb);
5636 EXIT();
5637 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305638
5639nla_put_failure:
5640 kfree_skb(skb);
5641 return -EINVAL;
5642}
5643
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305644static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305645wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
5646 struct wireless_dev *wdev,
5647 const void *data, int data_len)
5648{
5649 int ret = 0;
5650
5651 vos_ssr_protect(__func__);
5652 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
5653 vos_ssr_unprotect(__func__);
5654
5655 return ret;
5656}
5657
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305658
5659static const struct
5660nla_policy
5661qca_wlan_vendor_wifi_logger_get_ring_data_policy
5662[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1] = {
5663 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]
5664 = {.type = NLA_U32 },
5665};
5666
5667static int
5668 __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
5669 struct wireless_dev *wdev,
5670 const void *data,
5671 int data_len)
5672{
5673 int ret;
5674 VOS_STATUS status;
5675 uint32_t ring_id;
5676 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5677 struct nlattr *tb
5678 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1];
5679
5680 ENTER();
5681
5682 ret = wlan_hdd_validate_context(hdd_ctx);
5683 if (0 != ret) {
5684 return ret;
5685 }
5686
5687 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX,
5688 data, data_len,
5689 qca_wlan_vendor_wifi_logger_get_ring_data_policy)) {
5690 hddLog(LOGE, FL("Invalid attribute"));
5691 return -EINVAL;
5692 }
5693
5694 /* Parse and fetch ring id */
5695 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]) {
5696 hddLog(LOGE, FL("attr ATTR failed"));
5697 return -EINVAL;
5698 }
5699
5700 ring_id = nla_get_u32(
5701 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]);
5702
5703 hddLog(LOG1, FL("Bug report triggered by framework"));
5704
5705 status = vos_fatal_event_logs_req(WLAN_LOG_TYPE_NON_FATAL,
5706 WLAN_LOG_INDICATOR_FRAMEWORK,
5707 WLAN_LOG_REASON_CODE_FRAMEWORK,
Abhishek Singh837adf22015-10-01 17:37:37 +05305708 TRUE, TRUE
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305709 );
5710 if (VOS_STATUS_SUCCESS != status) {
5711 hddLog(LOGE, FL("Failed to trigger bug report"));
5712
5713 return -EINVAL;
5714 }
5715
5716 return 0;
5717
5718
5719}
5720
5721
5722static int
5723 wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
5724 struct wireless_dev *wdev,
5725 const void *data,
5726 int data_len)
5727{
5728 int ret = 0;
5729
5730 vos_ssr_protect(__func__);
5731 ret = __wlan_hdd_cfg80211_wifi_logger_get_ring_data(wiphy,
5732 wdev, data, data_len);
5733 vos_ssr_unprotect(__func__);
5734
5735 return ret;
5736
5737}
5738
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05305739#define MAX_CONCURRENT_MATRIX \
5740 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX
5741#define MATRIX_CONFIG_PARAM_SET_SIZE_MAX \
5742 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX
5743static const struct nla_policy
5744wlan_hdd_get_concurrency_matrix_policy[MAX_CONCURRENT_MATRIX + 1] = {
5745 [MATRIX_CONFIG_PARAM_SET_SIZE_MAX] = {.type = NLA_U32},
5746};
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305747
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305748static int
5749__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305750 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305751 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305752{
5753 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
5754 uint8_t i, feature_sets, max_feature_sets;
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05305755 struct nlattr *tb[MAX_CONCURRENT_MATRIX + 1];
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305756 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305757 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5758 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305759
5760 ENTER();
5761
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305762 ret = wlan_hdd_validate_context(pHddCtx);
5763 if (0 != ret)
5764 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305765 return ret;
5766 }
5767
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05305768 if (nla_parse(tb, MAX_CONCURRENT_MATRIX, data, data_len,
5769 wlan_hdd_get_concurrency_matrix_policy)) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305770 hddLog(LOGE, FL("Invalid ATTR"));
5771 return -EINVAL;
5772 }
5773
5774 /* Parse and fetch max feature set */
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05305775 if (!tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305776 hddLog(LOGE, FL("Attr max feature set size failed"));
5777 return -EINVAL;
5778 }
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05305779 max_feature_sets = nla_get_u32(tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305780 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
5781
5782 /* Fill feature combination matrix */
5783 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305784 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5785 WIFI_FEATURE_P2P;
5786
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305787 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5788 WIFI_FEATURE_SOFT_AP;
5789
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305790 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
5791 WIFI_FEATURE_SOFT_AP;
5792
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305793 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5794 WIFI_FEATURE_SOFT_AP |
5795 WIFI_FEATURE_P2P;
5796
5797 /* Add more feature combinations here */
5798
5799 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
5800 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
5801 hddLog(LOG1, "Feature set matrix");
5802 for (i = 0; i < feature_sets; i++)
5803 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
5804
5805 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
5806 sizeof(u32) * feature_sets +
5807 NLMSG_HDRLEN);
5808
5809 if (reply_skb) {
5810 if (nla_put_u32(reply_skb,
5811 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
5812 feature_sets) ||
5813 nla_put(reply_skb,
5814 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
5815 sizeof(u32) * feature_sets, feature_set_matrix)) {
5816 hddLog(LOGE, FL("nla put fail"));
5817 kfree_skb(reply_skb);
5818 return -EINVAL;
5819 }
5820
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305821 ret = cfg80211_vendor_cmd_reply(reply_skb);
5822 EXIT();
5823 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305824 }
5825 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
5826 return -ENOMEM;
5827
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305828}
5829
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05305830#undef MAX_CONCURRENT_MATRIX
5831#undef MATRIX_CONFIG_PARAM_SET_SIZE_MAX
5832
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305833static int
5834wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
5835 struct wireless_dev *wdev,
5836 const void *data, int data_len)
5837{
5838 int ret = 0;
5839
5840 vos_ssr_protect(__func__);
5841 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
5842 data_len);
5843 vos_ssr_unprotect(__func__);
5844
5845 return ret;
5846}
5847
c_manjeecfd1efb2015-09-25 19:32:34 +05305848
5849static int
5850__wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5851 struct wireless_dev *wdev,
5852 const void *data, int data_len)
5853{
5854 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5855 int ret;
5856 ENTER();
5857
5858 ret = wlan_hdd_validate_context(pHddCtx);
5859 if (0 != ret)
5860 {
5861 return ret;
5862 }
5863
5864 if( !pHddCtx->cfg_ini->enableFwrMemDump ||
5865 (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
5866 {
5867 hddLog(VOS_TRACE_LEVEL_INFO, FL("FW dump Logging not supported"));
5868 return -EINVAL;
5869 }
5870 /*call common API for FW mem dump req*/
5871 ret = wlan_hdd_fw_mem_dump_req(pHddCtx);
5872
Abhishek Singhc783fa72015-12-09 18:07:34 +05305873 if (!ret)
c_manjee04b4c5c2015-10-13 18:35:01 +05305874 {
5875 /*indicate to userspace the status of fw mem dump */
5876 wlan_indicate_mem_dump_complete(true);
5877 }
5878 else
5879 {
5880 /*else send failure to userspace */
5881 wlan_indicate_mem_dump_complete(false);
5882 }
c_manjeecfd1efb2015-09-25 19:32:34 +05305883 EXIT();
5884 return ret;
5885}
5886
5887/**
5888 * wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump
5889 * @wiphy: pointer to wireless wiphy structure.
5890 * @wdev: pointer to wireless_dev structure.
5891 * @data: Pointer to the NL data.
5892 * @data_len:Length of @data
5893 *
5894 * This is called when wlan driver needs to get the firmware memory dump
5895 * via vendor specific command.
5896 *
5897 * Return: 0 on success, error number otherwise.
5898 */
5899
5900static int
5901wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5902 struct wireless_dev *wdev,
5903 const void *data, int data_len)
Sushant Kaushik8e644982015-09-23 12:18:54 +05305904{
5905 int ret = 0;
5906 vos_ssr_protect(__func__);
5907 ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data,
5908 data_len);
5909 vos_ssr_unprotect(__func__);
5910 return ret;
5911}
c_manjeecfd1efb2015-09-25 19:32:34 +05305912
Sushant Kaushik8e644982015-09-23 12:18:54 +05305913static const struct
5914nla_policy
5915qca_wlan_vendor_wifi_logger_start_policy
5916[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
5917 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
5918 = {.type = NLA_U32 },
5919 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
5920 = {.type = NLA_U32 },
5921 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
5922 = {.type = NLA_U32 },
5923};
5924
5925/**
5926 * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
5927 * or disable the collection of packet statistics from the firmware
5928 * @wiphy: WIPHY structure pointer
5929 * @wdev: Wireless device structure pointer
5930 * @data: Pointer to the data received
5931 * @data_len: Length of the data received
5932 *
5933 * This function is used to enable or disable the collection of packet
5934 * statistics from the firmware
5935 *
5936 * Return: 0 on success and errno on failure
5937 */
5938static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
5939 struct wireless_dev *wdev,
5940 const void *data,
5941 int data_len)
5942{
5943 eHalStatus status;
5944 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5945 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
5946 tAniWifiStartLog start_log;
5947
5948 status = wlan_hdd_validate_context(hdd_ctx);
5949 if (0 != status) {
5950 return -EINVAL;
5951 }
5952
5953 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
5954 data, data_len,
5955 qca_wlan_vendor_wifi_logger_start_policy)) {
5956 hddLog(LOGE, FL("Invalid attribute"));
5957 return -EINVAL;
5958 }
5959
5960 /* Parse and fetch ring id */
5961 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
5962 hddLog(LOGE, FL("attr ATTR failed"));
5963 return -EINVAL;
5964 }
5965 start_log.ringId = nla_get_u32(
5966 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
5967 hddLog(LOG1, FL("Ring ID=%d"), start_log.ringId);
5968
5969 /* Parse and fetch verbose level */
5970 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
5971 hddLog(LOGE, FL("attr verbose_level failed"));
5972 return -EINVAL;
5973 }
5974 start_log.verboseLevel = nla_get_u32(
5975 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
5976 hddLog(LOG1, FL("verbose_level=%d"), start_log.verboseLevel);
5977
5978 /* Parse and fetch flag */
5979 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
5980 hddLog(LOGE, FL("attr flag failed"));
5981 return -EINVAL;
5982 }
5983 start_log.flag = nla_get_u32(
5984 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
5985 hddLog(LOG1, FL("flag=%d"), start_log.flag);
5986
5987 if ((RING_ID_PER_PACKET_STATS == start_log.ringId) &&
Sushant Kaushik33200572015-08-05 16:46:20 +05305988 (!hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable ||
5989 !vos_isPktStatsEnabled()))
5990
Sushant Kaushik8e644982015-09-23 12:18:54 +05305991 {
5992 hddLog(LOGE, FL("per pkt stats not enabled"));
5993 return -EINVAL;
5994 }
Sushant Kaushik8e644982015-09-23 12:18:54 +05305995
Sushant Kaushik33200572015-08-05 16:46:20 +05305996 vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel);
Sushant Kaushik8e644982015-09-23 12:18:54 +05305997 return 0;
5998}
5999
6000/**
6001 * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
6002 * or disable the collection of packet statistics from the firmware
6003 * @wiphy: WIPHY structure pointer
6004 * @wdev: Wireless device structure pointer
6005 * @data: Pointer to the data received
6006 * @data_len: Length of the data received
6007 *
6008 * This function is used to enable or disable the collection of packet
6009 * statistics from the firmware
6010 *
6011 * Return: 0 on success and errno on failure
6012 */
6013static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6014 struct wireless_dev *wdev,
6015 const void *data,
6016 int data_len)
c_manjeecfd1efb2015-09-25 19:32:34 +05306017{
6018 int ret = 0;
6019
6020 vos_ssr_protect(__func__);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306021
6022 ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
6023 wdev, data, data_len);
c_manjeecfd1efb2015-09-25 19:32:34 +05306024 vos_ssr_unprotect(__func__);
6025
6026 return ret;
c_manjeecfd1efb2015-09-25 19:32:34 +05306027}
6028
6029
Agarwal Ashish738843c2014-09-25 12:27:56 +05306030static const struct nla_policy
6031wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
6032 +1] =
6033{
6034 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
6035};
6036
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306037static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306038 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306039 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306040 int data_len)
6041{
6042 struct net_device *dev = wdev->netdev;
6043 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6044 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6045 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6046 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
6047 eHalStatus status;
6048 u32 dfsFlag = 0;
6049
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306050 ENTER();
6051
Agarwal Ashish738843c2014-09-25 12:27:56 +05306052 status = wlan_hdd_validate_context(pHddCtx);
6053 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05306054 return -EINVAL;
6055 }
6056 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
6057 data, data_len,
6058 wlan_hdd_set_no_dfs_flag_config_policy)) {
6059 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6060 return -EINVAL;
6061 }
6062
6063 /* Parse and fetch required bandwidth kbps */
6064 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
6065 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
6066 return -EINVAL;
6067 }
6068
6069 dfsFlag = nla_get_u32(
6070 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
6071 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
6072 dfsFlag);
6073
6074 pHddCtx->disable_dfs_flag = dfsFlag;
6075
6076 sme_disable_dfs_channel(hHal, dfsFlag);
6077 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306078
6079 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05306080 return 0;
6081}
Atul Mittal115287b2014-07-08 13:26:33 +05306082
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306083static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
6084 struct wireless_dev *wdev,
6085 const void *data,
6086 int data_len)
6087{
6088 int ret = 0;
6089
6090 vos_ssr_protect(__func__);
6091 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
6092 vos_ssr_unprotect(__func__);
6093
6094 return ret;
6095
6096}
6097
Mukul Sharma2a271632014-10-13 14:59:01 +05306098const struct
6099nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
6100{
6101 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05306102 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
6103 .type = NLA_UNSPEC,
6104 .len = HDD_MAC_ADDR_LEN},
Mukul Sharma2a271632014-10-13 14:59:01 +05306105};
6106
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306107static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05306108 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05306109{
6110
6111 u8 bssid[6] = {0};
6112 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6113 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6114 eHalStatus status = eHAL_STATUS_SUCCESS;
6115 v_U32_t isFwrRoamEnabled = FALSE;
6116 int ret;
6117
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306118 ENTER();
6119
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306120 ret = wlan_hdd_validate_context(pHddCtx);
6121 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306122 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05306123 }
6124
6125 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
6126 data, data_len,
6127 qca_wlan_vendor_attr);
6128 if (ret){
6129 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6130 return -EINVAL;
6131 }
6132
6133 /* Parse and fetch Enable flag */
6134 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
6135 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
6136 return -EINVAL;
6137 }
6138
6139 isFwrRoamEnabled = nla_get_u32(
6140 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
6141
6142 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
6143
6144 /* Parse and fetch bssid */
6145 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
6146 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
6147 return -EINVAL;
6148 }
6149
6150 memcpy(bssid, nla_data(
6151 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
6152 sizeof(bssid));
6153 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
6154
6155 //Update roaming
6156 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306157 if (!HAL_STATUS_SUCCESS(status)) {
6158 hddLog(LOGE,
6159 FL("sme_ConfigFwrRoaming failed (err=%d)"), status);
6160 return -EINVAL;
6161 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306162 EXIT();
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306163 return 0;
Mukul Sharma2a271632014-10-13 14:59:01 +05306164}
6165
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306166static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
6167 struct wireless_dev *wdev, const void *data, int data_len)
6168{
6169 int ret = 0;
6170
6171 vos_ssr_protect(__func__);
6172 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
6173 vos_ssr_unprotect(__func__);
6174
6175 return ret;
6176}
6177
Sushant Kaushik847890c2015-09-28 16:05:17 +05306178static const struct
6179nla_policy
6180qca_wlan_vendor_get_wifi_info_policy[
6181 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
6182 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
6183 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
6184};
6185
6186
6187/**
6188 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6189 * @wiphy: pointer to wireless wiphy structure.
6190 * @wdev: pointer to wireless_dev structure.
6191 * @data: Pointer to the data to be passed via vendor interface
6192 * @data_len:Length of the data to be passed
6193 *
6194 * This is called when wlan driver needs to send wifi driver related info
6195 * (driver/fw version) to the user space application upon request.
6196 *
6197 * Return: Return the Success or Failure code.
6198 */
6199static int __wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6200 struct wireless_dev *wdev,
6201 const void *data, int data_len)
6202{
6203 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6204 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
6205 tSirVersionString version;
6206 uint32 version_len;
6207 uint8 attr;
6208 int status;
6209 struct sk_buff *reply_skb = NULL;
6210
6211 if (VOS_FTM_MODE == hdd_get_conparam()) {
6212 hddLog(LOGE, FL("Command not allowed in FTM mode"));
6213 return -EINVAL;
6214 }
6215
6216 status = wlan_hdd_validate_context(hdd_ctx);
6217 if (0 != status) {
6218 hddLog(LOGE, FL("HDD context is not valid"));
6219 return -EINVAL;
6220 }
6221
6222 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
6223 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
6224 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
6225 return -EINVAL;
6226 }
6227
6228 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
6229 hddLog(LOG1, FL("Rcvd req for Driver version Driver version is %s"),
6230 QWLAN_VERSIONSTR);
6231 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
6232 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
6233 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
6234 hddLog(LOG1, FL("Rcvd req for FW version FW version is %s"),
6235 hdd_ctx->fw_Version);
6236 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
6237 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
6238 } else {
6239 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
6240 return -EINVAL;
6241 }
6242
6243 version_len = strlen(version);
6244 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
6245 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
6246 if (!reply_skb) {
6247 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6248 return -ENOMEM;
6249 }
6250
6251 if (nla_put(reply_skb, attr, version_len, version)) {
6252 hddLog(LOGE, FL("nla put fail"));
6253 kfree_skb(reply_skb);
6254 return -EINVAL;
6255 }
6256
6257 return cfg80211_vendor_cmd_reply(reply_skb);
6258}
6259
6260/**
6261 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6262 * @wiphy: pointer to wireless wiphy structure.
6263 * @wdev: pointer to wireless_dev structure.
6264 * @data: Pointer to the data to be passed via vendor interface
6265 * @data_len:Length of the data to be passed
6266 * @data_len: Length of the data received
6267 *
6268 * This function is used to enable or disable the collection of packet
6269 * statistics from the firmware
6270 *
6271 * Return: 0 on success and errno on failure
6272 */
6273
6274static int
6275wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6276 struct wireless_dev *wdev,
6277 const void *data, int data_len)
6278
6279
6280{
6281 int ret = 0;
6282
6283 vos_ssr_protect(__func__);
6284 ret = __wlan_hdd_cfg80211_get_wifi_info(wiphy,
6285 wdev, data, data_len);
6286 vos_ssr_unprotect(__func__);
6287
6288 return ret;
6289}
6290
6291
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306292/*
6293 * define short names for the global vendor params
6294 * used by __wlan_hdd_cfg80211_monitor_rssi()
6295 */
6296#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX
6297#define PARAM_REQUEST_ID QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID
6298#define PARAM_CONTROL QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL
6299#define PARAM_MIN_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI
6300#define PARAM_MAX_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI
6301
6302/**---------------------------------------------------------------------------
6303
6304 \brief hdd_rssi_monitor_start_done - callback to be executed when rssi
6305 monitor start is completed successfully.
6306
6307 \return - None
6308
6309 --------------------------------------------------------------------------*/
6310void hdd_rssi_monitor_start_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6311{
6312 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6313
6314 if (NULL == pHddCtx)
6315 {
6316 hddLog(VOS_TRACE_LEVEL_ERROR,
6317 "%s: HDD context is NULL",__func__);
6318 return;
6319 }
6320
6321 if (VOS_STATUS_SUCCESS == status)
6322 {
6323 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor start successful"));
6324 }
6325 else
6326 {
6327 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor start not successful"));
6328 }
6329
6330 return;
6331}
6332
6333/**---------------------------------------------------------------------------
6334
6335 \brief hdd_rssi_monitor_stop_done - callback to be executed when rssi monitor
6336 stop is completed successfully.
6337
6338 \return - None
6339
6340 --------------------------------------------------------------------------*/
6341void hdd_rssi_monitor_stop_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6342{
6343 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6344
6345 if (NULL == pHddCtx)
6346 {
6347 hddLog(VOS_TRACE_LEVEL_ERROR,
6348 "%s: HDD context is NULL",__func__);
6349 return;
6350 }
6351
6352 if (VOS_STATUS_SUCCESS == status)
6353 {
6354 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor stop successful"));
6355 }
6356 else
6357 {
6358 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor stop not successful"));
6359 }
6360
6361 return;
6362}
6363
6364/**
6365 * __wlan_hdd_cfg80211_monitor_rssi() - monitor rssi
6366 * @wiphy: Pointer to wireless phy
6367 * @wdev: Pointer to wireless device
6368 * @data: Pointer to data
6369 * @data_len: Data length
6370 *
6371 * Return: 0 on success, negative errno on failure
6372 */
6373
6374static int
6375__wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy,
6376 struct wireless_dev *wdev,
6377 const void *data,
6378 int data_len)
6379{
6380 struct net_device *dev = wdev->netdev;
6381 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6382 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6383 hdd_station_ctx_t *pHddStaCtx;
6384 struct nlattr *tb[PARAM_MAX + 1];
6385 tpSirRssiMonitorReq pReq;
6386 eHalStatus status;
6387 int ret;
6388 uint32_t control;
6389 static const struct nla_policy policy[PARAM_MAX + 1] = {
6390 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6391 [PARAM_CONTROL] = { .type = NLA_U32 },
6392 [PARAM_MIN_RSSI] = { .type = NLA_S8 },
6393 [PARAM_MAX_RSSI] = { .type = NLA_S8 },
6394 };
6395
6396 ENTER();
6397
6398 ret = wlan_hdd_validate_context(hdd_ctx);
6399 if (0 != ret) {
6400 return -EINVAL;
6401 }
6402
6403 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6404 hddLog(LOGE, FL("Not in Connected state!"));
6405 return -ENOTSUPP;
6406 }
6407
6408 if (nla_parse(tb, PARAM_MAX, data, data_len, policy)) {
6409 hddLog(LOGE, FL("Invalid ATTR"));
6410 return -EINVAL;
6411 }
6412
6413 if (!tb[PARAM_REQUEST_ID]) {
6414 hddLog(LOGE, FL("attr request id failed"));
6415 return -EINVAL;
6416 }
6417
6418 if (!tb[PARAM_CONTROL]) {
6419 hddLog(LOGE, FL("attr control failed"));
6420 return -EINVAL;
6421 }
6422
6423 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6424
6425 pReq = vos_mem_malloc(sizeof(tSirRssiMonitorReq));
6426 if(NULL == pReq)
6427 {
6428 hddLog(LOGE,
6429 FL("vos_mem_alloc failed "));
6430 return eHAL_STATUS_FAILED_ALLOC;
6431 }
6432 vos_mem_set(pReq, sizeof(tSirRssiMonitorReq), 0);
6433
6434 pReq->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]);
6435 pReq->sessionId = pAdapter->sessionId;
6436 pReq->rssiMonitorCbContext = hdd_ctx;
6437 control = nla_get_u32(tb[PARAM_CONTROL]);
6438 vos_mem_copy( &pReq->currentBssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
6439
6440 hddLog(LOG1, FL("Request Id: %u Session_id: %d Control: %d"),
6441 pReq->requestId, pReq->sessionId, control);
6442
6443 if (control == QCA_WLAN_RSSI_MONITORING_START) {
6444 if (!tb[PARAM_MIN_RSSI]) {
6445 hddLog(LOGE, FL("attr min rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306446 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306447 }
6448
6449 if (!tb[PARAM_MAX_RSSI]) {
6450 hddLog(LOGE, FL("attr max rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306451 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306452 }
6453
6454 pReq->minRssi = nla_get_s8(tb[PARAM_MIN_RSSI]);
6455 pReq->maxRssi = nla_get_s8(tb[PARAM_MAX_RSSI]);
6456 pReq->rssiMonitorCallback = hdd_rssi_monitor_start_done;
6457
6458 if (!(pReq->minRssi < pReq->maxRssi)) {
6459 hddLog(LOGW, FL("min_rssi: %d must be less than max_rssi: %d"),
6460 pReq->minRssi, pReq->maxRssi);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306461 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306462 }
6463 hddLog(LOG1, FL("Min_rssi: %d Max_rssi: %d"),
6464 pReq->minRssi, pReq->maxRssi);
6465 status = sme_StartRssiMonitoring(hdd_ctx->hHal, pReq);
6466
6467 }
6468 else if (control == QCA_WLAN_RSSI_MONITORING_STOP) {
6469 pReq->rssiMonitorCallback = hdd_rssi_monitor_stop_done;
6470 status = sme_StopRssiMonitoring(hdd_ctx->hHal, pReq);
6471 }
6472 else {
6473 hddLog(LOGE, FL("Invalid control cmd: %d"), control);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306474 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306475 }
6476
6477 if (!HAL_STATUS_SUCCESS(status)) {
6478 hddLog(LOGE,
6479 FL("sme_set_rssi_monitoring failed(err=%d)"), status);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306480 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306481 }
6482
6483 return 0;
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306484fail:
6485 vos_mem_free(pReq);
6486 return -EINVAL;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306487}
6488
6489/*
6490 * done with short names for the global vendor params
6491 * used by __wlan_hdd_cfg80211_monitor_rssi()
6492 */
6493#undef PARAM_MAX
6494#undef PARAM_CONTROL
6495#undef PARAM_REQUEST_ID
6496#undef PARAM_MAX_RSSI
6497#undef PARAM_MIN_RSSI
6498
6499/**
6500 * wlan_hdd_cfg80211_monitor_rssi() - SSR wrapper to rssi monitoring
6501 * @wiphy: wiphy structure pointer
6502 * @wdev: Wireless device structure pointer
6503 * @data: Pointer to the data received
6504 * @data_len: Length of @data
6505 *
6506 * Return: 0 on success; errno on failure
6507 */
6508static int
6509wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, struct wireless_dev *wdev,
6510 const void *data, int data_len)
6511{
6512 int ret;
6513
6514 vos_ssr_protect(__func__);
6515 ret = __wlan_hdd_cfg80211_monitor_rssi(wiphy, wdev, data, data_len);
6516 vos_ssr_unprotect(__func__);
6517
6518 return ret;
6519}
6520
6521/**
6522 * hdd_rssi_threshold_breached_cb() - rssi breached NL event
6523 * @hddctx: HDD context
6524 * @data: rssi breached event data
6525 *
6526 * This function reads the rssi breached event %data and fill in the skb with
6527 * NL attributes and send up the NL event.
6528 * This callback execute in atomic context and must not invoke any
6529 * blocking calls.
6530 *
6531 * Return: none
6532 */
6533void hdd_rssi_threshold_breached_cb(void *hddctx,
6534 struct rssi_breach_event *data)
6535{
6536 hdd_context_t *pHddCtx = (hdd_context_t *)hddctx;
6537 int status;
6538 struct sk_buff *skb;
6539
6540 ENTER();
6541 status = wlan_hdd_validate_context(pHddCtx);
6542
6543 if (0 != status) {
6544 return;
6545 }
6546
6547 if (!data) {
6548 hddLog(LOGE, FL("data is null"));
6549 return;
6550 }
6551
6552 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
6553#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
6554 NULL,
6555#endif
6556 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
6557 QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX,
6558 GFP_KERNEL);
6559
6560 if (!skb) {
6561 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
6562 return;
6563 }
6564
6565 hddLog(LOG1, "Req Id: %u Current rssi: %d",
6566 data->request_id, data->curr_rssi);
6567 hddLog(LOG1, "Current BSSID: "MAC_ADDRESS_STR,
6568 MAC_ADDR_ARRAY(data->curr_bssid.bytes));
6569
6570 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
6571 data->request_id) ||
6572 nla_put(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID,
6573 sizeof(data->curr_bssid), data->curr_bssid.bytes) ||
6574 nla_put_s8(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI,
6575 data->curr_rssi)) {
6576 hddLog(LOGE, FL("nla put fail"));
6577 goto fail;
6578 }
6579
6580 cfg80211_vendor_event(skb, GFP_KERNEL);
6581 return;
6582
6583fail:
6584 kfree_skb(skb);
6585 return;
6586}
6587
6588
6589
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306590/**
6591 * __wlan_hdd_cfg80211_setband() - set band
6592 * @wiphy: Pointer to wireless phy
6593 * @wdev: Pointer to wireless device
6594 * @data: Pointer to data
6595 * @data_len: Data length
6596 *
6597 * Return: 0 on success, negative errno on failure
6598 */
6599static int
6600__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6601 struct wireless_dev *wdev,
6602 const void *data,
6603 int data_len)
6604{
6605 struct net_device *dev = wdev->netdev;
6606 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6607 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6608 int ret;
6609 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
6610 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
6611
6612 ENTER();
6613
6614 ret = wlan_hdd_validate_context(hdd_ctx);
6615 if (0 != ret) {
6616 hddLog(LOGE, FL("HDD context is not valid"));
6617 return ret;
6618 }
6619
6620 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
6621 policy)) {
6622 hddLog(LOGE, FL("Invalid ATTR"));
6623 return -EINVAL;
6624 }
6625
6626 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
6627 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
6628 return -EINVAL;
6629 }
6630
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306631 hdd_ctx->isSetBandByNL = TRUE;
6632 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306633 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306634 hdd_ctx->isSetBandByNL = FALSE;
6635
6636 EXIT();
6637 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306638}
6639
6640/**
6641 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
6642 * @wiphy: wiphy structure pointer
6643 * @wdev: Wireless device structure pointer
6644 * @data: Pointer to the data received
6645 * @data_len: Length of @data
6646 *
6647 * Return: 0 on success; errno on failure
6648 */
6649static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6650 struct wireless_dev *wdev,
6651 const void *data,
6652 int data_len)
6653{
6654 int ret = 0;
6655
6656 vos_ssr_protect(__func__);
6657 ret = __wlan_hdd_cfg80211_setband(wiphy,
6658 wdev, data, data_len);
6659 vos_ssr_unprotect(__func__);
6660
6661 return ret;
6662}
6663
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05306664#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
6665/**
6666 * hdd_map_req_id_to_pattern_id() - map request id to pattern id
6667 * @hdd_ctx: HDD context
6668 * @request_id: [input] request id
6669 * @pattern_id: [output] pattern id
6670 *
6671 * This function loops through request id to pattern id array
6672 * if the slot is available, store the request id and return pattern id
6673 * if entry exists, return the pattern id
6674 *
6675 * Return: 0 on success and errno on failure
6676 */
6677static int hdd_map_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
6678 uint32_t request_id,
6679 uint8_t *pattern_id)
6680{
6681 uint32_t i;
6682
6683 mutex_lock(&hdd_ctx->op_ctx.op_lock);
6684 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
6685 {
6686 if (hdd_ctx->op_ctx.op_table[i].request_id == 0)
6687 {
6688 hdd_ctx->op_ctx.op_table[i].request_id = request_id;
6689 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6690 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6691 return 0;
6692 } else if (hdd_ctx->op_ctx.op_table[i].request_id ==
6693 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 }
6698 }
6699 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6700 return -EINVAL;
6701}
6702
6703/**
6704 * hdd_unmap_req_id_to_pattern_id() - unmap request id to pattern id
6705 * @hdd_ctx: HDD context
6706 * @request_id: [input] request id
6707 * @pattern_id: [output] pattern id
6708 *
6709 * This function loops through request id to pattern id array
6710 * reset request id to 0 (slot available again) and
6711 * return pattern id
6712 *
6713 * Return: 0 on success and errno on failure
6714 */
6715static int hdd_unmap_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
6716 uint32_t request_id,
6717 uint8_t *pattern_id)
6718{
6719 uint32_t i;
6720
6721 mutex_lock(&hdd_ctx->op_ctx.op_lock);
6722 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
6723 {
6724 if (hdd_ctx->op_ctx.op_table[i].request_id == request_id)
6725 {
6726 hdd_ctx->op_ctx.op_table[i].request_id = 0;
6727 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6728 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6729 return 0;
6730 }
6731 }
6732 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6733 return -EINVAL;
6734}
6735
6736
6737/*
6738 * define short names for the global vendor params
6739 * used by __wlan_hdd_cfg80211_offloaded_packets()
6740 */
6741#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX
6742#define PARAM_REQUEST_ID \
6743 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID
6744#define PARAM_CONTROL \
6745 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL
6746#define PARAM_IP_PACKET \
6747 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA
6748#define PARAM_SRC_MAC_ADDR \
6749 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR
6750#define PARAM_DST_MAC_ADDR \
6751 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR
6752#define PARAM_PERIOD QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD
6753
6754/**
6755 * wlan_hdd_add_tx_ptrn() - add tx pattern
6756 * @adapter: adapter pointer
6757 * @hdd_ctx: hdd context
6758 * @tb: nl attributes
6759 *
6760 * This function reads the NL attributes and forms a AddTxPtrn message
6761 * posts it to SME.
6762 *
6763 */
6764static int
6765wlan_hdd_add_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
6766 struct nlattr **tb)
6767{
6768 struct sSirAddPeriodicTxPtrn *add_req;
6769 eHalStatus status;
6770 uint32_t request_id, ret, len;
6771 uint8_t pattern_id = 0;
6772 v_MACADDR_t dst_addr;
6773 uint16_t eth_type = htons(ETH_P_IP);
6774
6775 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(adapter)))
6776 {
6777 hddLog(LOGE, FL("Not in Connected state!"));
6778 return -ENOTSUPP;
6779 }
6780
6781 add_req = vos_mem_malloc(sizeof(*add_req));
6782 if (!add_req)
6783 {
6784 hddLog(LOGE, FL("memory allocation failed"));
6785 return -ENOMEM;
6786 }
6787
6788 /* Parse and fetch request Id */
6789 if (!tb[PARAM_REQUEST_ID])
6790 {
6791 hddLog(LOGE, FL("attr request id failed"));
6792 goto fail;
6793 }
6794
6795 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
6796 hddLog(LOG1, FL("Request Id: %u"), request_id);
6797 if (request_id == 0)
6798 {
6799 hddLog(LOGE, FL("request_id cannot be zero"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306800 goto fail;
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05306801 }
6802
6803 if (!tb[PARAM_PERIOD])
6804 {
6805 hddLog(LOGE, FL("attr period failed"));
6806 goto fail;
6807 }
6808 add_req->usPtrnIntervalMs = nla_get_u32(tb[PARAM_PERIOD]);
6809 hddLog(LOG1, FL("Period: %u ms"), add_req->usPtrnIntervalMs);
6810 if (add_req->usPtrnIntervalMs == 0)
6811 {
6812 hddLog(LOGE, FL("Invalid interval zero, return failure"));
6813 goto fail;
6814 }
6815
6816 if (!tb[PARAM_SRC_MAC_ADDR])
6817 {
6818 hddLog(LOGE, FL("attr source mac address failed"));
6819 goto fail;
6820 }
6821 nla_memcpy(add_req->macAddress, tb[PARAM_SRC_MAC_ADDR],
6822 VOS_MAC_ADDR_SIZE);
6823 hddLog(LOG1, "input src mac address: "MAC_ADDRESS_STR,
6824 MAC_ADDR_ARRAY(add_req->macAddress));
6825
6826 if (memcmp(add_req->macAddress, adapter->macAddressCurrent.bytes,
6827 VOS_MAC_ADDR_SIZE))
6828 {
6829 hddLog(LOGE,
6830 FL("input src mac address and connected ap bssid are different"));
6831 goto fail;
6832 }
6833
6834 if (!tb[PARAM_DST_MAC_ADDR])
6835 {
6836 hddLog(LOGE, FL("attr dst mac address failed"));
6837 goto fail;
6838 }
6839 nla_memcpy(dst_addr.bytes, tb[PARAM_DST_MAC_ADDR], VOS_MAC_ADDR_SIZE);
6840 hddLog(LOG1, "input dst mac address: "MAC_ADDRESS_STR,
6841 MAC_ADDR_ARRAY(dst_addr.bytes));
6842
6843 if (!tb[PARAM_IP_PACKET])
6844 {
6845 hddLog(LOGE, FL("attr ip packet failed"));
6846 goto fail;
6847 }
6848 add_req->ucPtrnSize = nla_len(tb[PARAM_IP_PACKET]);
6849 hddLog(LOG1, FL("IP packet len: %u"), add_req->ucPtrnSize);
6850
6851 if (add_req->ucPtrnSize < 0 ||
6852 add_req->ucPtrnSize > (PERIODIC_TX_PTRN_MAX_SIZE -
6853 HDD_ETH_HEADER_LEN))
6854 {
6855 hddLog(LOGE, FL("Invalid IP packet len: %d"),
6856 add_req->ucPtrnSize);
6857 goto fail;
6858 }
6859
6860 len = 0;
6861 vos_mem_copy(&add_req->ucPattern[0], dst_addr.bytes, VOS_MAC_ADDR_SIZE);
6862 len += VOS_MAC_ADDR_SIZE;
6863 vos_mem_copy(&add_req->ucPattern[len], add_req->macAddress,
6864 VOS_MAC_ADDR_SIZE);
6865 len += VOS_MAC_ADDR_SIZE;
6866 vos_mem_copy(&add_req->ucPattern[len], &eth_type, 2);
6867 len += 2;
6868
6869 /*
6870 * This is the IP packet, add 14 bytes Ethernet (802.3) header
6871 * ------------------------------------------------------------
6872 * | 14 bytes Ethernet (802.3) header | IP header and payload |
6873 * ------------------------------------------------------------
6874 */
6875 vos_mem_copy(&add_req->ucPattern[len],
6876 nla_data(tb[PARAM_IP_PACKET]),
6877 add_req->ucPtrnSize);
6878 add_req->ucPtrnSize += len;
6879
6880 VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6881 add_req->ucPattern, add_req->ucPtrnSize);
6882
6883 ret = hdd_map_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
6884 if (ret)
6885 {
6886 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
6887 goto fail;
6888 }
6889 add_req->ucPtrnId = pattern_id;
6890 hddLog(LOG1, FL("pattern id: %d"), add_req->ucPtrnId);
6891
6892 status = sme_AddPeriodicTxPtrn(hdd_ctx->hHal, add_req);
6893 if (!HAL_STATUS_SUCCESS(status))
6894 {
6895 hddLog(LOGE,
6896 FL("sme_AddPeriodicTxPtrn failed (err=%d)"), status);
6897 goto fail;
6898 }
6899
6900 EXIT();
6901 vos_mem_free(add_req);
6902 return 0;
6903
6904fail:
6905 vos_mem_free(add_req);
6906 return -EINVAL;
6907}
6908
6909/**
6910 * wlan_hdd_del_tx_ptrn() - delete tx pattern
6911 * @adapter: adapter pointer
6912 * @hdd_ctx: hdd context
6913 * @tb: nl attributes
6914 *
6915 * This function reads the NL attributes and forms a DelTxPtrn message
6916 * posts it to SME.
6917 *
6918 */
6919static int
6920wlan_hdd_del_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
6921 struct nlattr **tb)
6922{
6923 struct sSirDelPeriodicTxPtrn *del_req;
6924 eHalStatus status;
6925 uint32_t request_id, ret;
6926 uint8_t pattern_id = 0;
6927
6928 /* Parse and fetch request Id */
6929 if (!tb[PARAM_REQUEST_ID])
6930 {
6931 hddLog(LOGE, FL("attr request id failed"));
6932 return -EINVAL;
6933 }
6934 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
6935 if (request_id == 0)
6936 {
6937 hddLog(LOGE, FL("request_id cannot be zero"));
6938 return -EINVAL;
6939 }
6940
6941 ret = hdd_unmap_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
6942 if (ret)
6943 {
6944 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
6945 return -EINVAL;
6946 }
6947
6948 del_req = vos_mem_malloc(sizeof(*del_req));
6949 if (!del_req)
6950 {
6951 hddLog(LOGE, FL("memory allocation failed"));
6952 return -ENOMEM;
6953 }
6954
6955 vos_mem_set(del_req, sizeof(*del_req), 0);
6956 vos_mem_copy(del_req->macAddress, adapter->macAddressCurrent.bytes,
6957 VOS_MAC_ADDR_SIZE);
6958 hddLog(LOG1, MAC_ADDRESS_STR, MAC_ADDR_ARRAY(del_req->macAddress));
6959 del_req->ucPatternIdBitmap |= (0x1 << pattern_id);
6960 hddLog(LOG1, FL("Request Id: %u Pattern id: %d, bitmap %04x"),
6961 request_id, pattern_id, del_req->ucPatternIdBitmap);
6962
6963 status = sme_DelPeriodicTxPtrn(hdd_ctx->hHal, del_req);
6964 if (!HAL_STATUS_SUCCESS(status))
6965 {
6966 hddLog(LOGE,
6967 FL("sme_DelPeriodicTxPtrn failed (err=%d)"), status);
6968 goto fail;
6969 }
6970
6971 EXIT();
6972 vos_mem_free(del_req);
6973 return 0;
6974
6975fail:
6976 vos_mem_free(del_req);
6977 return -EINVAL;
6978}
6979
6980
6981/**
6982 * __wlan_hdd_cfg80211_offloaded_packets() - send offloaded packets
6983 * @wiphy: Pointer to wireless phy
6984 * @wdev: Pointer to wireless device
6985 * @data: Pointer to data
6986 * @data_len: Data length
6987 *
6988 * Return: 0 on success, negative errno on failure
6989 */
6990static int
6991__wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
6992 struct wireless_dev *wdev,
6993 const void *data,
6994 int data_len)
6995{
6996 struct net_device *dev = wdev->netdev;
6997 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
6998 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6999 struct nlattr *tb[PARAM_MAX + 1];
7000 uint8_t control;
7001 int ret;
7002 static const struct nla_policy policy[PARAM_MAX + 1] =
7003 {
7004 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
7005 [PARAM_CONTROL] = { .type = NLA_U32 },
7006 [PARAM_SRC_MAC_ADDR] = { .type = NLA_BINARY,
7007 .len = VOS_MAC_ADDR_SIZE },
7008 [PARAM_DST_MAC_ADDR] = { .type = NLA_BINARY,
7009 .len = VOS_MAC_ADDR_SIZE },
7010 [PARAM_PERIOD] = { .type = NLA_U32 },
7011 };
7012
7013 ENTER();
7014
7015 ret = wlan_hdd_validate_context(hdd_ctx);
7016 if (0 != ret)
7017 {
7018 hddLog(LOGE, FL("HDD context is not valid"));
7019 return ret;
7020 }
7021
7022 if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN))
7023 {
7024 hddLog(LOGE,
7025 FL("Periodic Tx Pattern Offload feature is not supported in FW!"));
7026 return -ENOTSUPP;
7027 }
7028
7029 if (nla_parse(tb, PARAM_MAX, data, data_len, policy))
7030 {
7031 hddLog(LOGE, FL("Invalid ATTR"));
7032 return -EINVAL;
7033 }
7034
7035 if (!tb[PARAM_CONTROL])
7036 {
7037 hddLog(LOGE, FL("attr control failed"));
7038 return -EINVAL;
7039 }
7040 control = nla_get_u32(tb[PARAM_CONTROL]);
7041 hddLog(LOG1, FL("Control: %d"), control);
7042
7043 if (control == WLAN_START_OFFLOADED_PACKETS)
7044 return wlan_hdd_add_tx_ptrn(adapter, hdd_ctx, tb);
7045 else if (control == WLAN_STOP_OFFLOADED_PACKETS)
7046 return wlan_hdd_del_tx_ptrn(adapter, hdd_ctx, tb);
7047 else
7048 {
7049 hddLog(LOGE, FL("Invalid control: %d"), control);
7050 return -EINVAL;
7051 }
7052}
7053
7054/*
7055 * done with short names for the global vendor params
7056 * used by __wlan_hdd_cfg80211_offloaded_packets()
7057 */
7058#undef PARAM_MAX
7059#undef PARAM_REQUEST_ID
7060#undef PARAM_CONTROL
7061#undef PARAM_IP_PACKET
7062#undef PARAM_SRC_MAC_ADDR
7063#undef PARAM_DST_MAC_ADDR
7064#undef PARAM_PERIOD
7065
7066/**
7067 * wlan_hdd_cfg80211_offloaded_packets() - Wrapper to offload packets
7068 * @wiphy: wiphy structure pointer
7069 * @wdev: Wireless device structure pointer
7070 * @data: Pointer to the data received
7071 * @data_len: Length of @data
7072 *
7073 * Return: 0 on success; errno on failure
7074 */
7075static int wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7076 struct wireless_dev *wdev,
7077 const void *data,
7078 int data_len)
7079{
7080 int ret = 0;
7081
7082 vos_ssr_protect(__func__);
7083 ret = __wlan_hdd_cfg80211_offloaded_packets(wiphy,
7084 wdev, data, data_len);
7085 vos_ssr_unprotect(__func__);
7086
7087 return ret;
7088}
7089#endif
7090
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307091static const struct
7092nla_policy
7093qca_wlan_vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05307094 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
7095 .type = NLA_BINARY,
7096 .len = HDD_MAC_ADDR_LEN},
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307097};
7098
7099/**
7100 * wlan_hdd_cfg80211_get_link_properties() - This function is used to
7101 * get link properties like nss, rate flags and operating frequency for
7102 * the connection with the given peer.
7103 * @wiphy: WIPHY structure pointer
7104 * @wdev: Wireless device structure pointer
7105 * @data: Pointer to the data received
7106 * @data_len: Length of the data received
7107 *
7108 * This function return the above link properties on success.
7109 *
7110 * Return: 0 on success and errno on failure
7111 */
7112static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
7113 struct wireless_dev *wdev,
7114 const void *data,
7115 int data_len)
7116{
7117 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7118 struct net_device *dev = wdev->netdev;
7119 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7120 hdd_station_ctx_t *hdd_sta_ctx;
7121 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX+1];
7122 uint8_t peer_mac[VOS_MAC_ADDR_SIZE];
7123 uint32_t sta_id;
7124 struct sk_buff *reply_skb;
7125 uint32_t rate_flags = 0;
7126 uint8_t nss;
7127 uint8_t final_rate_flags = 0;
7128 uint32_t freq;
7129 v_CONTEXT_t pVosContext = NULL;
7130 ptSapContext pSapCtx = NULL;
7131
7132 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
7133 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
7134 return -EINVAL;
7135 }
7136
7137 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7138 qca_wlan_vendor_attr_policy)) {
7139 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid attribute"));
7140 return -EINVAL;
7141 }
7142
7143 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
7144 hddLog(VOS_TRACE_LEVEL_ERROR,
7145 FL("Attribute peerMac not provided for mode=%d"),
7146 adapter->device_mode);
7147 return -EINVAL;
7148 }
7149
Ashish Kumar Dhanotiyaddaf0482017-06-23 15:22:42 +05307150 if (nla_len(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) < sizeof(peer_mac)) {
7151 hddLog(VOS_TRACE_LEVEL_ERROR,
7152 FL("Attribute peerMac is invalid=%d"),
7153 adapter->device_mode);
7154 return -EINVAL;
7155 }
7156
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307157 memcpy(peer_mac, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
7158 sizeof(peer_mac));
7159 hddLog(VOS_TRACE_LEVEL_INFO,
7160 FL("peerMac="MAC_ADDRESS_STR" for device_mode:%d"),
7161 MAC_ADDR_ARRAY(peer_mac), adapter->device_mode);
7162
7163 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
7164 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
7165 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
7166 if ((hdd_sta_ctx->conn_info.connState !=
7167 eConnectionState_Associated) ||
7168 !vos_mem_compare(hdd_sta_ctx->conn_info.bssId, peer_mac,
7169 VOS_MAC_ADDRESS_LEN)) {
7170 hddLog(VOS_TRACE_LEVEL_ERROR,
7171 FL("Not Associated to mac "MAC_ADDRESS_STR),
7172 MAC_ADDR_ARRAY(peer_mac));
7173 return -EINVAL;
7174 }
7175
7176 nss = 1; //pronto supports only one spatial stream
7177 freq = vos_chan_to_freq(
7178 hdd_sta_ctx->conn_info.operationChannel);
7179 rate_flags = hdd_sta_ctx->conn_info.rate_flags;
7180
7181 } else if (adapter->device_mode == WLAN_HDD_P2P_GO ||
7182 adapter->device_mode == WLAN_HDD_SOFTAP) {
7183
7184 pVosContext = ( WLAN_HDD_GET_CTX(adapter))->pvosContext;
7185 pSapCtx = VOS_GET_SAP_CB(pVosContext);
7186 if(pSapCtx == NULL){
7187 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7188 FL("psapCtx is NULL"));
7189 return -ENOENT;
7190 }
7191
7192
7193 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
7194 if (pSapCtx->aStaInfo[sta_id].isUsed &&
7195 !vos_is_macaddr_broadcast(
7196 &pSapCtx->aStaInfo[sta_id].macAddrSTA) &&
7197 vos_mem_compare(
7198 &pSapCtx->aStaInfo[sta_id].macAddrSTA,
7199 peer_mac, VOS_MAC_ADDRESS_LEN))
7200 break;
7201 }
7202
7203 if (WLAN_MAX_STA_COUNT == sta_id) {
7204 hddLog(VOS_TRACE_LEVEL_ERROR,
7205 FL("No active peer with mac="MAC_ADDRESS_STR),
7206 MAC_ADDR_ARRAY(peer_mac));
7207 return -EINVAL;
7208 }
7209
7210 nss = 1; //pronto supports only one spatial stream
7211 freq = vos_chan_to_freq(
7212 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operatingChannel);
7213 rate_flags = pSapCtx->aStaInfo[sta_id].rate_flags;
7214 } else {
7215 hddLog(VOS_TRACE_LEVEL_ERROR,
7216 FL("Not Associated! with mac"MAC_ADDRESS_STR),
7217 MAC_ADDR_ARRAY(peer_mac));
7218 return -EINVAL;
7219 }
7220
7221 if (!(rate_flags & eHAL_TX_RATE_LEGACY)) {
7222 if (rate_flags & eHAL_TX_RATE_VHT80) {
7223 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7224 final_rate_flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
7225 } else if (rate_flags & eHAL_TX_RATE_VHT40) {
7226 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7227 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7228 } else if (rate_flags & eHAL_TX_RATE_VHT20) {
7229 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7230 } else if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40)) {
7231 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7232 if (rate_flags & eHAL_TX_RATE_HT40)
7233 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7234 }
7235
7236 if (rate_flags & eHAL_TX_RATE_SGI) {
7237 if (!(final_rate_flags & RATE_INFO_FLAGS_VHT_MCS))
7238 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7239 final_rate_flags |= RATE_INFO_FLAGS_SHORT_GI;
7240 }
7241 }
7242
7243 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7244 sizeof(u8) + sizeof(u8) + sizeof(u32) + NLMSG_HDRLEN);
7245
7246 if (NULL == reply_skb) {
7247 hddLog(VOS_TRACE_LEVEL_ERROR,
7248 FL("getLinkProperties: skb alloc failed"));
7249 return -EINVAL;
7250 }
7251
7252 if (nla_put_u8(reply_skb,
7253 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS,
7254 nss) ||
7255 nla_put_u8(reply_skb,
7256 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS,
7257 final_rate_flags) ||
7258 nla_put_u32(reply_skb,
7259 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ,
7260 freq)) {
7261 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_put failed"));
7262 kfree_skb(reply_skb);
7263 return -EINVAL;
7264 }
7265
7266 return cfg80211_vendor_cmd_reply(reply_skb);
7267}
7268
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307269#define BEACON_MISS_THRESH_2_4 \
7270 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24
7271#define BEACON_MISS_THRESH_5_0 \
7272 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307273#define PARAM_WIFICONFIG_MAX QCA_WLAN_VENDOR_ATTR_CONFIG_MAX
7274#define PARAM_MODULATED_DTIM QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM
7275#define PARAM_STATS_AVG_FACTOR QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR
7276#define PARAM_GUARD_TIME QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307277#define PARAM_BCNMISS_PENALTY_PARAM_COUNT \
7278 QCA_WLAN_VENDOR_ATTR_CONFIG_PENALIZE_AFTER_NCONS_BEACON_MISS
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307279
7280/**
7281 * __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7282 * vendor command
7283 *
7284 * @wiphy: wiphy device pointer
7285 * @wdev: wireless device pointer
7286 * @data: Vendor command data buffer
7287 * @data_len: Buffer length
7288 *
7289 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7290 *
7291 * Return: EOK or other error codes.
7292 */
7293
7294static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7295 struct wireless_dev *wdev,
7296 const void *data,
7297 int data_len)
7298{
7299 struct net_device *dev = wdev->netdev;
7300 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7301 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7302 hdd_station_ctx_t *pHddStaCtx;
7303 struct nlattr *tb[PARAM_WIFICONFIG_MAX + 1];
7304 tpSetWifiConfigParams pReq;
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307305 tModifyRoamParamsReqParams modifyRoamParamsReq;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307306 eHalStatus status;
7307 int ret_val;
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307308 uint8_t hb_thresh_val;
7309
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307310 static const struct nla_policy policy[PARAM_WIFICONFIG_MAX + 1] = {
7311 [PARAM_STATS_AVG_FACTOR] = { .type = NLA_U16 },
7312 [PARAM_MODULATED_DTIM] = { .type = NLA_U32 },
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307313 [PARAM_GUARD_TIME] = { .type = NLA_U32},
7314 [PARAM_BCNMISS_PENALTY_PARAM_COUNT] =
7315 { .type = NLA_U32},
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307316 [BEACON_MISS_THRESH_2_4] = { .type = NLA_U8 },
7317 [BEACON_MISS_THRESH_5_0] = { .type = NLA_U8 },
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307318 };
7319
7320 ENTER();
7321
7322 if (VOS_FTM_MODE == hdd_get_conparam()) {
7323 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7324 return -EINVAL;
7325 }
7326
7327 ret_val = wlan_hdd_validate_context(pHddCtx);
7328 if (ret_val) {
7329 return ret_val;
7330 }
7331
7332 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7333
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307334 if (nla_parse(tb, PARAM_WIFICONFIG_MAX, data, data_len, policy)) {
7335 hddLog(LOGE, FL("Invalid ATTR"));
7336 return -EINVAL;
7337 }
7338
7339 /* check the Wifi Capability */
7340 if ( (TRUE != pHddCtx->cfg_ini->fEnableWifiConfig) &&
7341 (TRUE != sme_IsFeatureSupportedByFW(WIFI_CONFIG)))
7342 {
7343 hddLog(VOS_TRACE_LEVEL_ERROR,
7344 FL("WIFICONFIG not supported by Firmware"));
7345 return -EINVAL;
7346 }
7347
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307348 if (tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]) {
7349 modifyRoamParamsReq.param = WIFI_CONFIG_SET_BCNMISS_PENALTY_COUNT;
7350 modifyRoamParamsReq.value =
7351 nla_get_u32(tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]);
7352
7353 if (eHAL_STATUS_SUCCESS !=
7354 sme_setBcnMissPenaltyCount(pHddCtx->hHal,&modifyRoamParamsReq))
7355 {
7356 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed", __func__);
7357 ret_val = -EINVAL;
7358 }
7359 return ret_val;
7360 }
7361
7362 /* Moved this down in order to provide provision to set beacon
7363 * miss penalty count irrespective of connection state.
7364 */
7365 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
7366 hddLog(LOGE, FL("Not in Connected state!"));
7367 return -ENOTSUPP;
7368 }
7369
7370 pReq = vos_mem_malloc(sizeof(tSetWifiConfigParams));
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307371
7372 if (!pReq) {
7373 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7374 "%s: Not able to allocate memory for tSetWifiConfigParams",
7375 __func__);
7376 return eHAL_STATUS_E_MALLOC_FAILED;
7377 }
7378
7379 vos_mem_set(pReq, sizeof(tSetWifiConfigParams), 0);
7380
7381 pReq->sessionId = pAdapter->sessionId;
7382 vos_mem_copy( &pReq->bssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
7383
7384 if (tb[PARAM_MODULATED_DTIM]) {
7385 pReq->paramValue = nla_get_u32(
7386 tb[PARAM_MODULATED_DTIM]);
7387 hddLog(LOG1, FL("Modulated DTIM: pReq->paramValue:%d "),
7388 pReq->paramValue);
Arun Khandavalli876886f2015-11-23 11:42:27 +05307389 pHddCtx->cfg_ini->enableDynamicDTIM = pReq->paramValue;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307390 hdd_set_pwrparams(pHddCtx);
7391 if (BMPS == pmcGetPmcState(pHddCtx->hHal)) {
7392 hddLog( LOG1, FL("WifiConfig: Requesting FullPower!"));
7393
7394 sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
7395 iw_full_power_cbfn, pAdapter,
7396 eSME_FULL_PWR_NEEDED_BY_HDD);
7397 }
7398 else
7399 {
7400 hddLog( LOG1, FL("WifiConfig Not in BMPS state"));
7401 }
7402 }
7403
7404 if (tb[PARAM_STATS_AVG_FACTOR]) {
7405 pReq->paramType = WIFI_CONFIG_SET_AVG_STATS_FACTOR;
7406 pReq->paramValue = nla_get_u16(
7407 tb[PARAM_STATS_AVG_FACTOR]);
7408 hddLog(LOG1, FL("AVG_STATS_FACTOR pReq->paramType:%d,pReq->paramValue:%d "),
7409 pReq->paramType, pReq->paramValue);
7410 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7411
7412 if (eHAL_STATUS_SUCCESS != status)
7413 {
7414 vos_mem_free(pReq);
7415 pReq = NULL;
7416 ret_val = -EPERM;
7417 return ret_val;
7418 }
7419 }
7420
7421
7422 if (tb[PARAM_GUARD_TIME]) {
7423 pReq->paramType = WIFI_CONFIG_SET_GUARD_TIME;
7424 pReq->paramValue = nla_get_u32(
7425 tb[PARAM_GUARD_TIME]);
7426 hddLog(LOG1, FL("GUARD_TIME pReq->paramType:%d,pReq->paramValue:%d "),
7427 pReq->paramType, pReq->paramValue);
7428 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7429
7430 if (eHAL_STATUS_SUCCESS != status)
7431 {
7432 vos_mem_free(pReq);
7433 pReq = NULL;
7434 ret_val = -EPERM;
7435 return ret_val;
7436 }
7437
7438 }
7439
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307440 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]) {
7441 hb_thresh_val = nla_get_u8(
7442 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]);
7443
7444 hddLog(LOG1, "WLAN set heartbeat threshold for 2.4Ghz %d",
7445 hb_thresh_val);
7446 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7447 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
7448 NULL, eANI_BOOLEAN_FALSE);
7449
7450 status = sme_update_hb_threshold(
7451 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
7452 WNI_CFG_HEART_BEAT_THRESHOLD,
7453 hb_thresh_val, eCSR_BAND_24);
7454 if (eHAL_STATUS_SUCCESS != status) {
7455 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
7456 vos_mem_free(pReq);
7457 pReq = NULL;
7458 return -EPERM;
7459 }
7460 }
7461
7462 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]) {
7463 hb_thresh_val = nla_get_u8(
7464 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]);
7465
7466 hddLog(LOG1, "WLAN set heartbeat threshold for 5Ghz %d",
7467 hb_thresh_val);
7468 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7469 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
7470 NULL, eANI_BOOLEAN_FALSE);
7471
7472 status = sme_update_hb_threshold(
7473 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
7474 WNI_CFG_HEART_BEAT_THRESHOLD,
7475 hb_thresh_val, eCSR_BAND_5G);
7476 if (eHAL_STATUS_SUCCESS != status) {
7477 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
7478 vos_mem_free(pReq);
7479 pReq = NULL;
7480 return -EPERM;
7481 }
7482 }
7483
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307484 EXIT();
7485 return ret_val;
7486}
7487
7488/**
7489 * wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7490 * vendor command
7491 *
7492 * @wiphy: wiphy device pointer
7493 * @wdev: wireless device pointer
7494 * @data: Vendor command data buffer
7495 * @data_len: Buffer length
7496 *
7497 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7498 *
7499 * Return: EOK or other error codes.
7500 */
7501static int wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7502 struct wireless_dev *wdev,
7503 const void *data,
7504 int data_len)
7505{
7506 int ret;
7507
7508 vos_ssr_protect(__func__);
7509 ret = __wlan_hdd_cfg80211_wifi_configuration_set(wiphy, wdev,
7510 data, data_len);
7511 vos_ssr_unprotect(__func__);
7512
7513 return ret;
7514}
Anurag Chouhan6ee81542017-02-09 18:09:27 +05307515
7516/*
7517 * define short names for the global vendor params
7518 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
7519 */
7520#define STATS_SET_INVALID \
7521 QCA_ATTR_NUD_STATS_SET_INVALID
7522#define STATS_SET_START \
7523 QCA_ATTR_NUD_STATS_SET_START
7524#define STATS_GW_IPV4 \
7525 QCA_ATTR_NUD_STATS_GW_IPV4
7526#define STATS_SET_MAX \
7527 QCA_ATTR_NUD_STATS_SET_MAX
7528
7529const struct nla_policy
7530qca_wlan_vendor_set_nud_stats[STATS_SET_MAX +1] =
7531{
7532 [STATS_SET_START] = {.type = NLA_FLAG },
7533 [STATS_GW_IPV4] = {.type = NLA_U32 },
7534};
7535
7536/**
7537 * hdd_set_nud_stats_cb() - hdd callback api to get status
7538 * @data: pointer to adapter
7539 * @rsp: status
7540 *
7541 * Return: None
7542 */
7543static void hdd_set_nud_stats_cb(void *data, VOS_STATUS rsp)
7544{
7545
7546 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
7547
7548 if (NULL == adapter)
7549 return;
7550
7551 if (VOS_STATUS_SUCCESS == rsp) {
7552 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7553 "%s success received STATS_SET_START", __func__);
7554 } else {
7555 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7556 "%s STATS_SET_START Failed!!", __func__);
7557 }
7558 return;
7559}
7560
7561/**
7562 * __wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
7563 * @wiphy: pointer to wireless wiphy structure.
7564 * @wdev: pointer to wireless_dev structure.
7565 * @data: pointer to apfind configuration data.
7566 * @data_len: the length in byte of apfind data.
7567 *
7568 * This is called when wlan driver needs to send arp stats to
7569 * firmware.
7570 *
7571 * Return: An error code or 0 on success.
7572 */
7573static int __wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
7574 struct wireless_dev *wdev,
7575 const void *data, int data_len)
7576{
7577 struct nlattr *tb[STATS_SET_MAX + 1];
7578 struct net_device *dev = wdev->netdev;
7579 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7580 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05307581 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
Anurag Chouhan6ee81542017-02-09 18:09:27 +05307582 setArpStatsParams arp_stats_params;
7583 int err = 0;
7584
7585 ENTER();
7586
7587 err = wlan_hdd_validate_context(hdd_ctx);
7588 if (0 != err)
7589 return err;
7590
7591 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
7592 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7593 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
7594 return -EINVAL;
7595 }
7596
7597 err = nla_parse(tb, STATS_SET_MAX, data, data_len,
7598 qca_wlan_vendor_set_nud_stats);
7599 if (err)
7600 {
7601 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7602 "%s STATS_SET_START ATTR", __func__);
7603 return err;
7604 }
7605
7606 if (tb[STATS_SET_START])
7607 {
7608 if (!tb[STATS_GW_IPV4]) {
7609 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7610 "%s STATS_SET_START CMD", __func__);
7611 return -EINVAL;
7612 }
7613 arp_stats_params.flag = true;
7614 arp_stats_params.ip_addr = nla_get_u32(tb[STATS_GW_IPV4]);
7615 } else {
7616 arp_stats_params.flag = false;
7617 }
Anurag Chouhan630c5562017-03-23 14:51:47 +05307618 if (arp_stats_params.flag)
Anurag Chouhan6ee81542017-02-09 18:09:27 +05307619 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7620 "%s STATS_SET_START Cleared!!", __func__);
Anurag Chouhan630c5562017-03-23 14:51:47 +05307621 vos_mem_zero(&adapter->hdd_stats.hddArpStats,
7622 sizeof(adapter->hdd_stats.hddArpStats));
Anurag Chouhan6ee81542017-02-09 18:09:27 +05307623
7624 arp_stats_params.pkt_type = 1; // ARP packet type
7625
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05307626 if (arp_stats_params.flag) {
7627 hdd_ctx->track_arp_ip = arp_stats_params.ip_addr;
7628 WLANTL_SetARPFWDatapath(pVosContext, true);
7629 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7630 "%s Set FW in data path for ARP with tgt IP :%d",
7631 __func__, hdd_ctx->track_arp_ip);
7632 }
7633 else {
7634 WLANTL_SetARPFWDatapath(pVosContext, false);
7635 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7636 "%s Remove FW from data path", __func__);
7637 }
7638
Anurag Chouhan6ee81542017-02-09 18:09:27 +05307639 arp_stats_params.rsp_cb_fn = hdd_set_nud_stats_cb;
7640 arp_stats_params.data_ctx = adapter;
7641
7642 if (eHAL_STATUS_SUCCESS !=
7643 sme_set_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
7644 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7645 "%s STATS_SET_START CMD Failed!!", __func__);
7646 return -EINVAL;
7647 }
7648
7649 EXIT();
7650
7651 return err;
7652}
7653
7654/**
7655 * wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
7656 * @wiphy: pointer to wireless wiphy structure.
7657 * @wdev: pointer to wireless_dev structure.
7658 * @data: pointer to apfind configuration data.
7659 * @data_len: the length in byte of apfind data.
7660 *
7661 * This is called when wlan driver needs to send arp stats to
7662 * firmware.
7663 *
7664 * Return: An error code or 0 on success.
7665 */
7666static int wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
7667 struct wireless_dev *wdev,
7668 const void *data, int data_len)
7669{
7670 int ret;
7671
7672 vos_ssr_protect(__func__);
7673 ret = __wlan_hdd_cfg80211_set_nud_stats(wiphy, wdev, data, data_len);
7674 vos_ssr_unprotect(__func__);
7675
7676 return ret;
7677}
7678#undef STATS_SET_INVALID
7679#undef STATS_SET_START
7680#undef STATS_GW_IPV4
7681#undef STATS_SET_MAX
7682
7683/*
7684 * define short names for the global vendor params
7685 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
7686 */
7687#define STATS_GET_INVALID \
7688 QCA_ATTR_NUD_STATS_SET_INVALID
7689#define COUNT_FROM_NETDEV \
7690 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
7691#define COUNT_TO_LOWER_MAC \
7692 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
7693#define RX_COUNT_BY_LOWER_MAC \
7694 QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
7695#define COUNT_TX_SUCCESS \
7696 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
7697#define RSP_RX_COUNT_BY_LOWER_MAC \
7698 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
7699#define RSP_RX_COUNT_BY_UPPER_MAC \
7700 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
7701#define RSP_COUNT_TO_NETDEV \
7702 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
7703#define RSP_COUNT_OUT_OF_ORDER_DROP \
7704 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
7705#define AP_LINK_ACTIVE \
7706 QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
7707#define AP_LINK_DAD \
7708 QCA_ATTR_NUD_STATS_AP_LINK_DAD
7709#define STATS_GET_MAX \
7710 QCA_ATTR_NUD_STATS_GET_MAX
7711
7712const struct nla_policy
7713qca_wlan_vendor_get_nud_stats[STATS_GET_MAX +1] =
7714{
7715 [COUNT_FROM_NETDEV] = {.type = NLA_U16 },
7716 [COUNT_TO_LOWER_MAC] = {.type = NLA_U16 },
7717 [RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
7718 [COUNT_TX_SUCCESS] = {.type = NLA_U16 },
7719 [RSP_RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
7720 [RSP_RX_COUNT_BY_UPPER_MAC] = {.type = NLA_U16 },
7721 [RSP_COUNT_TO_NETDEV] = {.type = NLA_U16 },
7722 [RSP_COUNT_OUT_OF_ORDER_DROP] = {.type = NLA_U16 },
7723 [AP_LINK_ACTIVE] = {.type = NLA_FLAG },
7724 [AP_LINK_DAD] = {.type = NLA_FLAG },
7725};
7726
7727static void hdd_get_nud_stats_cb(void *data, rsp_stats *rsp)
7728{
7729
7730 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
7731 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
7732 struct hdd_nud_stats_context *context;
7733 int status;
7734
7735 ENTER();
7736
7737 if (NULL == adapter)
7738 return;
7739
7740 status = wlan_hdd_validate_context(hdd_ctx);
7741 if (0 != status) {
7742 return;
7743 }
7744
7745 if (!rsp) {
7746 hddLog(LOGE, FL("data is null"));
7747 return;
7748 }
7749
7750 adapter->hdd_stats.hddArpStats.tx_fw_cnt = rsp->tx_fw_cnt;
7751 adapter->hdd_stats.hddArpStats.rx_fw_cnt = rsp->rx_fw_cnt;
7752 adapter->hdd_stats.hddArpStats.tx_ack_cnt = rsp->tx_ack_cnt;
7753 adapter->dad |= rsp->dad;
7754
7755 spin_lock(&hdd_context_lock);
7756 context = &hdd_ctx->nud_stats_context;
7757 complete(&context->response_event);
7758 spin_unlock(&hdd_context_lock);
7759
7760 return;
7761}
7762static int __wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
7763 struct wireless_dev *wdev,
7764 const void *data, int data_len)
7765{
7766 int err = 0;
7767 unsigned long rc;
7768 struct hdd_nud_stats_context *context;
7769 struct net_device *dev = wdev->netdev;
7770 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7771 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7772 getArpStatsParams arp_stats_params;
7773 struct sk_buff *skb;
7774
7775 ENTER();
7776
7777 err = wlan_hdd_validate_context(hdd_ctx);
7778 if (0 != err)
7779 return err;
7780
7781 arp_stats_params.pkt_type = WLAN_NUD_STATS_ARP_PKT_TYPE;
7782 arp_stats_params.get_rsp_cb_fn = hdd_get_nud_stats_cb;
7783 arp_stats_params.data_ctx = adapter;
7784
7785 spin_lock(&hdd_context_lock);
7786 context = &hdd_ctx->nud_stats_context;
7787 INIT_COMPLETION(context->response_event);
7788 spin_unlock(&hdd_context_lock);
7789
7790 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
7791 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7792 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
7793 return -EINVAL;
7794 }
7795
7796 if (eHAL_STATUS_SUCCESS !=
7797 sme_get_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
7798 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7799 "%s STATS_SET_START CMD Failed!!", __func__);
7800 return -EINVAL;
7801 }
7802
7803 rc = wait_for_completion_timeout(&context->response_event,
7804 msecs_to_jiffies(WLAN_WAIT_TIME_NUD_STATS));
7805 if (!rc)
7806 {
7807 hddLog(LOGE,
7808 FL("Target response timed out request "));
7809 return -ETIMEDOUT;
7810 }
7811
7812 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7813 WLAN_NUD_STATS_LEN);
7814 if (!skb)
7815 {
7816 hddLog(VOS_TRACE_LEVEL_ERROR,
7817 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
7818 __func__);
7819 return -ENOMEM;
7820 }
7821
7822 if (nla_put_u16(skb, COUNT_FROM_NETDEV,
7823 adapter->hdd_stats.hddArpStats.txCount) ||
7824 nla_put_u16(skb, COUNT_TO_LOWER_MAC,
7825 adapter->hdd_stats.hddArpStats.tx_host_fw_sent) ||
7826 nla_put_u16(skb, RX_COUNT_BY_LOWER_MAC,
7827 adapter->hdd_stats.hddArpStats.tx_fw_cnt) ||
7828 nla_put_u16(skb, COUNT_TX_SUCCESS,
7829 adapter->hdd_stats.hddArpStats.tx_ack_cnt) ||
7830 nla_put_u16(skb, RSP_RX_COUNT_BY_LOWER_MAC,
7831 adapter->hdd_stats.hddArpStats.rx_fw_cnt) ||
7832 nla_put_u16(skb, RSP_RX_COUNT_BY_UPPER_MAC,
7833 adapter->hdd_stats.hddArpStats.rxCount) ||
7834 nla_put_u16(skb, RSP_COUNT_TO_NETDEV,
7835 adapter->hdd_stats.hddArpStats.rxDelivered) ||
7836 nla_put_u16(skb, RSP_COUNT_OUT_OF_ORDER_DROP,
7837 adapter->hdd_stats.hddArpStats.rx_host_drop_reorder)) {
7838 hddLog(LOGE, FL("nla put fail"));
7839 kfree_skb(skb);
7840 return -EINVAL;
7841 }
7842 if (adapter->con_status)
7843 nla_put_flag(skb, AP_LINK_ACTIVE);
7844 if (adapter->dad)
7845 nla_put_flag(skb, AP_LINK_DAD);
7846
7847 cfg80211_vendor_cmd_reply(skb);
7848 return err;
7849}
7850
7851static int wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
7852 struct wireless_dev *wdev,
7853 const void *data, int data_len)
7854{
7855 int ret;
7856
7857 vos_ssr_protect(__func__);
7858 ret = __wlan_hdd_cfg80211_get_nud_stats(wiphy, wdev, data, data_len);
7859 vos_ssr_unprotect(__func__);
7860
7861 return ret;
7862}
7863
7864#undef QCA_ATTR_NUD_STATS_SET_INVALID
7865#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
7866#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
7867#undef QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
7868#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
7869#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
7870#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
7871#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
7872#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
7873#undef QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
7874#undef QCA_ATTR_NUD_STATS_GET_MAX
7875
7876
7877
Kapil Guptaee33bf12016-12-20 18:27:37 +05307878#ifdef WLAN_FEATURE_APFIND
7879/**
7880 * __wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
7881 * @wiphy: pointer to wireless wiphy structure.
7882 * @wdev: pointer to wireless_dev structure.
7883 * @data: pointer to apfind configuration data.
7884 * @data_len: the length in byte of apfind data.
7885 *
7886 * This is called when wlan driver needs to send APFIND configurations to
7887 * firmware.
7888 *
7889 * Return: An error code or 0 on success.
7890 */
7891static int __wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
7892 struct wireless_dev *wdev,
7893 const void *data, int data_len)
7894{
7895 struct sme_ap_find_request_req apfind_req;
7896 VOS_STATUS status;
7897 int ret_val;
7898 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7899
7900 ENTER();
7901
7902 ret_val = wlan_hdd_validate_context(hdd_ctx);
7903 if (ret_val)
7904 return ret_val;
7905
7906 if (VOS_FTM_MODE == hdd_get_conparam()) {
7907 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7908 return -EPERM;
7909 }
7910
7911 apfind_req.request_data_len = data_len;
7912 apfind_req.request_data = data;
7913
7914 status = sme_apfind_set_cmd(&apfind_req);
7915 if (VOS_STATUS_SUCCESS != status) {
7916 ret_val = -EIO;
7917 }
7918 return ret_val;
7919}
7920
7921/**
7922 * wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
7923 * @wiphy: pointer to wireless wiphy structure.
7924 * @wdev: pointer to wireless_dev structure.
7925 * @data: pointer to apfind configuration data.
7926 * @data_len: the length in byte of apfind data.
7927 *
7928 * This is called when wlan driver needs to send APFIND configurations to
7929 * firmware.
7930 *
7931 * Return: An error code or 0 on success.
7932 */
7933static int wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
7934 struct wireless_dev *wdev,
7935 const void *data, int data_len)
7936{
7937 int ret;
7938
7939 vos_ssr_protect(__func__);
7940 ret = __wlan_hdd_cfg80211_apfind_cmd(wiphy, wdev, data, data_len);
7941 vos_ssr_unprotect(__func__);
7942
7943 return ret;
7944}
7945#endif /* WLAN_FEATURE_APFIND */
Sunil Duttc69bccb2014-05-26 21:30:20 +05307946const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
7947{
Mukul Sharma2a271632014-10-13 14:59:01 +05307948 {
7949 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7950 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
7951 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7952 WIPHY_VENDOR_CMD_NEED_NETDEV |
7953 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307954 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05307955 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05307956
7957 {
7958 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7959 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
7960 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7961 WIPHY_VENDOR_CMD_NEED_NETDEV |
7962 WIPHY_VENDOR_CMD_NEED_RUNNING,
7963 .doit = wlan_hdd_cfg80211_nan_request
7964 },
7965
Sunil Duttc69bccb2014-05-26 21:30:20 +05307966#ifdef WLAN_FEATURE_LINK_LAYER_STATS
7967 {
7968 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7969 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
7970 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7971 WIPHY_VENDOR_CMD_NEED_NETDEV |
7972 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307973 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05307974 },
7975
7976 {
7977 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7978 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
7979 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7980 WIPHY_VENDOR_CMD_NEED_NETDEV |
7981 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307982 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05307983 },
7984
7985 {
7986 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7987 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
7988 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7989 WIPHY_VENDOR_CMD_NEED_NETDEV |
7990 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307991 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05307992 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05307993#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05307994#ifdef WLAN_FEATURE_EXTSCAN
7995 {
7996 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7997 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
7998 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7999 WIPHY_VENDOR_CMD_NEED_NETDEV |
8000 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308001 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05308002 },
8003 {
8004 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8005 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
8006 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8007 WIPHY_VENDOR_CMD_NEED_NETDEV |
8008 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308009 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05308010 },
8011 {
8012 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8013 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
8014 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8015 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308016 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05308017 },
8018 {
8019 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8020 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
8021 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8022 WIPHY_VENDOR_CMD_NEED_NETDEV |
8023 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308024 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05308025 },
8026 {
8027 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8028 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
8029 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8030 WIPHY_VENDOR_CMD_NEED_NETDEV |
8031 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308032 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05308033 },
8034 {
8035 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8036 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
8037 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8038 WIPHY_VENDOR_CMD_NEED_NETDEV |
8039 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308040 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308041 },
8042 {
8043 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8044 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
8045 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8046 WIPHY_VENDOR_CMD_NEED_NETDEV |
8047 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308048 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308049 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308050#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308051/*EXT TDLS*/
8052 {
8053 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8054 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
8055 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8056 WIPHY_VENDOR_CMD_NEED_NETDEV |
8057 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308058 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05308059 },
8060 {
8061 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8062 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
8063 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8064 WIPHY_VENDOR_CMD_NEED_NETDEV |
8065 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308066 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05308067 },
8068 {
8069 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8070 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
8071 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8072 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308073 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05308074 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05308075 {
8076 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8077 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
8078 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8079 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308080 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05308081 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05308082 {
8083 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8084 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
8085 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8086 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308087 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05308088 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308089 {
8090 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8091 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
8092 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8093 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308094 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308095 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308096 {
8097 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8098 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
8099 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8100 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308101 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308102 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308103 {
8104 .info.vendor_id = QCA_NL80211_VENDOR_ID,
c_manjeecfd1efb2015-09-25 19:32:34 +05308105 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
8106 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8107 WIPHY_VENDOR_CMD_NEED_NETDEV |
8108 WIPHY_VENDOR_CMD_NEED_RUNNING,
8109 .doit = wlan_hdd_cfg80211_get_fw_mem_dump
8110 },
8111 {
8112 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308113 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
8114 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8115 WIPHY_VENDOR_CMD_NEED_NETDEV |
8116 WIPHY_VENDOR_CMD_NEED_RUNNING,
8117 .doit = wlan_hdd_cfg80211_setband
Sushant Kaushik8e644982015-09-23 12:18:54 +05308118 },
8119 {
8120 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8121 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
8122 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8123 WIPHY_VENDOR_CMD_NEED_NETDEV,
8124 .doit = wlan_hdd_cfg80211_wifi_logger_start
8125 },
Sushant Kaushik847890c2015-09-28 16:05:17 +05308126 {
8127 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8128 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
8129 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8130 WIPHY_VENDOR_CMD_NEED_NETDEV|
8131 WIPHY_VENDOR_CMD_NEED_RUNNING,
8132 .doit = wlan_hdd_cfg80211_get_wifi_info
Sachin Ahujac08f72a2015-09-22 15:25:47 +05308133 },
8134 {
8135 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8136 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
8137 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8138 WIPHY_VENDOR_CMD_NEED_NETDEV |
8139 WIPHY_VENDOR_CMD_NEED_RUNNING,
8140 .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308141 },
8142 {
8143 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8144 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,
8145 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8146 WIPHY_VENDOR_CMD_NEED_NETDEV |
8147 WIPHY_VENDOR_CMD_NEED_RUNNING,
8148 .doit = wlan_hdd_cfg80211_monitor_rssi
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308149 },
8150#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
8151 {
8152 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8153 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS,
8154 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8155 WIPHY_VENDOR_CMD_NEED_NETDEV |
8156 WIPHY_VENDOR_CMD_NEED_RUNNING,
8157 .doit = wlan_hdd_cfg80211_offloaded_packets
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308158 },
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308159#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308160 {
8161 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8162 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
8163 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8164 WIPHY_VENDOR_CMD_NEED_NETDEV |
8165 WIPHY_VENDOR_CMD_NEED_RUNNING,
8166 .doit = wlan_hdd_cfg80211_get_link_properties
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05308167 },
8168 {
8169 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8170 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION,
8171 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8172 WIPHY_VENDOR_CMD_NEED_NETDEV |
8173 WIPHY_VENDOR_CMD_NEED_RUNNING,
8174 .doit = wlan_hdd_cfg80211_wifi_configuration_set
Kapil Guptaee33bf12016-12-20 18:27:37 +05308175 },
8176#ifdef WLAN_FEATURE_APFIND
8177 {
8178 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8179 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_APFIND,
8180 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8181 WIPHY_VENDOR_CMD_NEED_NETDEV,
8182 .doit = wlan_hdd_cfg80211_apfind_cmd
8183 },
8184#endif /* WLAN_FEATURE_APFIND */
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308185 {
8186 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8187 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET,
8188 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8189 WIPHY_VENDOR_CMD_NEED_NETDEV |
8190 WIPHY_VENDOR_CMD_NEED_RUNNING,
8191 .doit = wlan_hdd_cfg80211_set_nud_stats
8192 },
8193 {
8194 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8195 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8196 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8197 WIPHY_VENDOR_CMD_NEED_NETDEV |
8198 WIPHY_VENDOR_CMD_NEED_RUNNING,
8199 .doit = wlan_hdd_cfg80211_get_nud_stats
8200 },
Anurag Chouhanfcd20172017-07-19 17:25:19 +05308201 {
8202 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8203 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_STATION,
8204 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8205 WIPHY_VENDOR_CMD_NEED_NETDEV |
8206 WIPHY_VENDOR_CMD_NEED_RUNNING,
8207 .doit = hdd_cfg80211_get_station_cmd
8208 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308209};
8210
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008211/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05308212static const
8213struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008214{
8215#ifdef FEATURE_WLAN_CH_AVOID
8216 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05308217 .vendor_id = QCA_NL80211_VENDOR_ID,
8218 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008219 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308220#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
8221#ifdef WLAN_FEATURE_LINK_LAYER_STATS
8222 {
8223 /* Index = 1*/
8224 .vendor_id = QCA_NL80211_VENDOR_ID,
8225 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
8226 },
8227 {
8228 /* Index = 2*/
8229 .vendor_id = QCA_NL80211_VENDOR_ID,
8230 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
8231 },
8232 {
8233 /* Index = 3*/
8234 .vendor_id = QCA_NL80211_VENDOR_ID,
8235 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
8236 },
8237 {
8238 /* Index = 4*/
8239 .vendor_id = QCA_NL80211_VENDOR_ID,
8240 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
8241 },
8242 {
8243 /* Index = 5*/
8244 .vendor_id = QCA_NL80211_VENDOR_ID,
8245 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
8246 },
8247 {
8248 /* Index = 6*/
8249 .vendor_id = QCA_NL80211_VENDOR_ID,
8250 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
8251 },
8252#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308253#ifdef WLAN_FEATURE_EXTSCAN
8254 {
8255 .vendor_id = QCA_NL80211_VENDOR_ID,
8256 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
8257 },
8258 {
8259 .vendor_id = QCA_NL80211_VENDOR_ID,
8260 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
8261 },
8262 {
8263 .vendor_id = QCA_NL80211_VENDOR_ID,
8264 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
8265 },
8266 {
8267 .vendor_id = QCA_NL80211_VENDOR_ID,
8268 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
8269 },
8270 {
8271 .vendor_id = QCA_NL80211_VENDOR_ID,
8272 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
8273 },
8274 {
8275 .vendor_id = QCA_NL80211_VENDOR_ID,
8276 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
8277 },
8278 {
8279 .vendor_id = QCA_NL80211_VENDOR_ID,
8280 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
8281 },
8282 {
8283 .vendor_id = QCA_NL80211_VENDOR_ID,
8284 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
8285 },
8286 {
8287 .vendor_id = QCA_NL80211_VENDOR_ID,
8288 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
8289 },
8290 {
8291 .vendor_id = QCA_NL80211_VENDOR_ID,
8292 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
8293 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308294#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308295/*EXT TDLS*/
8296 {
8297 .vendor_id = QCA_NL80211_VENDOR_ID,
8298 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
8299 },
c_manjeecfd1efb2015-09-25 19:32:34 +05308300 [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
8301 .vendor_id = QCA_NL80211_VENDOR_ID,
8302 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
8303 },
8304
Srinivas Dasari030bad32015-02-18 23:23:54 +05308305
Srinivas Dasaribd1cf642017-01-23 14:54:41 +05308306 [QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX] = {
Srinivas Dasari030bad32015-02-18 23:23:54 +05308307 .vendor_id = QCA_NL80211_VENDOR_ID,
8308 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
8309 },
8310
Sushant Kaushik084f6592015-09-10 13:11:56 +05308311 {
8312 .vendor_id = QCA_NL80211_VENDOR_ID,
8313 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308314 },
8315 [QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = {
8316 .vendor_id = QCA_NL80211_VENDOR_ID,
8317 .subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI
8318 },
Padma, Santhosh Kumar7bbc7d92015-12-08 20:23:19 +05308319 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX] = {
8320 .vendor_id = QCA_NL80211_VENDOR_ID,
8321 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST
8322 },
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308323 [QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET_INDEX] = {
8324 .vendor_id = QCA_NL80211_VENDOR_ID,
8325 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8326 },
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008327};
8328
Jeff Johnson295189b2012-06-20 16:38:30 -07008329/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308330 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308331 * This function is called by hdd_wlan_startup()
8332 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308333 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07008334 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308335struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07008336{
8337 struct wiphy *wiphy;
8338 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308339 /*
8340 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07008341 */
8342 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
8343
8344 if (!wiphy)
8345 {
8346 /* Print error and jump into err label and free the memory */
8347 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
8348 return NULL;
8349 }
8350
Sunil Duttc69bccb2014-05-26 21:30:20 +05308351
Jeff Johnson295189b2012-06-20 16:38:30 -07008352 return wiphy;
8353}
8354
Anurag Chouhan343af7e2016-12-16 13:11:19 +05308355#if (LINUX_VERSION_CODE > KERNEL_VERSION(4,4,0)) || \
8356 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
8357/**
8358 * hdd_config_sched_scan_plans_to_wiphy() - configure sched scan plans to wiphy
8359 * @wiphy: pointer to wiphy
8360 * @config: pointer to config
8361 *
8362 * Return: None
8363 */
8364static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
8365 hdd_config_t *config)
8366{
8367 wiphy->max_sched_scan_plans = MAX_SCHED_SCAN_PLANS;
8368 if (config->max_sched_scan_plan_interval)
8369 wiphy->max_sched_scan_plan_interval =
8370 config->max_sched_scan_plan_interval;
8371 if (config->max_sched_scan_plan_iterations)
8372 wiphy->max_sched_scan_plan_iterations =
8373 config->max_sched_scan_plan_iterations;
8374}
8375#else
8376static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
8377 hdd_config_t *config)
8378{
8379}
8380#endif
8381
Jeff Johnson295189b2012-06-20 16:38:30 -07008382/*
8383 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308384 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07008385 * private ioctl to change the band value
8386 */
8387int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
8388{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308389 int i, j;
8390 eNVChannelEnabledType channelEnabledState;
8391
Jeff Johnsone7245742012-09-05 17:12:55 -07008392 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308393
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308394 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07008395 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308396
8397 if (NULL == wiphy->bands[i])
8398 {
8399 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
8400 __func__, i);
8401 continue;
8402 }
8403
8404 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
8405 {
8406 struct ieee80211_supported_band *band = wiphy->bands[i];
8407
8408 channelEnabledState = vos_nv_getChannelEnabledState(
8409 band->channels[j].hw_value);
8410
8411 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
8412 {
Abhishek Singh678227a2014-11-04 10:52:38 +05308413 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308414 continue;
8415 }
8416 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
8417 {
8418 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8419 continue;
8420 }
8421
8422 if (NV_CHANNEL_DISABLE == channelEnabledState ||
8423 NV_CHANNEL_INVALID == channelEnabledState)
8424 {
8425 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8426 }
8427 else if (NV_CHANNEL_DFS == channelEnabledState)
8428 {
8429 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
8430 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
8431 }
8432 else
8433 {
8434 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
8435 |IEEE80211_CHAN_RADAR);
8436 }
8437 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008438 }
8439 return 0;
8440}
8441/*
8442 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308443 * This function is called by hdd_wlan_startup()
8444 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07008445 * This function is used to initialize and register wiphy structure.
8446 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308447int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07008448 struct wiphy *wiphy,
8449 hdd_config_t *pCfg
8450 )
8451{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308452 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05308453 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
8454
Jeff Johnsone7245742012-09-05 17:12:55 -07008455 ENTER();
8456
Jeff Johnson295189b2012-06-20 16:38:30 -07008457 /* Now bind the underlying wlan device with wiphy */
8458 set_wiphy_dev(wiphy, dev);
8459
8460 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07008461
Kiet Lam6c583332013-10-14 05:37:09 +05308462#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07008463 /* the flag for the other case would be initialzed in
8464 vos_init_wiphy_from_nv_bin */
Manjeet Singh9e19de62016-08-18 18:26:41 +05308465#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
8466 wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
8467#else
Amar Singhal0a402232013-10-11 20:57:16 -07008468 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05308469#endif
Manjeet Singh9e19de62016-08-18 18:26:41 +05308470#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07008471
Amar Singhalfddc28c2013-09-05 13:03:40 -07008472 /* This will disable updating of NL channels from passive to
8473 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308474#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
8475 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
8476#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07008477 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308478#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07008479
Amar Singhala49cbc52013-10-08 18:37:44 -07008480
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008481#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07008482 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
8483 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
8484 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07008485 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308486#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Rajeev Kumar Sirasanagandla0d6dd752016-08-17 15:01:39 +05308487 wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308488#else
8489 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
8490#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008491#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07008492
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08008493#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07008494 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08008495#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07008496 || pCfg->isFastRoamIniFeatureEnabled
8497#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08008498#ifdef FEATURE_WLAN_ESE
8499 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07008500#endif
8501 )
8502 {
8503 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
8504 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08008505#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008506#ifdef FEATURE_WLAN_TDLS
8507 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
8508 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
8509#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308510#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05308511 if (pCfg->configPNOScanSupport)
8512 {
8513 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
8514 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
8515 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
8516 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
8517 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308518#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008519
Abhishek Singh10d85972015-04-17 10:27:23 +05308520#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
8521 wiphy->features |= NL80211_FEATURE_HT_IBSS;
8522#endif
8523
Amar Singhalfddc28c2013-09-05 13:03:40 -07008524#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07008525 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
8526 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07008527 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07008528 driver need to determine what to do with both
8529 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07008530
8531 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07008532#else
8533 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07008534#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008535
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308536 wiphy->max_scan_ssids = MAX_SCAN_SSID;
8537
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05308538 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07008539
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308540 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
8541
Jeff Johnson295189b2012-06-20 16:38:30 -07008542 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05308543 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
8544 | BIT(NL80211_IFTYPE_ADHOC)
8545 | BIT(NL80211_IFTYPE_P2P_CLIENT)
8546 | BIT(NL80211_IFTYPE_P2P_GO)
8547 | BIT(NL80211_IFTYPE_AP);
8548
8549 if (VOS_MONITOR_MODE == hdd_get_conparam())
8550 {
8551 wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
8552 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008553
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308554 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008555 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308556#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
8557 if( pCfg->enableMCC )
8558 {
8559 /* Currently, supports up to two channels */
8560 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008561
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308562 if( !pCfg->allowMCCGODiffBI )
8563 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008564
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308565 }
8566 wiphy->iface_combinations = &wlan_hdd_iface_combination;
8567 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008568#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308569 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008570
Jeff Johnson295189b2012-06-20 16:38:30 -07008571 /* Before registering we need to update the ht capabilitied based
8572 * on ini values*/
8573 if( !pCfg->ShortGI20MhzEnable )
8574 {
8575 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
8576 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
Jeff Johnson295189b2012-06-20 16:38:30 -07008577 }
8578
8579 if( !pCfg->ShortGI40MhzEnable )
8580 {
8581 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
8582 }
8583
8584 if( !pCfg->nChannelBondingMode5GHz )
8585 {
8586 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
8587 }
Agrawal Ashish97dec502015-11-26 20:20:58 +05308588 /*
8589 * In case of static linked driver at the time of driver unload,
8590 * module exit doesn't happens. Module cleanup helps in cleaning
8591 * of static memory.
8592 * If driver load happens statically, at the time of driver unload,
8593 * wiphy flags don't get reset because of static memory.
8594 * It's better not to store channel in static memory.
8595 */
8596 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
8597 wiphy->bands[IEEE80211_BAND_2GHZ]->channels =
8598 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_2_4_GHZ));
8599 if (wiphy->bands[IEEE80211_BAND_2GHZ]->channels == NULL)
8600 {
8601 hddLog(VOS_TRACE_LEVEL_ERROR,
8602 FL("Not enough memory to allocate channels"));
8603 return -ENOMEM;
8604 }
8605 vos_mem_copy(wiphy->bands[IEEE80211_BAND_2GHZ]->channels,
8606 &hdd_channels_2_4_GHZ[0],
8607 sizeof(hdd_channels_2_4_GHZ));
Jeff Johnson295189b2012-06-20 16:38:30 -07008608
Agrawal Ashish97dec502015-11-26 20:20:58 +05308609 if (true == hdd_is_5g_supported(pHddCtx))
8610 {
8611 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
8612 wiphy->bands[IEEE80211_BAND_5GHZ]->channels =
8613 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_5_GHZ));
8614 if (wiphy->bands[IEEE80211_BAND_5GHZ]->channels == NULL)
8615 {
8616 hddLog(VOS_TRACE_LEVEL_ERROR,
8617 FL("Not enough memory to allocate channels"));
8618 vos_mem_free(wiphy->bands[IEEE80211_BAND_2GHZ]->channels);
8619 wiphy->bands[IEEE80211_BAND_2GHZ]->channels = NULL;
8620 return -ENOMEM;
8621 }
8622 vos_mem_copy(wiphy->bands[IEEE80211_BAND_5GHZ]->channels,
8623 &hdd_channels_5_GHZ[0],
8624 sizeof(hdd_channels_5_GHZ));
8625 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308626
8627 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
8628 {
8629
8630 if (NULL == wiphy->bands[i])
8631 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05308632 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308633 __func__, i);
8634 continue;
8635 }
8636
8637 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
8638 {
8639 struct ieee80211_supported_band *band = wiphy->bands[i];
8640
8641 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
8642 {
8643 // Enable social channels for P2P
8644 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
8645 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
8646 else
8647 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8648 continue;
8649 }
8650 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
8651 {
8652 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8653 continue;
8654 }
8655 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008656 }
8657 /*Initialise the supported cipher suite details*/
8658 wiphy->cipher_suites = hdd_cipher_suites;
8659 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
8660
8661 /*signal strength in mBm (100*dBm) */
8662 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
8663
8664#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05308665 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07008666#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008667
Sunil Duttc69bccb2014-05-26 21:30:20 +05308668 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
8669 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008670 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
8671 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
8672
Anurag Chouhan343af7e2016-12-16 13:11:19 +05308673 hdd_config_sched_scan_plans_to_wiphy(wiphy, pCfg);
8674
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308675 EXIT();
8676 return 0;
8677}
8678
8679/* In this function we are registering wiphy. */
8680int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
8681{
8682 ENTER();
8683 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008684 if (0 > wiphy_register(wiphy))
8685 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308686 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07008687 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8688 return -EIO;
8689 }
8690
8691 EXIT();
8692 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308693}
Jeff Johnson295189b2012-06-20 16:38:30 -07008694
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308695/* In this function we are updating channel list when,
8696 regulatory domain is FCC and country code is US.
8697 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
8698 As per FCC smart phone is not a indoor device.
8699 GO should not opeate on indoor channels */
8700void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
8701{
8702 int j;
8703 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
8704 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
8705 //Default counrtycode from NV at the time of wiphy initialization.
8706 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
8707 &defaultCountryCode[0]))
8708 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008709 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308710 }
8711 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
8712 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308713 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
8714 {
8715 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
8716 return;
8717 }
8718 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
8719 {
8720 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
8721 // Mark UNII -1 band channel as passive
8722 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
8723 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
8724 }
8725 }
8726}
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05308727/* This function registers for all frame which supplicant is interested in */
8728void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008729{
Jeff Johnson295189b2012-06-20 16:38:30 -07008730 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8731 /* Register for all P2P action, public action etc frames */
8732 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
Jeff Johnsone7245742012-09-05 17:12:55 -07008733 ENTER();
Abhishek Singh16e05762015-11-30 14:29:27 +05308734 /* Register frame indication call back */
8735 sme_register_mgmt_frame_ind_callback(hHal, hdd_indicate_mgmt_frame);
Jeff Johnson295189b2012-06-20 16:38:30 -07008736 /* Right now we are registering these frame when driver is getting
8737 initialized. Once we will move to 2.6.37 kernel, in which we have
8738 frame register ops, we will move this code as a part of that */
8739 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308740 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07008741 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
8742
8743 /* GAS Initial Response */
8744 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8745 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308746
Jeff Johnson295189b2012-06-20 16:38:30 -07008747 /* GAS Comeback Request */
8748 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8749 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
8750
8751 /* GAS Comeback Response */
8752 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8753 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
8754
8755 /* P2P Public Action */
8756 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308757 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07008758 P2P_PUBLIC_ACTION_FRAME_SIZE );
8759
8760 /* P2P Action */
8761 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8762 (v_U8_t*)P2P_ACTION_FRAME,
8763 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07008764
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05308765 /* WNM BSS Transition Request frame */
8766 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8767 (v_U8_t*)WNM_BSS_ACTION_FRAME,
8768 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07008769
8770 /* WNM-Notification */
8771 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8772 (v_U8_t*)WNM_NOTIFICATION_FRAME,
8773 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008774}
8775
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05308776void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008777{
Jeff Johnson295189b2012-06-20 16:38:30 -07008778 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8779 /* Register for all P2P action, public action etc frames */
8780 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
8781
Jeff Johnsone7245742012-09-05 17:12:55 -07008782 ENTER();
8783
Jeff Johnson295189b2012-06-20 16:38:30 -07008784 /* Right now we are registering these frame when driver is getting
8785 initialized. Once we will move to 2.6.37 kernel, in which we have
8786 frame register ops, we will move this code as a part of that */
8787 /* GAS Initial Request */
8788
8789 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8790 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
8791
8792 /* GAS Initial Response */
8793 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8794 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308795
Jeff Johnson295189b2012-06-20 16:38:30 -07008796 /* GAS Comeback Request */
8797 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8798 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
8799
8800 /* GAS Comeback Response */
8801 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8802 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
8803
8804 /* P2P Public Action */
8805 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308806 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07008807 P2P_PUBLIC_ACTION_FRAME_SIZE );
8808
8809 /* P2P Action */
8810 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8811 (v_U8_t*)P2P_ACTION_FRAME,
8812 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07008813 /* WNM-Notification */
8814 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8815 (v_U8_t*)WNM_NOTIFICATION_FRAME,
8816 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008817}
8818
8819#ifdef FEATURE_WLAN_WAPI
8820void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05308821 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07008822{
8823 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8824 tCsrRoamSetKey setKey;
8825 v_BOOL_t isConnected = TRUE;
8826 int status = 0;
8827 v_U32_t roamId= 0xFF;
8828 tANI_U8 *pKeyPtr = NULL;
8829 int n = 0;
8830
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308831 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
8832 __func__, hdd_device_modetoString(pAdapter->device_mode),
8833 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008834
Gopichand Nakkalae7480202013-02-11 15:24:22 +05308835 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07008836 setKey.keyId = key_index; // Store Key ID
8837 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
8838 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
8839 setKey.paeRole = 0 ; // the PAE role
8840 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
8841 {
8842 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
8843 }
8844 else
8845 {
8846 isConnected = hdd_connIsConnected(pHddStaCtx);
8847 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
8848 }
8849 setKey.keyLength = key_Len;
8850 pKeyPtr = setKey.Key;
8851 memcpy( pKeyPtr, key, key_Len);
8852
Arif Hussain6d2a3322013-11-17 19:50:10 -08008853 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07008854 __func__, key_Len);
8855 for (n = 0 ; n < key_Len; n++)
8856 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
8857 __func__,n,setKey.Key[n]);
8858
8859 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8860 if ( isConnected )
8861 {
8862 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8863 pAdapter->sessionId, &setKey, &roamId );
8864 }
8865 if ( status != 0 )
8866 {
8867 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8868 "[%4d] sme_RoamSetKey returned ERROR status= %d",
8869 __LINE__, status );
8870 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8871 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308872 /* Need to clear any trace of key value in the memory.
8873 * Thus zero out the memory even though it is local
8874 * variable.
8875 */
8876 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07008877}
8878#endif /* FEATURE_WLAN_WAPI*/
8879
8880#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308881int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07008882 beacon_data_t **ppBeacon,
8883 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008884#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308885int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008886 beacon_data_t **ppBeacon,
8887 struct cfg80211_beacon_data *params,
8888 int dtim_period)
8889#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308890{
Jeff Johnson295189b2012-06-20 16:38:30 -07008891 int size;
8892 beacon_data_t *beacon = NULL;
8893 beacon_data_t *old = NULL;
Kapil Gupta137ef892016-12-13 19:38:00 +05308894 int head_len, tail_len, proberesp_ies_len, assocresp_ies_len;
8895 const u8 *head, *tail, *proberesp_ies, *assocresp_ies;
Jeff Johnson295189b2012-06-20 16:38:30 -07008896
Jeff Johnsone7245742012-09-05 17:12:55 -07008897 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008898 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308899 {
8900 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8901 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008902 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308903 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008904
8905 old = pAdapter->sessionCtx.ap.beacon;
8906
8907 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308908 {
8909 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8910 FL("session(%d) old and new heads points to NULL"),
8911 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008912 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308913 }
8914
8915 if (params->tail && !params->tail_len)
8916 {
8917 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8918 FL("tail_len is zero but tail is not NULL"));
8919 return -EINVAL;
8920 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008921
Jeff Johnson295189b2012-06-20 16:38:30 -07008922#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
8923 /* Kernel 3.0 is not updating dtim_period for set beacon */
8924 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308925 {
8926 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8927 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008928 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308929 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008930#endif
8931
Kapil Gupta137ef892016-12-13 19:38:00 +05308932 if (params->head)
8933 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008934 head_len = params->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05308935 head = params->head;
8936 } else
8937 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008938 head_len = old->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05308939 head = old->head;
8940 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008941
Kapil Gupta137ef892016-12-13 19:38:00 +05308942 if (params->tail || !old)
8943 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008944 tail_len = params->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05308945 tail = params->tail;
8946 } else
8947 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008948 tail_len = old->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05308949 tail = old->tail;
8950 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008951
Kapil Gupta137ef892016-12-13 19:38:00 +05308952 if (params->proberesp_ies || !old)
8953 {
8954 proberesp_ies_len = params->proberesp_ies_len;
8955 proberesp_ies = params->proberesp_ies;
8956 } else
8957 {
8958 proberesp_ies_len = old->proberesp_ies_len;
8959 proberesp_ies = old->proberesp_ies;
8960 }
8961
8962 if (params->assocresp_ies || !old)
8963 {
8964 assocresp_ies_len = params->assocresp_ies_len;
8965 assocresp_ies = params->assocresp_ies;
8966 } else
8967 {
8968 assocresp_ies_len = old->assocresp_ies_len;
8969 assocresp_ies = old->assocresp_ies;
8970 }
8971
8972 size = sizeof(beacon_data_t) + head_len + tail_len +
8973 proberesp_ies_len + assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07008974
8975 beacon = kzalloc(size, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07008976 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308977 {
8978 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8979 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008980 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308981 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008982
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008983#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Kapil Gupta137ef892016-12-13 19:38:00 +05308984 if (params->dtim_period)
Jeff Johnson295189b2012-06-20 16:38:30 -07008985 beacon->dtim_period = params->dtim_period;
8986 else
8987 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008988#else
Kapil Gupta137ef892016-12-13 19:38:00 +05308989 if (dtim_period)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008990 beacon->dtim_period = dtim_period;
8991 else
8992 beacon->dtim_period = old->dtim_period;
8993#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308994
Jeff Johnson295189b2012-06-20 16:38:30 -07008995 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
8996 beacon->tail = beacon->head + head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05308997 beacon->proberesp_ies = beacon->tail + tail_len;
8998 beacon->assocresp_ies = beacon->proberesp_ies + proberesp_ies_len;
8999
Jeff Johnson295189b2012-06-20 16:38:30 -07009000 beacon->head_len = head_len;
9001 beacon->tail_len = tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309002 beacon->proberesp_ies_len = proberesp_ies_len;
9003 beacon->assocresp_ies_len= assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009004
c_manjee527ecac2017-01-25 12:25:27 +05309005 if (head && head_len)
9006 memcpy(beacon->head, head, head_len);
9007 if (tail && tail_len)
9008 memcpy(beacon->tail, tail, tail_len);
9009 if (proberesp_ies && proberesp_ies_len)
9010 memcpy(beacon->proberesp_ies, proberesp_ies, proberesp_ies_len);
9011 if (assocresp_ies && assocresp_ies_len)
9012 memcpy(beacon->assocresp_ies, assocresp_ies, assocresp_ies_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009013
9014 *ppBeacon = beacon;
9015
9016 kfree(old);
9017
9018 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009019}
Jeff Johnson295189b2012-06-20 16:38:30 -07009020
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309021v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
9022#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
9023 const v_U8_t *pIes,
9024#else
9025 v_U8_t *pIes,
9026#endif
9027 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009028{
9029 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309030 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07009031 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309032
Jeff Johnson295189b2012-06-20 16:38:30 -07009033 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309034 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009035 elem_id = ptr[0];
9036 elem_len = ptr[1];
9037 left -= 2;
9038 if(elem_len > left)
9039 {
9040 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07009041 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009042 eid,elem_len,left);
9043 return NULL;
9044 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309045 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009046 {
9047 return ptr;
9048 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309049
Jeff Johnson295189b2012-06-20 16:38:30 -07009050 left -= elem_len;
9051 ptr += (elem_len + 2);
9052 }
9053 return NULL;
9054}
9055
Jeff Johnson295189b2012-06-20 16:38:30 -07009056/* Check if rate is 11g rate or not */
9057static int wlan_hdd_rate_is_11g(u8 rate)
9058{
Sanjay Devnani28322e22013-06-21 16:13:40 -07009059 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009060 u8 i;
9061 for (i = 0; i < 8; i++)
9062 {
9063 if(rate == gRateArray[i])
9064 return TRUE;
9065 }
9066 return FALSE;
9067}
9068
9069/* Check for 11g rate and set proper 11g only mode */
9070static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
9071 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
9072{
9073 u8 i, num_rates = pIe[0];
9074
9075 pIe += 1;
9076 for ( i = 0; i < num_rates; i++)
9077 {
9078 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
9079 {
9080 /* If rate set have 11g rate than change the mode to 11G */
9081 *pSapHw_mode = eSAP_DOT11_MODE_11g;
9082 if (pIe[i] & BASIC_RATE_MASK)
9083 {
9084 /* If we have 11g rate as basic rate, it means mode
9085 is 11g only mode.
9086 */
9087 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
9088 *pCheckRatesfor11g = FALSE;
9089 }
9090 }
9091 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
9092 {
9093 *require_ht = TRUE;
9094 }
9095 }
9096 return;
9097}
9098
9099static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
9100{
9101 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9102 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9103 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9104 u8 checkRatesfor11g = TRUE;
9105 u8 require_ht = FALSE;
9106 u8 *pIe=NULL;
9107
9108 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
9109
9110 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
9111 pBeacon->head_len, WLAN_EID_SUPP_RATES);
9112 if (pIe != NULL)
9113 {
9114 pIe += 1;
9115 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9116 &pConfig->SapHw_mode);
9117 }
9118
9119 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9120 WLAN_EID_EXT_SUPP_RATES);
9121 if (pIe != NULL)
9122 {
9123
9124 pIe += 1;
9125 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9126 &pConfig->SapHw_mode);
9127 }
9128
9129 if( pConfig->channel > 14 )
9130 {
9131 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
9132 }
9133
9134 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9135 WLAN_EID_HT_CAPABILITY);
9136
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309137 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009138 {
9139 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
9140 if(require_ht)
9141 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
9142 }
9143}
9144
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309145static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
9146 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
9147{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009148 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309149 v_U8_t *pIe = NULL;
9150 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9151
9152 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
9153 pBeacon->tail, pBeacon->tail_len);
9154
9155 if (pIe)
9156 {
9157 ielen = pIe[1] + 2;
9158 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9159 {
9160 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
9161 }
9162 else
9163 {
9164 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
9165 return -EINVAL;
9166 }
9167 *total_ielen += ielen;
9168 }
9169 return 0;
9170}
9171
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009172static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
9173 v_U8_t *genie, v_U8_t *total_ielen)
9174{
9175 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9176 int left = pBeacon->tail_len;
9177 v_U8_t *ptr = pBeacon->tail;
9178 v_U8_t elem_id, elem_len;
9179 v_U16_t ielen = 0;
9180
9181 if ( NULL == ptr || 0 == left )
9182 return;
9183
9184 while (left >= 2)
9185 {
9186 elem_id = ptr[0];
9187 elem_len = ptr[1];
9188 left -= 2;
9189 if (elem_len > left)
9190 {
9191 hddLog( VOS_TRACE_LEVEL_ERROR,
9192 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
9193 elem_id, elem_len, left);
9194 return;
9195 }
9196 if (IE_EID_VENDOR == elem_id)
9197 {
9198 /* skipping the VSIE's which we don't want to include or
9199 * it will be included by existing code
9200 */
9201 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
9202#ifdef WLAN_FEATURE_WFD
9203 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
9204#endif
9205 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9206 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9207 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
9208 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9209 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
9210 {
9211 ielen = ptr[1] + 2;
9212 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9213 {
9214 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
9215 *total_ielen += ielen;
9216 }
9217 else
9218 {
9219 hddLog( VOS_TRACE_LEVEL_ERROR,
9220 "IE Length is too big "
9221 "IEs eid=%d elem_len=%d total_ie_lent=%d",
9222 elem_id, elem_len, *total_ielen);
9223 }
9224 }
9225 }
9226
9227 left -= elem_len;
9228 ptr += (elem_len + 2);
9229 }
9230 return;
9231}
9232
Kapil Gupta137ef892016-12-13 19:38:00 +05309233int wlan_hdd_cfg80211_update_apies(hdd_adapter_t *pHostapdAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009234{
9235 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309236 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009237 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07009238 int ret = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +05309239 beacon_data_t *pBeacon = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009240
9241 genie = vos_mem_malloc(MAX_GENIE_LEN);
9242
9243 if(genie == NULL) {
9244
9245 return -ENOMEM;
9246 }
9247
Kapil Gupta137ef892016-12-13 19:38:00 +05309248 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309249 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9250 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009251 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309252 hddLog(LOGE,
9253 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309254 ret = -EINVAL;
9255 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009256 }
9257
9258#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309259 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9260 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
9261 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309262 hddLog(LOGE,
9263 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309264 ret = -EINVAL;
9265 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009266 }
9267#endif
9268
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309269 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9270 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009271 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309272 hddLog(LOGE,
9273 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309274 ret = -EINVAL;
9275 goto done;
9276 }
9277
9278 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
9279 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009280 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07009281 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009282
9283 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9284 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
9285 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
9286 {
9287 hddLog(LOGE,
9288 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009289 ret = -EINVAL;
9290 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009291 }
9292
9293 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9294 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
9295 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9296 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9297 ==eHAL_STATUS_FAILURE)
9298 {
9299 hddLog(LOGE,
9300 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009301 ret = -EINVAL;
9302 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009303 }
9304
9305 // Added for ProResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +05309306 if ((pBeacon->proberesp_ies != NULL) && (pBeacon->proberesp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009307 {
Kapil Gupta137ef892016-12-13 19:38:00 +05309308 u16 rem_probe_resp_ie_len = pBeacon->proberesp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009309 u8 probe_rsp_ie_len[3] = {0};
9310 u8 counter = 0;
9311 /* Check Probe Resp Length if it is greater then 255 then Store
9312 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
9313 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
9314 Store More then 255 bytes into One Variable.
9315 */
9316 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
9317 {
9318 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
9319 {
9320 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
9321 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
9322 }
9323 else
9324 {
9325 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
9326 rem_probe_resp_ie_len = 0;
9327 }
9328 }
9329
9330 rem_probe_resp_ie_len = 0;
9331
9332 if (probe_rsp_ie_len[0] > 0)
9333 {
9334 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9335 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
Kapil Gupta137ef892016-12-13 19:38:00 +05309336 (tANI_U8*)&pBeacon->
9337 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07009338 probe_rsp_ie_len[0], NULL,
9339 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9340 {
9341 hddLog(LOGE,
9342 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009343 ret = -EINVAL;
9344 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009345 }
9346 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
9347 }
9348
9349 if (probe_rsp_ie_len[1] > 0)
9350 {
9351 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9352 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
Kapil Gupta137ef892016-12-13 19:38:00 +05309353 (tANI_U8*)&pBeacon->
9354 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07009355 probe_rsp_ie_len[1], NULL,
9356 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9357 {
9358 hddLog(LOGE,
9359 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009360 ret = -EINVAL;
9361 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009362 }
9363 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
9364 }
9365
9366 if (probe_rsp_ie_len[2] > 0)
9367 {
9368 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9369 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
Kapil Gupta137ef892016-12-13 19:38:00 +05309370 (tANI_U8*)&pBeacon->
9371 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07009372 probe_rsp_ie_len[2], NULL,
9373 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9374 {
9375 hddLog(LOGE,
9376 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009377 ret = -EINVAL;
9378 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009379 }
9380 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
9381 }
9382
9383 if (probe_rsp_ie_len[1] == 0 )
9384 {
9385 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9386 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
9387 eANI_BOOLEAN_FALSE) )
9388 {
9389 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009390 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009391 }
9392 }
9393
9394 if (probe_rsp_ie_len[2] == 0 )
9395 {
9396 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9397 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
9398 eANI_BOOLEAN_FALSE) )
9399 {
9400 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009401 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009402 }
9403 }
9404
9405 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9406 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
9407 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9408 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9409 == eHAL_STATUS_FAILURE)
9410 {
9411 hddLog(LOGE,
9412 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009413 ret = -EINVAL;
9414 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009415 }
9416 }
9417 else
9418 {
9419 // Reset WNI_CFG_PROBE_RSP Flags
9420 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
9421
9422 hddLog(VOS_TRACE_LEVEL_INFO,
9423 "%s: No Probe Response IE received in set beacon",
9424 __func__);
9425 }
9426
9427 // Added for AssocResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +05309428 if ((pBeacon->assocresp_ies != NULL) && (pBeacon->assocresp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009429 {
9430 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
Kapil Gupta137ef892016-12-13 19:38:00 +05309431 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)pBeacon->assocresp_ies,
9432 pBeacon->assocresp_ies_len, NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -07009433 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9434 {
9435 hddLog(LOGE,
9436 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009437 ret = -EINVAL;
9438 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009439 }
9440
9441 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9442 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
9443 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9444 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9445 == eHAL_STATUS_FAILURE)
9446 {
9447 hddLog(LOGE,
9448 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009449 ret = -EINVAL;
9450 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009451 }
9452 }
9453 else
9454 {
9455 hddLog(VOS_TRACE_LEVEL_INFO,
9456 "%s: No Assoc Response IE received in set beacon",
9457 __func__);
9458
9459 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9460 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
9461 eANI_BOOLEAN_FALSE) )
9462 {
9463 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009464 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009465 }
9466 }
9467
Jeff Johnsone7245742012-09-05 17:12:55 -07009468done:
Jeff Johnson295189b2012-06-20 16:38:30 -07009469 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309470 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009471}
Jeff Johnson295189b2012-06-20 16:38:30 -07009472
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309473/*
Jeff Johnson295189b2012-06-20 16:38:30 -07009474 * FUNCTION: wlan_hdd_validate_operation_channel
9475 * called by wlan_hdd_cfg80211_start_bss() and
9476 * wlan_hdd_cfg80211_set_channel()
9477 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309478 * channel list.
9479 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07009480VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07009481{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309482
Jeff Johnson295189b2012-06-20 16:38:30 -07009483 v_U32_t num_ch = 0;
9484 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
9485 u32 indx = 0;
9486 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309487 v_U8_t fValidChannel = FALSE, count = 0;
9488 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309489
Jeff Johnson295189b2012-06-20 16:38:30 -07009490 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
9491
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309492 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07009493 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309494 /* Validate the channel */
9495 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07009496 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309497 if ( channel == rfChannels[count].channelNum )
9498 {
9499 fValidChannel = TRUE;
9500 break;
9501 }
9502 }
9503 if (fValidChannel != TRUE)
9504 {
9505 hddLog(VOS_TRACE_LEVEL_ERROR,
9506 "%s: Invalid Channel [%d]", __func__, channel);
9507 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009508 }
9509 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309510 else
Jeff Johnson295189b2012-06-20 16:38:30 -07009511 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309512 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
9513 valid_ch, &num_ch))
9514 {
9515 hddLog(VOS_TRACE_LEVEL_ERROR,
9516 "%s: failed to get valid channel list", __func__);
9517 return VOS_STATUS_E_FAILURE;
9518 }
9519 for (indx = 0; indx < num_ch; indx++)
9520 {
9521 if (channel == valid_ch[indx])
9522 {
9523 break;
9524 }
9525 }
9526
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05309527 if (indx >= num_ch)
9528 {
9529 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
9530 {
9531 eCsrBand band;
9532 unsigned int freq;
9533
9534 sme_GetFreqBand(hHal, &band);
9535
9536 if (eCSR_BAND_5G == band)
9537 {
9538#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
9539 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
9540 {
9541 freq = ieee80211_channel_to_frequency(channel,
9542 IEEE80211_BAND_2GHZ);
9543 }
9544 else
9545 {
9546 freq = ieee80211_channel_to_frequency(channel,
9547 IEEE80211_BAND_5GHZ);
9548 }
9549#else
9550 freq = ieee80211_channel_to_frequency(channel);
9551#endif
9552 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
9553 return VOS_STATUS_SUCCESS;
9554 }
9555 }
9556
9557 hddLog(VOS_TRACE_LEVEL_ERROR,
9558 "%s: Invalid Channel [%d]", __func__, channel);
9559 return VOS_STATUS_E_FAILURE;
9560 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009561 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05309562
Jeff Johnson295189b2012-06-20 16:38:30 -07009563 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309564
Jeff Johnson295189b2012-06-20 16:38:30 -07009565}
9566
Viral Modi3a32cc52013-02-08 11:14:52 -08009567/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309568 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08009569 * This function is used to set the channel number
9570 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309571static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08009572 struct ieee80211_channel *chan,
9573 enum nl80211_channel_type channel_type
9574 )
9575{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309576 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08009577 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07009578 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08009579 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309580 hdd_context_t *pHddCtx;
9581 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009582
9583 ENTER();
9584
9585 if( NULL == dev )
9586 {
9587 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009588 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08009589 return -ENODEV;
9590 }
9591 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309592
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309593 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9594 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
9595 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08009596 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309597 "%s: device_mode = %s (%d) freq = %d", __func__,
9598 hdd_device_modetoString(pAdapter->device_mode),
9599 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309600
9601 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9602 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309603 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08009604 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309605 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009606 }
9607
9608 /*
9609 * Do freq to chan conversion
9610 * TODO: for 11a
9611 */
9612
9613 channel = ieee80211_frequency_to_channel(freq);
9614
9615 /* Check freq range */
9616 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
9617 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
9618 {
9619 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009620 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08009621 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
9622 WNI_CFG_CURRENT_CHANNEL_STAMAX);
9623 return -EINVAL;
9624 }
9625
9626 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
9627
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05309628 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
9629 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08009630 {
9631 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
9632 {
9633 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009634 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08009635 return -EINVAL;
9636 }
9637 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
9638 "%s: set channel to [%d] for device mode =%d",
9639 __func__, channel,pAdapter->device_mode);
9640 }
9641 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08009642 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08009643 )
9644 {
9645 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9646 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
9647 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9648
9649 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
9650 {
9651 /* Link is up then return cant set channel*/
9652 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009653 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08009654 return -EINVAL;
9655 }
9656
9657 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
9658 pHddStaCtx->conn_info.operationChannel = channel;
9659 pRoamProfile->ChannelInfo.ChannelList =
9660 &pHddStaCtx->conn_info.operationChannel;
9661 }
9662 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08009663 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08009664 )
9665 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309666 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
9667 {
9668 if(VOS_STATUS_SUCCESS !=
9669 wlan_hdd_validate_operation_channel(pAdapter,channel))
9670 {
9671 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009672 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309673 return -EINVAL;
9674 }
9675 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
9676 }
9677 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08009678 {
9679 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
9680
9681 /* If auto channel selection is configured as enable/ 1 then ignore
9682 channel set by supplicant
9683 */
9684 if ( cfg_param->apAutoChannelSelection )
9685 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309686 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
9687 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08009688 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309689 "%s: set channel to auto channel (0) for device mode =%s (%d)",
9690 __func__, hdd_device_modetoString(pAdapter->device_mode),
9691 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08009692 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309693 else
9694 {
9695 if(VOS_STATUS_SUCCESS !=
9696 wlan_hdd_validate_operation_channel(pAdapter,channel))
9697 {
9698 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009699 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309700 return -EINVAL;
9701 }
9702 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
9703 }
Viral Modi3a32cc52013-02-08 11:14:52 -08009704 }
9705 }
9706 else
9707 {
9708 hddLog(VOS_TRACE_LEVEL_FATAL,
9709 "%s: Invalid device mode failed to set valid channel", __func__);
9710 return -EINVAL;
9711 }
9712 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309713 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009714}
9715
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309716static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
9717 struct net_device *dev,
9718 struct ieee80211_channel *chan,
9719 enum nl80211_channel_type channel_type
9720 )
9721{
9722 int ret;
9723
9724 vos_ssr_protect(__func__);
9725 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
9726 vos_ssr_unprotect(__func__);
9727
9728 return ret;
9729}
9730
Anurag Chouhan83026002016-12-13 22:46:21 +05309731#ifdef DHCP_SERVER_OFFLOAD
9732void hdd_dhcp_server_offload_done(void *fw_dhcp_srv_offload_cb_context,
9733 VOS_STATUS status)
9734{
9735 hdd_adapter_t* adapter = (hdd_adapter_t*)fw_dhcp_srv_offload_cb_context;
9736
9737 ENTER();
9738
9739 if (NULL == adapter)
9740 {
9741 hddLog(VOS_TRACE_LEVEL_ERROR,
9742 "%s: adapter is NULL",__func__);
9743 return;
9744 }
9745
9746 adapter->dhcp_status.dhcp_offload_status = status;
9747 vos_event_set(&adapter->dhcp_status.vos_event);
9748 return;
9749}
9750
9751/**
9752 * wlan_hdd_set_dhcp_server_offload() - set dhcp server offload
9753 * @hostapd_adapter: pointer to hostapd adapter.
Anurag Chouhan638f5e22017-03-06 12:28:43 +05309754 * @re_init: flag set if api called post ssr
Anurag Chouhan83026002016-12-13 22:46:21 +05309755 *
9756 * Return: None
9757 */
Anurag Chouhan638f5e22017-03-06 12:28:43 +05309758VOS_STATUS wlan_hdd_set_dhcp_server_offload(hdd_adapter_t *hostapd_adapter,
9759 bool re_init)
Anurag Chouhan83026002016-12-13 22:46:21 +05309760{
9761 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter);
9762 sir_dhcp_srv_offload_info dhcp_srv_info;
9763 tANI_U8 num_entries = 0;
9764 tANI_U8 srv_ip[IPADDR_NUM_ENTRIES];
9765 tANI_U8 num;
9766 tANI_U32 temp;
9767 VOS_STATUS ret;
9768
9769 ENTER();
9770
Anurag Chouhan638f5e22017-03-06 12:28:43 +05309771 if (!re_init) {
9772 ret = wlan_hdd_validate_context(hdd_ctx);
9773 if (0 != ret)
9774 return VOS_STATUS_E_INVAL;
9775 }
Anurag Chouhan83026002016-12-13 22:46:21 +05309776
9777 /* Prepare the request to send to SME */
9778 dhcp_srv_info = vos_mem_malloc(sizeof(*dhcp_srv_info));
9779 if (NULL == dhcp_srv_info) {
9780 hddLog(VOS_TRACE_LEVEL_ERROR,
9781 "%s: could not allocate tDhcpSrvOffloadInfo!", __func__);
9782 return VOS_STATUS_E_NOMEM;
9783 }
9784
9785 vos_mem_zero(dhcp_srv_info, sizeof(*dhcp_srv_info));
9786
9787 dhcp_srv_info->bssidx = hostapd_adapter->sessionId;
9788 dhcp_srv_info->dhcp_srv_offload_enabled = TRUE;
9789 dhcp_srv_info->dhcp_client_num = hdd_ctx->cfg_ini->dhcp_max_num_clients;
9790 dhcp_srv_info->start_lsb = hdd_ctx->cfg_ini->dhcp_start_lsb;
9791 dhcp_srv_info->dhcp_offload_callback = hdd_dhcp_server_offload_done;
9792 dhcp_srv_info->dhcp_server_offload_cb_context = hostapd_adapter;
9793
9794 hdd_string_to_u8_array(hdd_ctx->cfg_ini->dhcp_srv_ip,
9795 srv_ip,
9796 &num_entries,
Anurag Chouhanac145c22016-11-22 16:51:47 +05309797 IPADDR_NUM_ENTRIES, ".");
Anurag Chouhan83026002016-12-13 22:46:21 +05309798 if (num_entries != IPADDR_NUM_ENTRIES) {
9799 hddLog(VOS_TRACE_LEVEL_ERROR,
9800 "%s: incorrect IP address (%s) assigned for DHCP server!",
9801 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
9802 vos_mem_free(dhcp_srv_info);
9803 return VOS_STATUS_E_FAILURE;
9804 }
9805
9806 if ((srv_ip[0] >= 224) && (srv_ip[0] <= 239)) {
9807 hddLog(VOS_TRACE_LEVEL_ERROR,
9808 "%s: invalid IP address (%s)! It could NOT be multicast IP address!",
9809 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
9810 vos_mem_free(dhcp_srv_info);
9811 return VOS_STATUS_E_FAILURE;
9812 }
9813
9814 if (srv_ip[IPADDR_NUM_ENTRIES-1] >= DHCP_START_POOL_ADDRESS) {
9815 hddLog(VOS_TRACE_LEVEL_ERROR,
9816 "%s: invalid IP address (%s)! The last field must be less than 100!",
9817 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
9818 vos_mem_free(dhcp_srv_info);
9819 return VOS_STATUS_E_FAILURE;
9820 }
9821
9822 for (num = 0; num < num_entries; num++) {
9823 temp = srv_ip[num];
9824 dhcp_srv_info->dhcp_srv_ip |= (temp << (8 * num));
9825 }
9826
9827 if (eHAL_STATUS_SUCCESS !=
9828 sme_set_dhcp_srv_offload(hdd_ctx->hHal, dhcp_srv_info)) {
9829 hddLog(VOS_TRACE_LEVEL_ERROR,
9830 "%s: sme_set_dhcp_srv_offload fail!", __func__);
9831 vos_mem_free(dhcp_srv_info);
9832 return VOS_STATUS_E_FAILURE;
9833 }
9834
9835 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
9836 "%s: enable DHCP Server offload successfully!", __func__);
9837
9838 vos_mem_free(dhcp_srv_info);
9839 return 0;
9840}
9841#endif /* DHCP_SERVER_OFFLOAD */
9842
Jeff Johnson295189b2012-06-20 16:38:30 -07009843#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9844static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
9845 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009846#else
9847static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
9848 struct cfg80211_beacon_data *params,
9849 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309850 enum nl80211_hidden_ssid hidden_ssid,
9851 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009852#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009853{
9854 tsap_Config_t *pConfig;
9855 beacon_data_t *pBeacon = NULL;
9856 struct ieee80211_mgmt *pMgmt_frame;
9857 v_U8_t *pIe=NULL;
9858 v_U16_t capab_info;
9859 eCsrAuthType RSNAuthType;
9860 eCsrEncryptionType RSNEncryptType;
9861 eCsrEncryptionType mcRSNEncryptType;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +05309862 int status = VOS_STATUS_SUCCESS, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009863 tpWLAN_SAPEventCB pSapEventCallback;
9864 hdd_hostapd_state_t *pHostapdState;
Jeff Johnson295189b2012-06-20 16:38:30 -07009865 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309866 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009867 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309868 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07009869 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08009870 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05309871 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07009872 v_BOOL_t MFPCapable = VOS_FALSE;
9873 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309874 v_BOOL_t sapEnable11AC =
9875 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Kapil Gupta137ef892016-12-13 19:38:00 +05309876 u_int16_t prev_rsn_length = 0;
9877
Jeff Johnson295189b2012-06-20 16:38:30 -07009878 ENTER();
9879
Nitesh Shah9b066282017-06-06 18:05:52 +05309880 wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309881 iniConfig = pHddCtx->cfg_ini;
9882
Jeff Johnson295189b2012-06-20 16:38:30 -07009883 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
9884
9885 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9886
9887 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9888
9889 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9890
9891 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
9892
9893 //channel is already set in the set_channel Call back
9894 //pConfig->channel = pCommitConfig->channel;
9895
9896 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309897 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07009898 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
9899
9900 pConfig->dtim_period = pBeacon->dtim_period;
9901
Arif Hussain6d2a3322013-11-17 19:50:10 -08009902 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07009903 pConfig->dtim_period);
9904
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08009905 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07009906 {
9907 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07009908 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05309909 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
9910 {
9911 tANI_BOOLEAN restartNeeded;
9912 pConfig->ieee80211d = 1;
9913 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
9914 sme_setRegInfo(hHal, pConfig->countryCode);
9915 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
9916 }
9917 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009918 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07009919 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07009920 pConfig->ieee80211d = 1;
9921 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
9922 sme_setRegInfo(hHal, pConfig->countryCode);
9923 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07009924 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07009925 else
9926 {
9927 pConfig->ieee80211d = 0;
9928 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309929 /*
9930 * If auto channel is configured i.e. channel is 0,
9931 * so skip channel validation.
9932 */
9933 if( AUTO_CHANNEL_SELECT != pConfig->channel )
9934 {
9935 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
9936 {
9937 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009938 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309939 return -EINVAL;
9940 }
9941 }
9942 else
9943 {
9944 if(1 != pHddCtx->is_dynamic_channel_range_set)
9945 {
9946 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
9947 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
9948 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
9949 }
9950 pHddCtx->is_dynamic_channel_range_set = 0;
9951 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009952 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07009953 else
Jeff Johnson295189b2012-06-20 16:38:30 -07009954 {
9955 pConfig->ieee80211d = 0;
9956 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309957
9958#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9959 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
9960 pConfig->authType = eSAP_OPEN_SYSTEM;
9961 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
9962 pConfig->authType = eSAP_SHARED_KEY;
9963 else
9964 pConfig->authType = eSAP_AUTO_SWITCH;
9965#else
9966 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
9967 pConfig->authType = eSAP_OPEN_SYSTEM;
9968 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
9969 pConfig->authType = eSAP_SHARED_KEY;
9970 else
9971 pConfig->authType = eSAP_AUTO_SWITCH;
9972#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009973
9974 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309975
9976 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07009977 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
Agrawal Ashisha8e8a722016-10-18 19:07:45 +05309978#ifdef SAP_AUTH_OFFLOAD
9979 /* In case of sap offload, hostapd.conf is configuted with open mode and
9980 * security is configured from ini file. Due to open mode in hostapd.conf
9981 * privacy bit is set to false which will result in not sending,
9982 * data packets as encrypted.
9983 * If enable_sap_auth_offload is enabled in ini and
9984 * sap_auth_offload_sec_type is type of WPA2-PSK,
9985 * driver will set privacy bit to 1.
9986 */
9987 if (pHddCtx->cfg_ini->enable_sap_auth_offload &&
9988 pHddCtx->cfg_ini->sap_auth_offload_sec_type)
9989 pConfig->privacy = VOS_TRUE;
9990#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009991
9992 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
9993
9994 /*Set wps station to configured*/
9995 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
9996
9997 if(pIe)
9998 {
9999 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
10000 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010001 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -070010002 return -EINVAL;
10003 }
10004 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
10005 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -070010006 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -070010007 /* Check 15 bit of WPS IE as it contain information for wps state
10008 * WPS state
10009 */
10010 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
10011 {
10012 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
10013 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
10014 {
10015 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
10016 }
10017 }
10018 }
10019 else
10020 {
10021 pConfig->wps_state = SAP_WPS_DISABLED;
10022 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010023 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -070010024
c_hpothufe599e92014-06-16 11:38:55 +053010025 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
10026 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
10027 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
10028 eCSR_ENCRYPT_TYPE_NONE;
10029
Jeff Johnson295189b2012-06-20 16:38:30 -070010030 pConfig->RSNWPAReqIELength = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +053010031 memset(&pConfig->RSNWPAReqIE[0], 0, sizeof(pConfig->RSNWPAReqIE));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010032 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070010033 WLAN_EID_RSN);
10034 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010035 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010036 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053010037 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
10038 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
10039 pConfig->RSNWPAReqIELength);
10040 else
10041 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
10042 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010043 /* The actual processing may eventually be more extensive than
10044 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -070010045 * by the app.
10046 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010047 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070010048 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
10049 &RSNEncryptType,
10050 &mcRSNEncryptType,
10051 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080010052 &MFPCapable,
10053 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053010054 pConfig->RSNWPAReqIE[1]+2,
10055 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010056
10057 if( VOS_STATUS_SUCCESS == status )
10058 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010059 /* Now copy over all the security attributes you have
10060 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070010061 * */
10062 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
10063 pConfig->mcRSNEncryptType = mcRSNEncryptType;
10064 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
10065 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010066 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080010067 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070010068 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
10069 }
10070 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010071
Jeff Johnson295189b2012-06-20 16:38:30 -070010072 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
10073 pBeacon->tail, pBeacon->tail_len);
10074
10075 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
10076 {
Kapil Gupta137ef892016-12-13 19:38:00 +053010077 if (pConfig->RSNWPAReqIE[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070010078 {
10079 /*Mixed mode WPA/WPA2*/
Kapil Gupta137ef892016-12-13 19:38:00 +053010080 prev_rsn_length = pConfig->RSNWPAReqIELength;
Jeff Johnson295189b2012-06-20 16:38:30 -070010081 pConfig->RSNWPAReqIELength += pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053010082 if (pConfig->RSNWPAReqIELength <=
10083 (sizeof(pConfig->RSNWPAReqIE) - prev_rsn_length))
10084 memcpy(&pConfig->RSNWPAReqIE[0] + prev_rsn_length, pIe,
10085 pIe[1] + 2);
10086 else
10087 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
10088 pConfig->RSNWPAReqIELength);
10089
Jeff Johnson295189b2012-06-20 16:38:30 -070010090 }
10091 else
10092 {
10093 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053010094 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
10095 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
10096 pConfig->RSNWPAReqIELength);
10097 else
10098 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
10099 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010100 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070010101 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
10102 &RSNEncryptType,
10103 &mcRSNEncryptType,
10104 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080010105 &MFPCapable,
10106 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053010107 pConfig->RSNWPAReqIE[1]+2,
10108 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010109
10110 if( VOS_STATUS_SUCCESS == status )
10111 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010112 /* Now copy over all the security attributes you have
10113 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070010114 * */
10115 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
10116 pConfig->mcRSNEncryptType = mcRSNEncryptType;
10117 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
10118 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010119 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080010120 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070010121 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
10122 }
10123 }
10124 }
10125
Kapil Gupta137ef892016-12-13 19:38:00 +053010126 if (pConfig->RSNWPAReqIELength > sizeof(pConfig->RSNWPAReqIE)) {
Jeff Johnson4416a782013-03-25 14:17:50 -070010127 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
10128 return -EINVAL;
10129 }
10130
Jeff Johnson295189b2012-06-20 16:38:30 -070010131 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
10132
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010133#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010134 if (params->ssid != NULL)
10135 {
10136 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
10137 pConfig->SSIDinfo.ssid.length = params->ssid_len;
10138 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
10139 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
10140 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010141#else
10142 if (ssid != NULL)
10143 {
10144 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
10145 pConfig->SSIDinfo.ssid.length = ssid_len;
10146 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
10147 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
10148 }
10149#endif
10150
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010151 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -070010152 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010153
Jeff Johnson295189b2012-06-20 16:38:30 -070010154 /* default value */
10155 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
10156 pConfig->num_accept_mac = 0;
10157 pConfig->num_deny_mac = 0;
10158
10159 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
10160 pBeacon->tail, pBeacon->tail_len);
10161
10162 /* pIe for black list is following form:
10163 type : 1 byte
10164 length : 1 byte
10165 OUI : 4 bytes
10166 acl type : 1 byte
10167 no of mac addr in black list: 1 byte
10168 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010169 */
10170 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010171 {
10172 pConfig->SapMacaddr_acl = pIe[6];
10173 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080010174 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010175 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053010176 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
10177 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010178 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
10179 for (i = 0; i < pConfig->num_deny_mac; i++)
10180 {
10181 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
10182 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010183 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010184 }
10185 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
10186 pBeacon->tail, pBeacon->tail_len);
10187
10188 /* pIe for white list is following form:
10189 type : 1 byte
10190 length : 1 byte
10191 OUI : 4 bytes
10192 acl type : 1 byte
10193 no of mac addr in white list: 1 byte
10194 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010195 */
10196 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010197 {
10198 pConfig->SapMacaddr_acl = pIe[6];
10199 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080010200 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010201 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053010202 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
10203 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010204 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
10205 for (i = 0; i < pConfig->num_accept_mac; i++)
10206 {
10207 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
10208 acl_entry++;
10209 }
10210 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053010211
Jeff Johnson295189b2012-06-20 16:38:30 -070010212 wlan_hdd_set_sapHwmode(pHostapdAdapter);
10213
Jeff Johnsone7245742012-09-05 17:12:55 -070010214#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080010215 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +053010216 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
10217 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +053010218 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
10219 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080010220 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
10221 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +053010222 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
10223 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -070010224 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053010225 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -070010226 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +053010227 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070010228
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010229 /* If ACS disable and selected channel <= 14
10230 * OR
10231 * ACS enabled and ACS operating band is choosen as 2.4
10232 * AND
10233 * VHT in 2.4G Disabled
10234 * THEN
10235 * Fallback to 11N mode
10236 */
10237 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
10238 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +053010239 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010240 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -070010241 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053010242 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
10243 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070010244 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
10245 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010246 }
10247#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010248
Jeff Johnson295189b2012-06-20 16:38:30 -070010249 // ht_capab is not what the name conveys,this is used for protection bitmap
10250 pConfig->ht_capab =
10251 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
10252
Kapil Gupta137ef892016-12-13 19:38:00 +053010253 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -070010254 {
10255 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
10256 return -EINVAL;
10257 }
10258
10259 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010260 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -070010261 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
10262 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010263 pConfig->obssProtEnabled =
10264 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -070010265
Chet Lanctot8cecea22014-02-11 19:09:36 -080010266#ifdef WLAN_FEATURE_11W
10267 pConfig->mfpCapable = MFPCapable;
10268 pConfig->mfpRequired = MFPRequired;
10269 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
10270 pConfig->mfpCapable, pConfig->mfpRequired);
10271#endif
10272
Arif Hussain6d2a3322013-11-17 19:50:10 -080010273 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -070010274 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -080010275 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
10276 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
10277 (int)pConfig->channel);
10278 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
10279 pConfig->SapHw_mode, pConfig->privacy,
10280 pConfig->authType);
10281 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
10282 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
10283 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
10284 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -070010285
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010286 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -070010287 {
10288 //Bss already started. just return.
10289 //TODO Probably it should update some beacon params.
10290 hddLog( LOGE, "Bss Already started...Ignore the request");
10291 EXIT();
10292 return 0;
10293 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010294
Agarwal Ashish51325b52014-06-16 16:50:49 +053010295 if (vos_max_concurrent_connections_reached()) {
10296 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10297 return -EINVAL;
10298 }
10299
Jeff Johnson295189b2012-06-20 16:38:30 -070010300 pConfig->persona = pHostapdAdapter->device_mode;
10301
Peng Xu2446a892014-09-05 17:21:18 +053010302 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
10303 if ( NULL != psmeConfig)
10304 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053010305 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +053010306 sme_GetConfigParam(hHal, psmeConfig);
10307 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053010308#ifdef WLAN_FEATURE_AP_HT40_24G
10309 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
10310 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
10311 && pHddCtx->cfg_ini->apHT40_24GEnabled)
10312 {
10313 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
10314 sme_UpdateConfig (hHal, psmeConfig);
10315 }
10316#endif
Peng Xu2446a892014-09-05 17:21:18 +053010317 vos_mem_free(psmeConfig);
10318 }
Peng Xuafc34e32014-09-25 13:23:55 +053010319 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +053010320
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010321 set_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
10322
Jeff Johnson295189b2012-06-20 16:38:30 -070010323 pSapEventCallback = hdd_hostapd_SAPEventCB;
10324 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
10325 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
10326 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010327 hddLog(LOGE,FL("SAP Start Bss fail"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010328 ret = -EINVAL;
10329 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070010330 }
10331
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010332 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -070010333 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
10334
10335 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010336
Jeff Johnson295189b2012-06-20 16:38:30 -070010337 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010338 {
10339 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010340 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -070010341 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070010342 VOS_ASSERT(0);
10343 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010344
Jeff Johnson295189b2012-06-20 16:38:30 -070010345 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053010346 if (WLANSAP_get_sessionId(pVosContext, &pHostapdAdapter->sessionId) !=
10347 VOS_STATUS_SUCCESS)
10348 {
10349 hddLog(LOGE,FL("Fail to get Softap sessionID"));
10350 VOS_ASSERT(0);
10351 }
Kaushik, Sushantf6070802014-10-15 15:09:23 +053010352 /* Initialize WMM configuation */
10353 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010354 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010355
Anurag Chouhan83026002016-12-13 22:46:21 +053010356#ifdef DHCP_SERVER_OFFLOAD
10357 /* set dhcp server offload */
10358 if (iniConfig->enable_dhcp_srv_offload &&
10359 sme_IsFeatureSupportedByFW(SAP_OFFLOADS)) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010360 vos_event_reset(&pHostapdAdapter->dhcp_status.vos_event);
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010361 status = wlan_hdd_set_dhcp_server_offload(pHostapdAdapter, false);
Anurag Chouhan83026002016-12-13 22:46:21 +053010362 if (!VOS_IS_STATUS_SUCCESS(status))
10363 {
10364 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10365 ("HDD DHCP Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010366 vos_event_reset(&pHostapdState->vosEvent);
10367 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
10368 status = vos_wait_single_event(&pHostapdState->vosEvent,
10369 10000);
10370 if (!VOS_IS_STATUS_SUCCESS(status)) {
10371 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010372 ret = -EINVAL;
10373 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010374 }
10375 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010376 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010377 status = vos_wait_single_event(&pHostapdAdapter->dhcp_status.vos_event, 2000);
10378 if (!VOS_IS_STATUS_SUCCESS(status) || pHostapdAdapter->dhcp_status.dhcp_offload_status)
10379 {
10380 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10381 ("ERROR: DHCP HDD vos wait for single_event failed!! %d"),
10382 pHostapdAdapter->dhcp_status.dhcp_offload_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010383 vos_event_reset(&pHostapdState->vosEvent);
10384 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
10385 status = vos_wait_single_event(&pHostapdState->vosEvent,
10386 10000);
10387 if (!VOS_IS_STATUS_SUCCESS(status)) {
10388 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010389 ret = -EINVAL;
10390 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010391 }
10392 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010393 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010394#ifdef MDNS_OFFLOAD
10395 if (iniConfig->enable_mdns_offload) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010396 vos_event_reset(&pHostapdAdapter->mdns_status.vos_event);
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010397 status = wlan_hdd_set_mdns_offload(pHostapdAdapter);
10398 if (VOS_IS_STATUS_SUCCESS(status))
10399 {
10400 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10401 ("HDD MDNS Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010402 vos_event_reset(&pHostapdState->vosEvent);
10403 if (VOS_STATUS_SUCCESS ==
10404 WLANSAP_StopBss(pHddCtx->pvosContext)) {
10405 status = vos_wait_single_event(&pHostapdState->vosEvent,
10406 10000);
10407 if (!VOS_IS_STATUS_SUCCESS(status)) {
10408 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010409 ret = -EINVAL;
10410 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010411 }
10412 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010413 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010414 status = vos_wait_single_event(&pHostapdAdapter->
10415 mdns_status.vos_event, 2000);
10416 if (!VOS_IS_STATUS_SUCCESS(status) ||
10417 pHostapdAdapter->mdns_status.mdns_enable_status ||
10418 pHostapdAdapter->mdns_status.mdns_fqdn_status ||
10419 pHostapdAdapter->mdns_status.mdns_resp_status)
10420 {
10421 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10422 ("MDNS HDD vos wait for single_event failed!! enable %d fqdn %d resp %d"),
10423 pHostapdAdapter->mdns_status.mdns_enable_status,
10424 pHostapdAdapter->mdns_status.mdns_fqdn_status,
10425 pHostapdAdapter->mdns_status.mdns_resp_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010426 vos_event_reset(&pHostapdState->vosEvent);
10427 if (VOS_STATUS_SUCCESS ==
10428 WLANSAP_StopBss(pHddCtx->pvosContext)) {
10429 status = vos_wait_single_event(&pHostapdState->vosEvent,
10430 10000);
10431 if (!VOS_IS_STATUS_SUCCESS(status)) {
10432 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010433 ret = -EINVAL;
10434 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010435 }
10436 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010437 }
10438 }
10439#endif /* MDNS_OFFLOAD */
10440 } else {
10441 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10442 ("DHCP Disabled ini %d, FW %d"),
10443 iniConfig->enable_dhcp_srv_offload,
10444 sme_IsFeatureSupportedByFW(SAP_OFFLOADS));
Anurag Chouhan83026002016-12-13 22:46:21 +053010445 }
10446#endif /* DHCP_SERVER_OFFLOAD */
10447
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010448#ifdef WLAN_FEATURE_P2P_DEBUG
10449 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
10450 {
10451 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
10452 {
10453 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
10454 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -080010455 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010456 }
10457 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
10458 {
10459 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
10460 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -080010461 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010462 }
10463 }
10464#endif
Ashish Kumar Dhanotiya42aa5152017-01-03 20:25:57 +053010465 /* Check and restart SAP if it is on Unsafe channel */
10466 hdd_check_for_unsafe_ch(pHostapdAdapter, pHddCtx);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010467
Jeff Johnson295189b2012-06-20 16:38:30 -070010468 pHostapdState->bCommit = TRUE;
10469 EXIT();
10470
10471 return 0;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010472error:
10473 clear_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
10474 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010475}
10476
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010477#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010478static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010479 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070010480 struct beacon_parameters *params)
10481{
10482 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010483 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010484 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010485
10486 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010487
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010488 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10489 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
10490 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010491 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
10492 hdd_device_modetoString(pAdapter->device_mode),
10493 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010494
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010495 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10496 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010497 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010498 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010499 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010500 }
10501
Agarwal Ashish51325b52014-06-16 16:50:49 +053010502 if (vos_max_concurrent_connections_reached()) {
10503 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10504 return -EINVAL;
10505 }
10506
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010507 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010508 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070010509 )
10510 {
10511 beacon_data_t *old,*new;
10512
10513 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010514
Jeff Johnson295189b2012-06-20 16:38:30 -070010515 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010516 {
10517 hddLog(VOS_TRACE_LEVEL_WARN,
10518 FL("already beacon info added to session(%d)"),
10519 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070010520 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010521 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010522
10523 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
10524
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010525 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -070010526 {
10527 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010528 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010529 return -EINVAL;
10530 }
10531
10532 pAdapter->sessionCtx.ap.beacon = new;
10533
10534 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
10535 }
10536
10537 EXIT();
10538 return status;
10539}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010540
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010541static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
10542 struct net_device *dev,
10543 struct beacon_parameters *params)
10544{
10545 int ret;
10546
10547 vos_ssr_protect(__func__);
10548 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
10549 vos_ssr_unprotect(__func__);
10550
10551 return ret;
10552}
10553
10554static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010555 struct net_device *dev,
10556 struct beacon_parameters *params)
10557{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010558 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010559 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10560 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010561 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010562
10563 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010564
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010565 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10566 TRACE_CODE_HDD_CFG80211_SET_BEACON,
10567 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
10568 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10569 __func__, hdd_device_modetoString(pAdapter->device_mode),
10570 pAdapter->device_mode);
10571
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010572 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10573 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010574 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010575 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010576 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010577 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010578
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010579 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010580 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010581 )
Jeff Johnson295189b2012-06-20 16:38:30 -070010582 {
10583 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010584
Jeff Johnson295189b2012-06-20 16:38:30 -070010585 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010586
Jeff Johnson295189b2012-06-20 16:38:30 -070010587 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010588 {
10589 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10590 FL("session(%d) old and new heads points to NULL"),
10591 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070010592 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010593 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010594
10595 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
10596
10597 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010598 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010599 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010600 return -EINVAL;
10601 }
10602
10603 pAdapter->sessionCtx.ap.beacon = new;
10604
10605 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
10606 }
10607
10608 EXIT();
10609 return status;
10610}
10611
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010612static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
10613 struct net_device *dev,
10614 struct beacon_parameters *params)
10615{
10616 int ret;
10617
10618 vos_ssr_protect(__func__);
10619 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
10620 vos_ssr_unprotect(__func__);
10621
10622 return ret;
10623}
10624
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010625#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10626
10627#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010628static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010629 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010630#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010631static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010632 struct net_device *dev)
10633#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010634{
10635 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -070010636 hdd_context_t *pHddCtx = NULL;
10637 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010638 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010639 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010640
10641 ENTER();
10642
10643 if (NULL == pAdapter)
10644 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010645 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010646 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010647 return -ENODEV;
10648 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010649
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010650 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10651 TRACE_CODE_HDD_CFG80211_STOP_AP,
10652 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010653 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10654 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010655 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010656 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010657 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -070010658 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010659
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010660 pScanInfo = &pHddCtx->scan_info;
10661
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010662 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10663 __func__, hdd_device_modetoString(pAdapter->device_mode),
10664 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010665
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010666 ret = wlan_hdd_scan_abort(pAdapter);
10667
Girish Gowli4bf7a632014-06-12 13:42:11 +053010668 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -070010669 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010670 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10671 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010672
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010673 if (pHddCtx->isLogpInProgress)
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 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -080010677
Jeff Johnsone7245742012-09-05 17:12:55 -070010678 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010679 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -070010680 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010681 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070010682 }
10683
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010684 /* Delete all associated STAs before stopping AP/P2P GO */
10685 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +053010686 hdd_hostapd_stop(dev);
10687
Jeff Johnson295189b2012-06-20 16:38:30 -070010688 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010689 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070010690 )
10691 {
10692 beacon_data_t *old;
10693
10694 old = pAdapter->sessionCtx.ap.beacon;
10695
10696 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010697 {
10698 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10699 FL("session(%d) beacon data points to NULL"),
10700 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070010701 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010702 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010703
Jeff Johnson295189b2012-06-20 16:38:30 -070010704 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010705
10706 mutex_lock(&pHddCtx->sap_lock);
10707 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
10708 {
Jeff Johnson4416a782013-03-25 14:17:50 -070010709 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -070010710 {
10711 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
10712
10713 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
10714
10715 if (!VOS_IS_STATUS_SUCCESS(status))
10716 {
10717 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010718 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -070010719 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010720 }
10721 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010722 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010723 /* BSS stopped, clear the active sessions for this device mode */
10724 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010725 }
10726 mutex_unlock(&pHddCtx->sap_lock);
10727
10728 if(status != VOS_STATUS_SUCCESS)
10729 {
10730 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010731 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010732 return -EINVAL;
10733 }
10734
Jeff Johnson4416a782013-03-25 14:17:50 -070010735 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070010736 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
10737 ==eHAL_STATUS_FAILURE)
10738 {
10739 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010740 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010741 }
10742
Jeff Johnson4416a782013-03-25 14:17:50 -070010743 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070010744 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
10745 eANI_BOOLEAN_FALSE) )
10746 {
10747 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010748 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010749 }
10750
10751 // Reset WNI_CFG_PROBE_RSP Flags
10752 wlan_hdd_reset_prob_rspies(pAdapter);
10753
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010754 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
10755
Jeff Johnson295189b2012-06-20 16:38:30 -070010756 pAdapter->sessionCtx.ap.beacon = NULL;
10757 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010758#ifdef WLAN_FEATURE_P2P_DEBUG
10759 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
10760 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
10761 {
10762 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
10763 "GO got removed");
10764 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
10765 }
10766#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010767 }
10768 EXIT();
10769 return status;
10770}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010771
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010772#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10773static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
10774 struct net_device *dev)
10775{
10776 int ret;
10777
10778 vos_ssr_protect(__func__);
10779 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
10780 vos_ssr_unprotect(__func__);
10781
10782 return ret;
10783}
10784#else
10785static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
10786 struct net_device *dev)
10787{
10788 int ret;
10789
10790 vos_ssr_protect(__func__);
10791 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
10792 vos_ssr_unprotect(__func__);
10793
10794 return ret;
10795}
10796#endif
10797
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010798#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
10799
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010800static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010801 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010802 struct cfg80211_ap_settings *params)
10803{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010804 hdd_adapter_t *pAdapter;
10805 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010806 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010807
10808 ENTER();
10809
Girish Gowlib143d7a2015-02-18 19:39:55 +053010810 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010811 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010812 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +053010813 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010814 return -ENODEV;
10815 }
10816
10817 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
10818 if (NULL == pAdapter)
10819 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010820 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010821 "%s: HDD adapter is Null", __func__);
10822 return -ENODEV;
10823 }
10824
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010825 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10826 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
10827 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010828 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
10829 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010830 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010831 "%s: HDD adapter magic is invalid", __func__);
10832 return -ENODEV;
10833 }
10834
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010835 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
10836
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010837 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010838 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010839 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010840 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010841 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010842 }
10843
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010844 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
10845 __func__, hdd_device_modetoString(pAdapter->device_mode),
10846 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010847
10848 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010849 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010850 )
10851 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010852 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010853
10854 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010855
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010856 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010857 {
10858 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
10859 FL("already beacon info added to session(%d)"),
10860 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010861 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010862 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010863
Girish Gowlib143d7a2015-02-18 19:39:55 +053010864#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10865 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
10866 &new,
10867 &params->beacon);
10868#else
10869 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
10870 &new,
10871 &params->beacon,
10872 params->dtim_period);
10873#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010874
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010875 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010876 {
10877 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010878 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010879 return -EINVAL;
10880 }
10881 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -080010882#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -070010883 wlan_hdd_cfg80211_set_channel(wiphy, dev,
10884#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
10885 params->channel, params->channel_type);
10886#else
10887 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
10888#endif
Viral Modi3a32cc52013-02-08 11:14:52 -080010889#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010890 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010891 params->ssid_len, params->hidden_ssid,
10892 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010893 }
10894
10895 EXIT();
10896 return status;
10897}
10898
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010899static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
10900 struct net_device *dev,
10901 struct cfg80211_ap_settings *params)
10902{
10903 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010904
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010905 vos_ssr_protect(__func__);
10906 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
10907 vos_ssr_unprotect(__func__);
10908
10909 return ret;
10910}
10911
10912static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010913 struct net_device *dev,
10914 struct cfg80211_beacon_data *params)
10915{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010916 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010917 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010918 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010919
10920 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010921
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010922 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10923 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
10924 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -080010925 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010926 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010927
10928 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10929 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010930 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010931 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010932 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010933 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010934
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010935 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010936 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010937 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010938 {
10939 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010940
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010941 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010942
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010943 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010944 {
10945 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10946 FL("session(%d) beacon data points to NULL"),
10947 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010948 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010949 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010950
10951 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
10952
10953 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010954 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010955 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010956 return -EINVAL;
10957 }
10958
10959 pAdapter->sessionCtx.ap.beacon = new;
10960
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010961 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
10962 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010963 }
10964
10965 EXIT();
10966 return status;
10967}
10968
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010969static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
10970 struct net_device *dev,
10971 struct cfg80211_beacon_data *params)
10972{
10973 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010974
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010975 vos_ssr_protect(__func__);
10976 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
10977 vos_ssr_unprotect(__func__);
10978
10979 return ret;
10980}
10981
10982#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010983
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010984static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010985 struct net_device *dev,
10986 struct bss_parameters *params)
10987{
10988 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010989 hdd_context_t *pHddCtx;
10990 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010991
10992 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010993
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010994 if (NULL == pAdapter)
10995 {
10996 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10997 "%s: HDD adapter is Null", __func__);
10998 return -ENODEV;
10999 }
11000 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011001 ret = wlan_hdd_validate_context(pHddCtx);
11002 if (0 != ret)
11003 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011004 return ret;
11005 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011006 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11007 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
11008 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011009 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11010 __func__, hdd_device_modetoString(pAdapter->device_mode),
11011 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011012
11013 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011014 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011015 )
Jeff Johnson295189b2012-06-20 16:38:30 -070011016 {
11017 /* ap_isolate == -1 means that in change bss, upper layer doesn't
11018 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011019 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -070011020 {
11021 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011022 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011023 }
11024
11025 EXIT();
11026 return 0;
11027}
11028
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011029static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
11030 struct net_device *dev,
11031 struct bss_parameters *params)
11032{
11033 int ret;
11034
11035 vos_ssr_protect(__func__);
11036 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
11037 vos_ssr_unprotect(__func__);
11038
11039 return ret;
11040}
Kiet Lam10841362013-11-01 11:36:50 +053011041/* FUNCTION: wlan_hdd_change_country_code_cd
11042* to wait for contry code completion
11043*/
11044void* wlan_hdd_change_country_code_cb(void *pAdapter)
11045{
11046 hdd_adapter_t *call_back_pAdapter = pAdapter;
11047 complete(&call_back_pAdapter->change_country_code);
11048 return NULL;
11049}
11050
Jeff Johnson295189b2012-06-20 16:38:30 -070011051/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053011052 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -070011053 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
11054 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053011055int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011056 struct net_device *ndev,
11057 enum nl80211_iftype type,
11058 u32 *flags,
11059 struct vif_params *params
11060 )
11061{
11062 struct wireless_dev *wdev;
11063 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011064 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -070011065 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011066 tCsrRoamProfile *pRoamProfile = NULL;
11067 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011068 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011069 eMib_dot11DesiredBssType connectedBssType;
11070 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011071 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011072
11073 ENTER();
11074
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011075 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011076 {
11077 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11078 "%s: Adapter context is null", __func__);
11079 return VOS_STATUS_E_FAILURE;
11080 }
11081
11082 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11083 if (!pHddCtx)
11084 {
11085 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11086 "%s: HDD context is null", __func__);
11087 return VOS_STATUS_E_FAILURE;
11088 }
11089
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011090 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11091 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
11092 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011093 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011094 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011095 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011096 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011097 }
11098
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011099 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11100 __func__, hdd_device_modetoString(pAdapter->device_mode),
11101 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011102
Agarwal Ashish51325b52014-06-16 16:50:49 +053011103 if (vos_max_concurrent_connections_reached()) {
11104 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11105 return -EINVAL;
11106 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011107 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070011108 wdev = ndev->ieee80211_ptr;
11109
11110#ifdef WLAN_BTAMP_FEATURE
11111 if((NL80211_IFTYPE_P2P_CLIENT == type)||
11112 (NL80211_IFTYPE_ADHOC == type)||
11113 (NL80211_IFTYPE_AP == type)||
11114 (NL80211_IFTYPE_P2P_GO == type))
11115 {
11116 pHddCtx->isAmpAllowed = VOS_FALSE;
11117 // stop AMP traffic
11118 status = WLANBAP_StopAmp();
11119 if(VOS_STATUS_SUCCESS != status )
11120 {
11121 pHddCtx->isAmpAllowed = VOS_TRUE;
11122 hddLog(VOS_TRACE_LEVEL_FATAL,
11123 "%s: Failed to stop AMP", __func__);
11124 return -EINVAL;
11125 }
11126 }
11127#endif //WLAN_BTAMP_FEATURE
11128 /* Reset the current device mode bit mask*/
11129 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
11130
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +053011131 if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
11132 ((type == NL80211_IFTYPE_P2P_CLIENT) ||
11133 (type == NL80211_IFTYPE_P2P_GO)))
11134 {
11135 /* Notify Mode change in case of concurrency.
11136 * Below function invokes TDLS teardown Functionality Since TDLS is
11137 * not Supported in case of concurrency i.e Once P2P session
11138 * is detected disable offchannel and teardown TDLS links
11139 */
11140 hddLog(LOG1,
11141 FL("Device mode = %d Interface type = %d"),
11142 pAdapter->device_mode, type);
11143 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
11144 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +053011145
Jeff Johnson295189b2012-06-20 16:38:30 -070011146 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070011147 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -070011148 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -070011149 )
11150 {
11151 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011152 if (!pWextState)
11153 {
11154 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11155 "%s: pWextState is null", __func__);
11156 return VOS_STATUS_E_FAILURE;
11157 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011158 pRoamProfile = &pWextState->roamProfile;
11159 LastBSSType = pRoamProfile->BSSType;
11160
11161 switch (type)
11162 {
11163 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070011164 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070011165 hddLog(VOS_TRACE_LEVEL_INFO,
11166 "%s: setting interface Type to INFRASTRUCTURE", __func__);
11167 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -070011168#ifdef WLAN_FEATURE_11AC
11169 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
11170 {
11171 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
11172 }
11173#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011174 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -070011175 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011176 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080011177 //Check for sub-string p2p to confirm its a p2p interface
11178 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011179 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +053011180#ifdef FEATURE_WLAN_TDLS
11181 mutex_lock(&pHddCtx->tdls_lock);
11182 wlan_hdd_tdls_exit(pAdapter, TRUE);
11183 mutex_unlock(&pHddCtx->tdls_lock);
11184#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -080011185 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
11186 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
11187 }
11188 else
11189 {
11190 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070011191 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080011192 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011193 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +053011194
Jeff Johnson295189b2012-06-20 16:38:30 -070011195 case NL80211_IFTYPE_ADHOC:
11196 hddLog(VOS_TRACE_LEVEL_INFO,
11197 "%s: setting interface Type to ADHOC", __func__);
11198 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
11199 pRoamProfile->phyMode =
11200 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -070011201 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011202 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +053011203 hdd_set_ibss_ops( pAdapter );
11204 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +053011205
11206 status = hdd_sta_id_hash_attach(pAdapter);
11207 if (VOS_STATUS_SUCCESS != status) {
11208 hddLog(VOS_TRACE_LEVEL_ERROR,
11209 FL("Failed to initialize hash for IBSS"));
11210 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011211 break;
11212
11213 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070011214 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070011215 {
11216 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
11217 "%s: setting interface Type to %s", __func__,
11218 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
11219
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080011220 //Cancel any remain on channel for GO mode
11221 if (NL80211_IFTYPE_P2P_GO == type)
11222 {
11223 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
11224 }
Mohit Khanna0f232092012-09-11 14:46:08 -070011225 if (NL80211_IFTYPE_AP == type)
11226 {
11227 /* As Loading WLAN Driver one interface being created for p2p device
11228 * address. This will take one HW STA and the max number of clients
11229 * that can connect to softAP will be reduced by one. so while changing
11230 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
11231 * interface as it is not required in SoftAP mode.
11232 */
11233
11234 // Get P2P Adapter
11235 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
11236
11237 if (pP2pAdapter)
11238 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053011239 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +053011240 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -070011241 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
11242 }
11243 }
Swaroop Goltia2e32212014-04-09 23:37:33 +053011244 //Disable IMPS & BMPS for SAP/GO
11245 if(VOS_STATUS_E_FAILURE ==
11246 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
11247 {
11248 //Fail to Exit BMPS
11249 VOS_ASSERT(0);
11250 }
Deepthi Gowri500fc472014-08-11 19:53:10 +053011251
11252 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
11253
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011254#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -070011255
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011256 /* A Mutex Lock is introduced while changing the mode to
11257 * protect the concurrent access for the Adapters by TDLS
11258 * module.
11259 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011260 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011261#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011262 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +053011263 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011264 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -070011265 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
11266 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011267#ifdef FEATURE_WLAN_TDLS
11268 mutex_unlock(&pHddCtx->tdls_lock);
11269#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070011270 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
11271 (pConfig->apRandomBssidEnabled))
11272 {
11273 /* To meet Android requirements create a randomized
11274 MAC address of the form 02:1A:11:Fx:xx:xx */
11275 get_random_bytes(&ndev->dev_addr[3], 3);
11276 ndev->dev_addr[0] = 0x02;
11277 ndev->dev_addr[1] = 0x1A;
11278 ndev->dev_addr[2] = 0x11;
11279 ndev->dev_addr[3] |= 0xF0;
11280 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
11281 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -080011282 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
11283 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070011284 }
11285
Jeff Johnson295189b2012-06-20 16:38:30 -070011286 hdd_set_ap_ops( pAdapter->dev );
11287
Kiet Lam10841362013-11-01 11:36:50 +053011288 /* This is for only SAP mode where users can
11289 * control country through ini.
11290 * P2P GO follows station country code
11291 * acquired during the STA scanning. */
11292 if((NL80211_IFTYPE_AP == type) &&
11293 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
11294 {
11295 int status = 0;
11296 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
11297 "%s: setting country code from INI ", __func__);
11298 init_completion(&pAdapter->change_country_code);
11299 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
11300 (void *)(tSmeChangeCountryCallback)
11301 wlan_hdd_change_country_code_cb,
11302 pConfig->apCntryCode, pAdapter,
11303 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053011304 eSIR_FALSE,
11305 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +053011306 if (eHAL_STATUS_SUCCESS == status)
11307 {
11308 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011309 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +053011310 &pAdapter->change_country_code,
11311 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011312 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +053011313 {
11314 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011315 FL("SME Timed out while setting country code %ld"),
11316 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -080011317
11318 if (pHddCtx->isLogpInProgress)
11319 {
11320 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11321 "%s: LOGP in Progress. Ignore!!!", __func__);
11322 return -EAGAIN;
11323 }
Kiet Lam10841362013-11-01 11:36:50 +053011324 }
11325 }
11326 else
11327 {
11328 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011329 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +053011330 return -EINVAL;
11331 }
11332 }
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +053011333 status = hdd_init_ap_mode(pAdapter, false);
Jeff Johnson295189b2012-06-20 16:38:30 -070011334 if(status != VOS_STATUS_SUCCESS)
11335 {
11336 hddLog(VOS_TRACE_LEVEL_FATAL,
11337 "%s: Error initializing the ap mode", __func__);
11338 return -EINVAL;
11339 }
11340 hdd_set_conparam(1);
11341
Nirav Shah7e3c8132015-06-22 23:51:42 +053011342 status = hdd_sta_id_hash_attach(pAdapter);
11343 if (VOS_STATUS_SUCCESS != status)
11344 {
11345 hddLog(VOS_TRACE_LEVEL_ERROR,
11346 FL("Failed to initialize hash for AP"));
11347 return -EINVAL;
11348 }
11349
Jeff Johnson295189b2012-06-20 16:38:30 -070011350 /*interface type changed update in wiphy structure*/
11351 if(wdev)
11352 {
11353 wdev->iftype = type;
11354 pHddCtx->change_iface = type;
11355 }
11356 else
11357 {
11358 hddLog(VOS_TRACE_LEVEL_ERROR,
11359 "%s: ERROR !!!! Wireless dev is NULL", __func__);
11360 return -EINVAL;
11361 }
11362 goto done;
11363 }
11364
11365 default:
11366 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
11367 __func__);
11368 return -EOPNOTSUPP;
11369 }
11370 }
11371 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011372 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011373 )
11374 {
11375 switch(type)
11376 {
11377 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070011378 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070011379 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +053011380
11381 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011382#ifdef FEATURE_WLAN_TDLS
11383
11384 /* A Mutex Lock is introduced while changing the mode to
11385 * protect the concurrent access for the Adapters by TDLS
11386 * module.
11387 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011388 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011389#endif
c_hpothu002231a2015-02-05 14:58:51 +053011390 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011391 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080011392 //Check for sub-string p2p to confirm its a p2p interface
11393 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -080011394 {
11395 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
11396 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
11397 }
11398 else
11399 {
11400 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070011401 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080011402 }
Agrawal Ashishcfe83282016-09-29 13:03:45 +053011403
11404 /* set con_mode to STA only when no SAP concurrency mode */
11405 if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO)))
11406 hdd_set_conparam(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070011407 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070011408 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
11409 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011410#ifdef FEATURE_WLAN_TDLS
11411 mutex_unlock(&pHddCtx->tdls_lock);
11412#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +053011413 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -070011414 if( VOS_STATUS_SUCCESS != status )
11415 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -070011416 /* In case of JB, for P2P-GO, only change interface will be called,
11417 * This is the right place to enable back bmps_imps()
11418 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053011419 if (pHddCtx->hdd_wlan_suspended)
11420 {
11421 hdd_set_pwrparams(pHddCtx);
11422 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011423 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070011424 goto done;
11425 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070011426 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070011427 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070011428 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
11429 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -070011430 goto done;
11431 default:
11432 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
11433 __func__);
11434 return -EOPNOTSUPP;
11435
11436 }
11437
11438 }
11439 else
11440 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011441 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
11442 __func__, hdd_device_modetoString(pAdapter->device_mode),
11443 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011444 return -EOPNOTSUPP;
11445 }
11446
11447
11448 if(pRoamProfile)
11449 {
11450 if ( LastBSSType != pRoamProfile->BSSType )
11451 {
11452 /*interface type changed update in wiphy structure*/
11453 wdev->iftype = type;
11454
11455 /*the BSS mode changed, We need to issue disconnect
11456 if connected or in IBSS disconnect state*/
11457 if ( hdd_connGetConnectedBssType(
11458 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
11459 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
11460 {
11461 /*need to issue a disconnect to CSR.*/
11462 INIT_COMPLETION(pAdapter->disconnect_comp_var);
11463 if( eHAL_STATUS_SUCCESS ==
11464 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
11465 pAdapter->sessionId,
11466 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
11467 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011468 ret = wait_for_completion_interruptible_timeout(
11469 &pAdapter->disconnect_comp_var,
11470 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
11471 if (ret <= 0)
11472 {
11473 hddLog(VOS_TRACE_LEVEL_ERROR,
11474 FL("wait on disconnect_comp_var failed %ld"), ret);
11475 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011476 }
11477 }
11478 }
11479 }
11480
11481done:
11482 /*set bitmask based on updated value*/
11483 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -070011484
11485 /* Only STA mode support TM now
11486 * all other mode, TM feature should be disabled */
11487 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
11488 (~VOS_STA & pHddCtx->concurrency_mode) )
11489 {
11490 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
11491 }
11492
Jeff Johnson295189b2012-06-20 16:38:30 -070011493#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011494 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053011495 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -070011496 {
11497 //we are ok to do AMP
11498 pHddCtx->isAmpAllowed = VOS_TRUE;
11499 }
11500#endif //WLAN_BTAMP_FEATURE
11501 EXIT();
11502 return 0;
11503}
11504
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053011505/*
11506 * FUNCTION: wlan_hdd_cfg80211_change_iface
11507 * wrapper function to protect the actual implementation from SSR.
11508 */
11509int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
11510 struct net_device *ndev,
11511 enum nl80211_iftype type,
11512 u32 *flags,
11513 struct vif_params *params
11514 )
11515{
11516 int ret;
11517
11518 vos_ssr_protect(__func__);
11519 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
11520 vos_ssr_unprotect(__func__);
11521
11522 return ret;
11523}
11524
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011525#ifdef FEATURE_WLAN_TDLS
11526static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011527 struct net_device *dev,
11528#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
11529 const u8 *mac,
11530#else
11531 u8 *mac,
11532#endif
11533 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011534{
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011535 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011536 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011537 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011538 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053011539 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053011540 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011541
11542 ENTER();
11543
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053011544 if (!dev) {
11545 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
11546 return -EINVAL;
11547 }
11548
11549 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
11550 if (!pAdapter) {
11551 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
11552 return -EINVAL;
11553 }
11554
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053011555 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011556 {
11557 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11558 "Invalid arguments");
11559 return -EINVAL;
11560 }
Hoonki Lee27511902013-03-14 18:19:06 -070011561
11562 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
11563 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
11564 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011565 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070011566 "%s: TDLS mode is disabled OR not enabled in FW."
11567 MAC_ADDRESS_STR " Request declined.",
11568 __func__, MAC_ADDR_ARRAY(mac));
11569 return -ENOTSUPP;
11570 }
11571
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011572 if (pHddCtx->isLogpInProgress)
11573 {
11574 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11575 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053011576 wlan_hdd_tdls_set_link_status(pAdapter,
11577 mac,
11578 eTDLS_LINK_IDLE,
11579 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011580 return -EBUSY;
11581 }
11582
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053011583 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +053011584 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011585
11586 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011587 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011588 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
11589 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053011590 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011591 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070011592 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011593
11594 /* in add station, we accept existing valid staId if there is */
11595 if ((0 == update) &&
11596 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
11597 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011598 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011599 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011600 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011601 " link_status %d. staId %d. add station ignored.",
11602 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011603 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011604 return 0;
11605 }
11606 /* in change station, we accept only when staId is valid */
11607 if ((1 == update) &&
11608 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
11609 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
11610 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011611 tANI_U16 staId = pTdlsPeer->staId;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011612 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011613 "%s: " MAC_ADDRESS_STR
11614 " link status %d. staId %d. change station %s.",
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011615 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, staId,
11616 (TDLS_STA_INDEX_VALID(staId)) ? "ignored" : "declined");
11617 mutex_unlock(&pHddCtx->tdls_lock);
11618 return (TDLS_STA_INDEX_VALID(staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011619 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011620 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070011621
11622 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053011623 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011624 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011625 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11626 "%s: " MAC_ADDRESS_STR
11627 " TDLS setup is ongoing. Request declined.",
11628 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -070011629 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011630 }
11631
11632 /* first to check if we reached to maximum supported TDLS peer.
11633 TODO: for now, return -EPERM looks working fine,
11634 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011635 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
11636 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011637 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011638 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11639 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011640 " TDLS Max peer already connected. Request declined."
11641 " Num of peers (%d), Max allowed (%d).",
11642 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
11643 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070011644 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011645 }
11646 else
11647 {
11648 hddTdlsPeer_t *pTdlsPeer;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011649 mutex_lock(&pHddCtx->tdls_lock);
11650 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011651 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011652 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011653 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011654 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11655 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
11656 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011657 return -EPERM;
11658 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011659 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011660 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011661 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +053011662 wlan_hdd_tdls_set_link_status(pAdapter,
11663 mac,
11664 eTDLS_LINK_CONNECTING,
11665 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011666
Jeff Johnsond75fe012013-04-06 10:53:06 -070011667 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053011668 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011669 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011670 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011671 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -070011672 if(StaParams->htcap_present)
11673 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011674 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070011675 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011676 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070011677 "ht_capa->extended_capabilities: %0x",
11678 StaParams->HTCap.extendedHtCapInfo);
11679 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011680 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011681 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011682 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011683 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -070011684 if(StaParams->vhtcap_present)
11685 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011686 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070011687 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
11688 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
11689 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
11690 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011691 {
11692 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011693 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011694 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011695 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011696 "[%d]: %x ", i, StaParams->supported_rates[i]);
11697 }
Jeff Johnsond75fe012013-04-06 10:53:06 -070011698 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053011699 else if ((1 == update) && (NULL == StaParams))
11700 {
11701 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11702 "%s : update is true, but staParams is NULL. Error!", __func__);
11703 return -EPERM;
11704 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011705
11706 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
11707
11708 if (!update)
11709 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053011710 /*Before adding sta make sure that device exited from BMPS*/
11711 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
11712 {
11713 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11714 "%s: Adding tdls peer sta. Disable BMPS", __func__);
11715 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
11716 if (status != VOS_STATUS_SUCCESS) {
11717 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
11718 }
11719 }
11720
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011721 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011722 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011723 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053011724 hddLog(VOS_TRACE_LEVEL_ERROR,
11725 FL("Failed to add TDLS peer STA. Enable Bmps"));
11726 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011727 return -EPERM;
11728 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011729 }
11730 else
11731 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011732 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011733 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011734 if (ret != eHAL_STATUS_SUCCESS) {
11735 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
11736 return -EPERM;
11737 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011738 }
11739
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011740 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011741 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
11742
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053011743 mutex_lock(&pHddCtx->tdls_lock);
11744 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
11745
Masti, Narayanraddi07262462016-01-19 12:40:06 +053011746 if ((pTdlsPeer != NULL) &&
11747 (pTdlsPeer->link_status == eTDLS_LINK_TEARING))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011748 {
Masti, Narayanraddi07262462016-01-19 12:40:06 +053011749 hddLog(VOS_TRACE_LEVEL_ERROR,
11750 FL("peer link status %u"), pTdlsPeer->link_status);
11751 mutex_unlock(&pHddCtx->tdls_lock);
11752 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011753 }
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053011754 mutex_unlock(&pHddCtx->tdls_lock);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011755
Masti, Narayanraddi07262462016-01-19 12:40:06 +053011756 if (ret <= 0)
11757 {
11758 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11759 "%s: timeout waiting for tdls add station indication %ld",
11760 __func__, ret);
11761 goto error;
11762 }
11763
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011764 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
11765 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011766 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011767 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070011768 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011769 }
11770
11771 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -070011772
11773error:
Atul Mittal115287b2014-07-08 13:26:33 +053011774 wlan_hdd_tdls_set_link_status(pAdapter,
11775 mac,
11776 eTDLS_LINK_IDLE,
11777 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -070011778 return -EPERM;
11779
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011780}
11781#endif
11782
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011783static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011784 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011785#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
11786 const u8 *mac,
11787#else
Jeff Johnson295189b2012-06-20 16:38:30 -070011788 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011789#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011790 struct station_parameters *params)
11791{
11792 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011793 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +053011794 hdd_context_t *pHddCtx;
11795 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011796 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011797 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070011798#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011799 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011800 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011801 tANI_U8 isOffChannelSupported = 0;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011802 tANI_U8 isQosWmmSta = FALSE;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070011803#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070011804
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011805 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011806
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011807 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +053011808 if ((NULL == pAdapter))
11809 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011810 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053011811 "invalid adapter ");
11812 return -EINVAL;
11813 }
11814
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011815 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11816 TRACE_CODE_HDD_CHANGE_STATION,
11817 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +053011818 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +053011819
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011820 ret = wlan_hdd_validate_context(pHddCtx);
11821 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +053011822 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011823 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +053011824 }
11825
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011826 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11827
11828 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011829 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011830 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11831 "invalid HDD station context");
11832 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011833 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011834 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
11835
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011836 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
11837 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -070011838 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011839 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -070011840 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011841 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -070011842 WLANTL_STA_AUTHENTICATED);
11843
Gopichand Nakkala29149562013-05-10 21:43:41 +053011844 if (status != VOS_STATUS_SUCCESS)
11845 {
11846 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11847 "%s: Not able to change TL state to AUTHENTICATED", __func__);
11848 return -EINVAL;
11849 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011850 }
11851 }
Hoonki Leea6d49be2013-04-05 09:43:25 -070011852 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
11853 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +053011854#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011855 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
11856 StaParams.capability = params->capability;
11857 StaParams.uapsd_queues = params->uapsd_queues;
11858 StaParams.max_sp = params->max_sp;
11859
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011860 /* Convert (first channel , number of channels) tuple to
11861 * the total list of channels. This goes with the assumption
11862 * that if the first channel is < 14, then the next channels
11863 * are an incremental of 1 else an incremental of 4 till the number
11864 * of channels.
11865 */
11866 if (0 != params->supported_channels_len) {
11867 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
11868 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
11869 {
11870 int wifi_chan_index;
11871 StaParams.supported_channels[j] = params->supported_channels[i];
11872 wifi_chan_index =
11873 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
11874 no_of_channels = params->supported_channels[i+1];
11875 for(k=1; k <= no_of_channels; k++)
11876 {
11877 StaParams.supported_channels[j+1] =
11878 StaParams.supported_channels[j] + wifi_chan_index;
11879 j+=1;
11880 }
11881 }
11882 StaParams.supported_channels_len = j;
11883 }
SaidiReddy Yenuga0f1a1592017-04-05 13:18:26 +053011884 if (params->supported_oper_classes_len >
11885 SIR_MAC_MAX_SUPP_OPER_CLASSES) {
11886 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11887 "received oper classes:%d, resetting it to max supported %d",
11888 params->supported_oper_classes_len,
11889 SIR_MAC_MAX_SUPP_OPER_CLASSES);
11890 params->supported_oper_classes_len =
11891 SIR_MAC_MAX_SUPP_OPER_CLASSES;
11892 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011893 vos_mem_copy(StaParams.supported_oper_classes,
11894 params->supported_oper_classes,
11895 params->supported_oper_classes_len);
11896 StaParams.supported_oper_classes_len =
11897 params->supported_oper_classes_len;
11898
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053011899 if (params->ext_capab_len > sizeof(StaParams.extn_capability)) {
11900 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11901 "received extn capabilities:%d, resetting it to max supported",
11902 params->ext_capab_len);
11903 params->ext_capab_len = sizeof(StaParams.extn_capability);
11904 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011905 if (0 != params->ext_capab_len)
11906 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053011907 params->ext_capab_len);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011908
11909 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070011910 {
11911 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011912 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070011913 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011914
11915 StaParams.supported_rates_len = params->supported_rates_len;
11916
11917 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
11918 * The supported_rates array , for all the structures propogating till Add Sta
11919 * to the firmware has to be modified , if the supplicant (ieee80211) is
11920 * modified to send more rates.
11921 */
11922
11923 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
11924 */
11925 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
11926 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
11927
11928 if (0 != StaParams.supported_rates_len) {
11929 int i = 0;
11930 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
11931 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011932 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011933 "Supported Rates with Length %d", StaParams.supported_rates_len);
11934 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011935 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011936 "[%d]: %0x", i, StaParams.supported_rates[i]);
11937 }
11938
11939 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070011940 {
11941 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011942 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070011943 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011944
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011945 if (0 != params->ext_capab_len ) {
11946 /*Define A Macro : TODO Sunil*/
11947 if ((1<<4) & StaParams.extn_capability[3]) {
11948 isBufSta = 1;
11949 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011950 /* TDLS Channel Switching Support */
11951 if ((1<<6) & StaParams.extn_capability[3]) {
11952 isOffChannelSupported = 1;
11953 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011954 }
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011955
11956 if (pHddCtx->cfg_ini->fEnableTDLSWmmMode &&
Nitesh Shah48df4c02016-08-12 16:27:33 +053011957 (params->ht_capa || params->vht_capa ||
11958 (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME))))
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011959 /* TDLS Peer is WME/QoS capable */
11960 isQosWmmSta = TRUE;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011961
11962 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11963 "%s: TDLS Peer is QOS capable isQosWmmSta= %d HTcapPresent= %d",
11964 __func__, isQosWmmSta, StaParams.htcap_present);
11965
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011966 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
11967 &StaParams, isBufSta,
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011968 isOffChannelSupported,
11969 isQosWmmSta);
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011970
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053011971 if (VOS_STATUS_SUCCESS != status) {
11972 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11973 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
11974 return -EINVAL;
11975 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011976 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
11977
11978 if (VOS_STATUS_SUCCESS != status) {
11979 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11980 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
11981 return -EINVAL;
11982 }
11983 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -070011984#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +053011985 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011986 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011987 return status;
11988}
11989
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011990#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
11991static int wlan_hdd_change_station(struct wiphy *wiphy,
11992 struct net_device *dev,
11993 const u8 *mac,
11994 struct station_parameters *params)
11995#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011996static int wlan_hdd_change_station(struct wiphy *wiphy,
11997 struct net_device *dev,
11998 u8 *mac,
11999 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012000#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012001{
12002 int ret;
12003
12004 vos_ssr_protect(__func__);
12005 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
12006 vos_ssr_unprotect(__func__);
12007
12008 return ret;
12009}
12010
Jeff Johnson295189b2012-06-20 16:38:30 -070012011/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012012 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -070012013 * This function is used to initialize the key information
12014 */
12015#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012016static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012017 struct net_device *ndev,
12018 u8 key_index, bool pairwise,
12019 const u8 *mac_addr,
12020 struct key_params *params
12021 )
12022#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012023static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012024 struct net_device *ndev,
12025 u8 key_index, const u8 *mac_addr,
12026 struct key_params *params
12027 )
12028#endif
12029{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012030 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070012031 tCsrRoamSetKey setKey;
12032 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012033 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012034 v_U32_t roamId= 0xFF;
12035 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070012036 hdd_hostapd_state_t *pHostapdState;
12037 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012038 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012039 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012040
12041 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012042
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012043 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12044 TRACE_CODE_HDD_CFG80211_ADD_KEY,
12045 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012046 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12047 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012048 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012049 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012050 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012051 }
12052
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012053 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12054 __func__, hdd_device_modetoString(pAdapter->device_mode),
12055 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012056
12057 if (CSR_MAX_NUM_KEY <= key_index)
12058 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012059 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012060 key_index);
12061
12062 return -EINVAL;
12063 }
12064
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012065 if (CSR_MAX_KEY_LEN < params->key_len)
12066 {
12067 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
12068 params->key_len);
12069
12070 return -EINVAL;
12071 }
12072
12073 hddLog(VOS_TRACE_LEVEL_INFO,
12074 "%s: called with key index = %d & key length %d",
12075 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070012076
12077 /*extract key idx, key len and key*/
12078 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
12079 setKey.keyId = key_index;
12080 setKey.keyLength = params->key_len;
12081 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
12082
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012083 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070012084 {
12085 case WLAN_CIPHER_SUITE_WEP40:
12086 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
12087 break;
12088
12089 case WLAN_CIPHER_SUITE_WEP104:
12090 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
12091 break;
12092
12093 case WLAN_CIPHER_SUITE_TKIP:
12094 {
12095 u8 *pKey = &setKey.Key[0];
12096 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
12097
12098 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
12099
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012100 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -070012101
12102 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012103 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070012104 |--------------|----------|----------|
12105 <---16bytes---><--8bytes--><--8bytes-->
12106
12107 */
12108 /*Sme expects the 32 bytes key to be in the below order
12109
12110 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012111 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070012112 |--------------|----------|----------|
12113 <---16bytes---><--8bytes--><--8bytes-->
12114 */
12115 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012116 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -070012117
12118 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012119 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070012120
12121 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012122 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070012123
12124
12125 break;
12126 }
12127
12128 case WLAN_CIPHER_SUITE_CCMP:
12129 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
12130 break;
12131
12132#ifdef FEATURE_WLAN_WAPI
12133 case WLAN_CIPHER_SUITE_SMS4:
12134 {
12135 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
12136 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
12137 params->key, params->key_len);
12138 return 0;
12139 }
12140#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070012141
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080012142#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070012143 case WLAN_CIPHER_SUITE_KRK:
12144 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
12145 break;
12146#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070012147
12148#ifdef WLAN_FEATURE_11W
12149 case WLAN_CIPHER_SUITE_AES_CMAC:
12150 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -070012151 break;
Chet Lanctot186b5732013-03-18 10:26:30 -070012152#endif
12153
Jeff Johnson295189b2012-06-20 16:38:30 -070012154 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012155 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070012156 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012157 status = -EOPNOTSUPP;
12158 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012159 }
12160
12161 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
12162 __func__, setKey.encType);
12163
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012164 if (
Jeff Johnson295189b2012-06-20 16:38:30 -070012165#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12166 (!pairwise)
12167#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012168 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -070012169#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012170 )
12171 {
12172 /* set group key*/
12173 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12174 "%s- %d: setting Broadcast key",
12175 __func__, __LINE__);
12176 setKey.keyDirection = eSIR_RX_ONLY;
12177 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
12178 }
12179 else
12180 {
12181 /* set pairwise key*/
12182 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12183 "%s- %d: setting pairwise key",
12184 __func__, __LINE__);
12185 setKey.keyDirection = eSIR_TX_RX;
12186 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
12187 }
12188 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
12189 {
12190 setKey.keyDirection = eSIR_TX_RX;
12191 /*Set the group key*/
12192 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
12193 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -070012194
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012195 if ( 0 != status )
12196 {
12197 hddLog(VOS_TRACE_LEVEL_ERROR,
12198 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012199 status = -EINVAL;
12200 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012201 }
12202 /*Save the keys here and call sme_RoamSetKey for setting
12203 the PTK after peer joins the IBSS network*/
12204 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
12205 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012206 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012207 }
Gopichand Nakkala29149562013-05-10 21:43:41 +053012208 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
12209 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
12210 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012211 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012212 if( pHostapdState->bssState == BSS_START )
12213 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012214 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12215 vos_status = wlan_hdd_check_ula_done(pAdapter);
12216
12217 if ( vos_status != VOS_STATUS_SUCCESS )
12218 {
12219 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12220 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
12221 __LINE__, vos_status );
12222
12223 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
12224
12225 status = -EINVAL;
12226 goto end;
12227 }
12228
Jeff Johnson295189b2012-06-20 16:38:30 -070012229 status = WLANSAP_SetKeySta( pVosContext, &setKey);
12230
12231 if ( status != eHAL_STATUS_SUCCESS )
12232 {
12233 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12234 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
12235 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012236 status = -EINVAL;
12237 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012238 }
12239 }
12240
12241 /* Saving WEP keys */
12242 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
12243 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
12244 {
12245 //Save the wep key in ap context. Issue setkey after the BSS is started.
12246 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
12247 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
12248 }
12249 else
12250 {
12251 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012252 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012253 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
12254 }
12255 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012256 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
12257 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012258 {
12259 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12260 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12261
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012262#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12263 if (!pairwise)
12264#else
12265 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
12266#endif
12267 {
12268 /* set group key*/
12269 if (pHddStaCtx->roam_info.deferKeyComplete)
12270 {
12271 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12272 "%s- %d: Perform Set key Complete",
12273 __func__, __LINE__);
12274 hdd_PerformRoamSetKeyComplete(pAdapter);
12275 }
12276 }
12277
Jeff Johnson295189b2012-06-20 16:38:30 -070012278 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
12279
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -080012280 pWextState->roamProfile.Keys.defaultIndex = key_index;
12281
12282
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012283 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070012284 params->key, params->key_len);
12285
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012286
Jeff Johnson295189b2012-06-20 16:38:30 -070012287 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
12288
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012289 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070012290 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012291 __func__, setKey.peerMac[0], setKey.peerMac[1],
12292 setKey.peerMac[2], setKey.peerMac[3],
12293 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070012294 setKey.keyDirection);
12295
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012296 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +053012297
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012298 if ( vos_status != VOS_STATUS_SUCCESS )
12299 {
12300 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012301 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
12302 __LINE__, vos_status );
12303
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012304 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012305
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012306 status = -EINVAL;
12307 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012308
12309 }
12310
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012311#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012312 /* The supplicant may attempt to set the PTK once pre-authentication
12313 is done. Save the key in the UMAC and include it in the ADD BSS
12314 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012315 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012316 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012317 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012318 hddLog(VOS_TRACE_LEVEL_INFO_MED,
12319 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012320 status = 0;
12321 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012322 }
12323 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
12324 {
12325 hddLog(VOS_TRACE_LEVEL_ERROR,
12326 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012327 status = -EINVAL;
12328 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012329 }
12330#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070012331
12332 /* issue set key request to SME*/
12333 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
12334 pAdapter->sessionId, &setKey, &roamId );
12335
12336 if ( 0 != status )
12337 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012338 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012339 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
12340 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012341 status = -EINVAL;
12342 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012343 }
12344
12345
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012346 /* in case of IBSS as there was no information available about WEP keys during
12347 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070012348 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012349 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
12350 !( ( IW_AUTH_KEY_MGMT_802_1X
12351 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070012352 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
12353 )
12354 &&
12355 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
12356 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
12357 )
12358 )
12359 {
12360 setKey.keyDirection = eSIR_RX_ONLY;
12361 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
12362
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012363 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070012364 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012365 __func__, setKey.peerMac[0], setKey.peerMac[1],
12366 setKey.peerMac[2], setKey.peerMac[3],
12367 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070012368 setKey.keyDirection);
12369
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012370 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070012371 pAdapter->sessionId, &setKey, &roamId );
12372
12373 if ( 0 != status )
12374 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012375 hddLog(VOS_TRACE_LEVEL_ERROR,
12376 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012377 __func__, status);
12378 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012379 status = -EINVAL;
12380 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012381 }
12382 }
12383 }
12384
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012385end:
12386 /* Need to clear any trace of key value in the memory.
12387 * Thus zero out the memory even though it is local
12388 * variable.
12389 */
12390 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012391 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012392 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012393}
12394
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012395#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12396static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
12397 struct net_device *ndev,
12398 u8 key_index, bool pairwise,
12399 const u8 *mac_addr,
12400 struct key_params *params
12401 )
12402#else
12403static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
12404 struct net_device *ndev,
12405 u8 key_index, const u8 *mac_addr,
12406 struct key_params *params
12407 )
12408#endif
12409{
12410 int ret;
12411 vos_ssr_protect(__func__);
12412#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12413 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
12414 mac_addr, params);
12415#else
12416 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
12417 params);
12418#endif
12419 vos_ssr_unprotect(__func__);
12420
12421 return ret;
12422}
12423
Jeff Johnson295189b2012-06-20 16:38:30 -070012424/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012425 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070012426 * This function is used to get the key information
12427 */
12428#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012429static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012430 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012431 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012432 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070012433 const u8 *mac_addr, void *cookie,
12434 void (*callback)(void *cookie, struct key_params*)
12435 )
12436#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012437static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012438 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012439 struct net_device *ndev,
12440 u8 key_index, const u8 *mac_addr, void *cookie,
12441 void (*callback)(void *cookie, struct key_params*)
12442 )
12443#endif
12444{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012445 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012446 hdd_wext_state_t *pWextState = NULL;
12447 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012448 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012449 hdd_context_t *pHddCtx;
12450 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012451
12452 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012453
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012454 if (NULL == pAdapter)
12455 {
12456 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12457 "%s: HDD adapter is Null", __func__);
12458 return -ENODEV;
12459 }
12460
12461 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12462 ret = wlan_hdd_validate_context(pHddCtx);
12463 if (0 != ret)
12464 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012465 return ret;
12466 }
12467
12468 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12469 pRoamProfile = &(pWextState->roamProfile);
12470
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012471 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12472 __func__, hdd_device_modetoString(pAdapter->device_mode),
12473 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012474
Jeff Johnson295189b2012-06-20 16:38:30 -070012475 memset(&params, 0, sizeof(params));
12476
12477 if (CSR_MAX_NUM_KEY <= key_index)
12478 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012479 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070012480 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012481 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012482
12483 switch(pRoamProfile->EncryptionType.encryptionType[0])
12484 {
12485 case eCSR_ENCRYPT_TYPE_NONE:
12486 params.cipher = IW_AUTH_CIPHER_NONE;
12487 break;
12488
12489 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
12490 case eCSR_ENCRYPT_TYPE_WEP40:
12491 params.cipher = WLAN_CIPHER_SUITE_WEP40;
12492 break;
12493
12494 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
12495 case eCSR_ENCRYPT_TYPE_WEP104:
12496 params.cipher = WLAN_CIPHER_SUITE_WEP104;
12497 break;
12498
12499 case eCSR_ENCRYPT_TYPE_TKIP:
12500 params.cipher = WLAN_CIPHER_SUITE_TKIP;
12501 break;
12502
12503 case eCSR_ENCRYPT_TYPE_AES:
12504 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
12505 break;
12506
12507 default:
12508 params.cipher = IW_AUTH_CIPHER_NONE;
12509 break;
12510 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012511
c_hpothuaaf19692014-05-17 17:01:48 +053012512 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12513 TRACE_CODE_HDD_CFG80211_GET_KEY,
12514 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012515
Jeff Johnson295189b2012-06-20 16:38:30 -070012516 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
12517 params.seq_len = 0;
12518 params.seq = NULL;
12519 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
12520 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012521 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012522 return 0;
12523}
12524
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012525#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12526static int wlan_hdd_cfg80211_get_key(
12527 struct wiphy *wiphy,
12528 struct net_device *ndev,
12529 u8 key_index, bool pairwise,
12530 const u8 *mac_addr, void *cookie,
12531 void (*callback)(void *cookie, struct key_params*)
12532 )
12533#else
12534static int wlan_hdd_cfg80211_get_key(
12535 struct wiphy *wiphy,
12536 struct net_device *ndev,
12537 u8 key_index, const u8 *mac_addr, void *cookie,
12538 void (*callback)(void *cookie, struct key_params*)
12539 )
12540#endif
12541{
12542 int ret;
12543
12544 vos_ssr_protect(__func__);
12545#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12546 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
12547 mac_addr, cookie, callback);
12548#else
12549 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
12550 callback);
12551#endif
12552 vos_ssr_unprotect(__func__);
12553
12554 return ret;
12555}
12556
Jeff Johnson295189b2012-06-20 16:38:30 -070012557/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012558 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070012559 * This function is used to delete the key information
12560 */
12561#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012562static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012563 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012564 u8 key_index,
12565 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070012566 const u8 *mac_addr
12567 )
12568#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012569static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012570 struct net_device *ndev,
12571 u8 key_index,
12572 const u8 *mac_addr
12573 )
12574#endif
12575{
12576 int status = 0;
12577
12578 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012579 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070012580 //it is observed that this is invalidating peer
12581 //key index whenever re-key is done. This is affecting data link.
12582 //It should be ok to ignore del_key.
12583#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012584 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
12585 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070012586 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
12587 tCsrRoamSetKey setKey;
12588 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012589
Jeff Johnson295189b2012-06-20 16:38:30 -070012590 ENTER();
12591
12592 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
12593 __func__,pAdapter->device_mode);
12594
12595 if (CSR_MAX_NUM_KEY <= key_index)
12596 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012597 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012598 key_index);
12599
12600 return -EINVAL;
12601 }
12602
12603 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
12604 setKey.keyId = key_index;
12605
12606 if (mac_addr)
12607 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
12608 else
12609 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
12610
12611 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
12612
12613 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012614 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012615 )
12616 {
12617
12618 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070012619 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
12620 if( pHostapdState->bssState == BSS_START)
12621 {
12622 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012623
Jeff Johnson295189b2012-06-20 16:38:30 -070012624 if ( status != eHAL_STATUS_SUCCESS )
12625 {
12626 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12627 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
12628 __LINE__, status );
12629 }
12630 }
12631 }
12632 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012633 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070012634 )
12635 {
12636 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12637
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012638 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
12639
12640 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070012641 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012642 __func__, setKey.peerMac[0], setKey.peerMac[1],
12643 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070012644 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012645 if(pAdapter->sessionCtx.station.conn_info.connState ==
12646 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070012647 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012648 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070012649 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012650
Jeff Johnson295189b2012-06-20 16:38:30 -070012651 if ( 0 != status )
12652 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012653 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012654 "%s: sme_RoamSetKey failure, returned %d",
12655 __func__, status);
12656 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
12657 return -EINVAL;
12658 }
12659 }
12660 }
12661#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070012662 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012663 return status;
12664}
12665
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012666#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12667static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
12668 struct net_device *ndev,
12669 u8 key_index,
12670 bool pairwise,
12671 const u8 *mac_addr
12672 )
12673#else
12674static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
12675 struct net_device *ndev,
12676 u8 key_index,
12677 const u8 *mac_addr
12678 )
12679#endif
12680{
12681 int ret;
12682
12683 vos_ssr_protect(__func__);
12684#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12685 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
12686 mac_addr);
12687#else
12688 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
12689#endif
12690 vos_ssr_unprotect(__func__);
12691
12692 return ret;
12693}
12694
Jeff Johnson295189b2012-06-20 16:38:30 -070012695/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012696 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070012697 * This function is used to set the default tx key index
12698 */
12699#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012700static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012701 struct net_device *ndev,
12702 u8 key_index,
12703 bool unicast, bool multicast)
12704#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012705static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012706 struct net_device *ndev,
12707 u8 key_index)
12708#endif
12709{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012710 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012711 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053012712 hdd_wext_state_t *pWextState;
12713 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012714 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012715
12716 ENTER();
12717
Gopichand Nakkala29149562013-05-10 21:43:41 +053012718 if ((NULL == pAdapter))
12719 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012720 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053012721 "invalid adapter");
12722 return -EINVAL;
12723 }
12724
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012725 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12726 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
12727 pAdapter->sessionId, key_index));
12728
Gopichand Nakkala29149562013-05-10 21:43:41 +053012729 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12730 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12731
12732 if ((NULL == pWextState) || (NULL == pHddStaCtx))
12733 {
12734 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12735 "invalid Wext state or HDD context");
12736 return -EINVAL;
12737 }
12738
Arif Hussain6d2a3322013-11-17 19:50:10 -080012739 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012740 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012741
Jeff Johnson295189b2012-06-20 16:38:30 -070012742 if (CSR_MAX_NUM_KEY <= key_index)
12743 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012744 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012745 key_index);
12746
12747 return -EINVAL;
12748 }
12749
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012750 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12751 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012752 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012753 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012754 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012755 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012756
Jeff Johnson295189b2012-06-20 16:38:30 -070012757 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070012758 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012759 )
Jeff Johnson295189b2012-06-20 16:38:30 -070012760 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053012761 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080012762 pHddStaCtx->conn_info.ucEncryptionType) &&
Hu Wangb1f68cb2017-08-23 20:01:49 +080012763#ifdef FEATURE_WLAN_WAPI
12764 (eCSR_ENCRYPT_TYPE_WPI !=
12765 pHddStaCtx->conn_info.ucEncryptionType) &&
12766#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012767 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080012768 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070012769 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012770 {
12771 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070012772 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012773
Jeff Johnson295189b2012-06-20 16:38:30 -070012774 tCsrRoamSetKey setKey;
12775 v_U32_t roamId= 0xFF;
12776 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012777
12778 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012779 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012780
Jeff Johnson295189b2012-06-20 16:38:30 -070012781 Keys->defaultIndex = (u8)key_index;
12782 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
12783 setKey.keyId = key_index;
12784 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012785
12786 vos_mem_copy(&setKey.Key[0],
12787 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070012788 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012789
Gopichand Nakkala29149562013-05-10 21:43:41 +053012790 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012791
12792 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070012793 &pHddStaCtx->conn_info.bssId[0],
12794 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012795
Gopichand Nakkala29149562013-05-10 21:43:41 +053012796 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
12797 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
12798 eCSR_ENCRYPT_TYPE_WEP104)
12799 {
12800 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
12801 even though ap is configured for WEP-40 encryption. In this canse the key length
12802 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
12803 type(104) and switching encryption type to 40*/
12804 pWextState->roamProfile.EncryptionType.encryptionType[0] =
12805 eCSR_ENCRYPT_TYPE_WEP40;
12806 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
12807 eCSR_ENCRYPT_TYPE_WEP40;
12808 }
12809
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012810 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070012811 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012812
Jeff Johnson295189b2012-06-20 16:38:30 -070012813 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012814 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070012815 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012816
Jeff Johnson295189b2012-06-20 16:38:30 -070012817 if ( 0 != status )
12818 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012819 hddLog(VOS_TRACE_LEVEL_ERROR,
12820 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012821 status);
12822 return -EINVAL;
12823 }
12824 }
12825 }
12826
12827 /* In SoftAp mode setting key direction for default mode */
12828 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
12829 {
12830 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
12831 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
12832 (eCSR_ENCRYPT_TYPE_AES !=
12833 pWextState->roamProfile.EncryptionType.encryptionType[0])
12834 )
12835 {
12836 /* Saving key direction for default key index to TX default */
12837 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
12838 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
12839 }
12840 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012841 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012842 return status;
12843}
12844
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012845#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12846static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
12847 struct net_device *ndev,
12848 u8 key_index,
12849 bool unicast, bool multicast)
12850#else
12851static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
12852 struct net_device *ndev,
12853 u8 key_index)
12854#endif
12855{
12856 int ret;
12857 vos_ssr_protect(__func__);
12858#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12859 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
12860 multicast);
12861#else
12862 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
12863#endif
12864 vos_ssr_unprotect(__func__);
12865
12866 return ret;
12867}
12868
Jeff Johnson295189b2012-06-20 16:38:30 -070012869/*
12870 * FUNCTION: wlan_hdd_cfg80211_inform_bss
12871 * This function is used to inform the BSS details to nl80211 interface.
12872 */
12873static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
12874 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
12875{
12876 struct net_device *dev = pAdapter->dev;
12877 struct wireless_dev *wdev = dev->ieee80211_ptr;
12878 struct wiphy *wiphy = wdev->wiphy;
12879 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
12880 int chan_no;
12881 int ie_length;
12882 const char *ie;
12883 unsigned int freq;
12884 struct ieee80211_channel *chan;
12885 int rssi = 0;
12886 struct cfg80211_bss *bss = NULL;
12887
Jeff Johnson295189b2012-06-20 16:38:30 -070012888 if( NULL == pBssDesc )
12889 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012890 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012891 return bss;
12892 }
12893
12894 chan_no = pBssDesc->channelId;
12895 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
12896 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
12897
12898 if( NULL == ie )
12899 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012900 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012901 return bss;
12902 }
12903
12904#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
12905 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
12906 {
12907 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
12908 }
12909 else
12910 {
12911 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
12912 }
12913#else
12914 freq = ieee80211_channel_to_frequency(chan_no);
12915#endif
12916
12917 chan = __ieee80211_get_channel(wiphy, freq);
12918
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053012919 if (!chan) {
12920 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
12921 return NULL;
12922 }
12923
Abhishek Singhaee43942014-06-16 18:55:47 +053012924 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070012925
Anand N Sunkad9f80b742015-07-30 20:05:51 +053012926 return cfg80211_inform_bss(wiphy, chan,
12927#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12928 CFG80211_BSS_FTYPE_UNKNOWN,
12929#endif
12930 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012931 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070012932 pBssDesc->capabilityInfo,
12933 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053012934 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070012935}
12936
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053012937/*
12938 * wlan_hdd_cfg80211_update_bss_list :to inform nl80211
12939 * interface that BSS might have been lost.
12940 * @pAdapter: adaptor
12941 * @bssid: bssid which might have been lost
12942 *
12943 * Return: bss which is unlinked from kernel cache
12944 */
12945struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_list(
12946 hdd_adapter_t *pAdapter, tSirMacAddr bssid)
12947{
12948 struct net_device *dev = pAdapter->dev;
12949 struct wireless_dev *wdev = dev->ieee80211_ptr;
12950 struct wiphy *wiphy = wdev->wiphy;
12951 struct cfg80211_bss *bss = NULL;
12952
Abhishek Singh5a597e62016-12-05 15:16:30 +053012953 bss = hdd_get_bss_entry(wiphy,
12954 NULL, bssid,
12955 NULL, 0);
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053012956 if (bss == NULL) {
12957 hddLog(LOGE, FL("BSS not present"));
12958 } else {
12959 hddLog(LOG1, FL("cfg80211_unlink_bss called for BSSID "
12960 MAC_ADDRESS_STR), MAC_ADDR_ARRAY(bssid));
12961 cfg80211_unlink_bss(wiphy, bss);
12962 }
12963 return bss;
12964}
Jeff Johnson295189b2012-06-20 16:38:30 -070012965
12966
12967/*
12968 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
12969 * This function is used to inform the BSS details to nl80211 interface.
12970 */
12971struct cfg80211_bss*
12972wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
12973 tSirBssDescription *bss_desc
12974 )
12975{
12976 /*
12977 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
12978 already exists in bss data base of cfg80211 for that particular BSS ID.
12979 Using cfg80211_inform_bss_frame to update the bss entry instead of
12980 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
12981 now there is no possibility to get the mgmt(probe response) frame from PE,
12982 converting bss_desc to ieee80211_mgmt(probe response) and passing to
12983 cfg80211_inform_bss_frame.
12984 */
12985 struct net_device *dev = pAdapter->dev;
12986 struct wireless_dev *wdev = dev->ieee80211_ptr;
12987 struct wiphy *wiphy = wdev->wiphy;
12988 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012989#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
12990 qcom_ie_age *qie_age = NULL;
12991 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
12992#else
Jeff Johnson295189b2012-06-20 16:38:30 -070012993 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012994#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012995 const char *ie =
12996 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
12997 unsigned int freq;
12998 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053012999 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013000 struct cfg80211_bss *bss_status = NULL;
13001 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
13002 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070013003 hdd_context_t *pHddCtx;
13004 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070013005#ifdef WLAN_OPEN_SOURCE
13006 struct timespec ts;
13007#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013008
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013009
Wilson Yangf80a0542013-10-07 13:02:37 -070013010 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13011 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070013012 if (0 != status)
13013 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070013014 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070013015 }
13016
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053013017 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070013018 if (!mgmt)
13019 {
13020 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13021 "%s: memory allocation failed ", __func__);
13022 return NULL;
13023 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070013024
Jeff Johnson295189b2012-06-20 16:38:30 -070013025 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070013026
13027#ifdef WLAN_OPEN_SOURCE
13028 /* Android does not want the timestamp from the frame.
13029 Instead it wants a monotonic increasing value */
13030 get_monotonic_boottime(&ts);
13031 mgmt->u.probe_resp.timestamp =
13032 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
13033#else
13034 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070013035 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
13036 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070013037
13038#endif
13039
Jeff Johnson295189b2012-06-20 16:38:30 -070013040 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
13041 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080013042
13043#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
13044 /* GPS Requirement: need age ie per entry. Using vendor specific. */
13045 /* Assuming this is the last IE, copy at the end */
13046 ie_length -=sizeof(qcom_ie_age);
13047 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
13048 qie_age->element_id = QCOM_VENDOR_IE_ID;
13049 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
13050 qie_age->oui_1 = QCOM_OUI1;
13051 qie_age->oui_2 = QCOM_OUI2;
13052 qie_age->oui_3 = QCOM_OUI3;
13053 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
Selvaraj, Sridhar4b3a8362016-10-12 12:34:08 +053013054 /* Lowi expects the timestamp of bss in units of 1/10 ms. In driver all
13055 * bss related timestamp is in units of ms. Due to this when scan results
13056 * are sent to lowi the scan age is high.To address this, send age in units
13057 * of 1/10 ms.
13058 */
13059 qie_age->age = (vos_timer_get_system_time() -
13060 bss_desc->nReceivedTime)/10;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080013061#endif
13062
Jeff Johnson295189b2012-06-20 16:38:30 -070013063 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053013064 if (bss_desc->fProbeRsp)
13065 {
13066 mgmt->frame_control |=
13067 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
13068 }
13069 else
13070 {
13071 mgmt->frame_control |=
13072 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
13073 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013074
13075#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013076 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070013077 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
13078 {
13079 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
13080 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013081 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070013082 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
13083
13084 {
13085 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
13086 }
13087 else
13088 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013089 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
13090 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070013091 kfree(mgmt);
13092 return NULL;
13093 }
13094#else
13095 freq = ieee80211_channel_to_frequency(chan_no);
13096#endif
13097 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080013098 /*when the band is changed on the fly using the GUI, three things are done
13099 * 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)
13100 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
13101 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
13102 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
13103 * and discards the channels correponding to previous band and calls back with zero bss results.
13104 * 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
13105 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
13106 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
13107 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
13108 * So drop the bss and continue to next bss.
13109 */
13110 if(chan == NULL)
13111 {
Deepthi Gowri306657b2016-04-28 17:10:41 +053013112 hddLog(VOS_TRACE_LEVEL_ERROR,
13113 FL("chan pointer is NULL, chan_no: %d freq: %d"),
13114 chan_no, freq);
Chilam Ngc4244af2013-04-01 15:37:32 -070013115 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080013116 return NULL;
13117 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053013118 /*To keep the rssi icon of the connected AP in the scan window
13119 *and the rssi icon of the wireless networks in sync
13120 * */
13121 if (( eConnectionState_Associated ==
13122 pAdapter->sessionCtx.station.conn_info.connState ) &&
13123 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
13124 pAdapter->sessionCtx.station.conn_info.bssId,
13125 WNI_CFG_BSSID_LEN)) &&
13126 (pHddCtx->hdd_wlan_suspended == FALSE))
13127 {
13128 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
13129 rssi = (pAdapter->rssi * 100);
13130 }
13131 else
13132 {
13133 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
13134 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013135
Nirav Shah20ac06f2013-12-12 18:14:06 +053013136 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053013137 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
13138 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053013139
Jeff Johnson295189b2012-06-20 16:38:30 -070013140 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
13141 frame_len, rssi, GFP_KERNEL);
13142 kfree(mgmt);
13143 return bss_status;
13144}
13145
13146/*
13147 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
13148 * This function is used to update the BSS data base of CFG8011
13149 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013150struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070013151 tCsrRoamInfo *pRoamInfo
13152 )
13153{
13154 tCsrRoamConnectedProfile roamProfile;
13155 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13156 struct cfg80211_bss *bss = NULL;
13157
13158 ENTER();
13159
13160 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
13161 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
13162
13163 if (NULL != roamProfile.pBssDesc)
13164 {
Girish Gowlif4b68022014-08-28 23:18:57 +053013165 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
13166 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070013167
13168 if (NULL == bss)
13169 {
13170 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
13171 __func__);
13172 }
13173
13174 sme_RoamFreeConnectProfile(hHal, &roamProfile);
13175 }
13176 else
13177 {
13178 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
13179 __func__);
13180 }
13181 return bss;
13182}
13183
13184/*
13185 * FUNCTION: wlan_hdd_cfg80211_update_bss
13186 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013187static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
13188 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070013189 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013190{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013191 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013192 tCsrScanResultInfo *pScanResult;
13193 eHalStatus status = 0;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013194 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013195 tScanResultHandle pResult;
13196 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070013197 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013198 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070013199 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013200
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013201 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13202 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
13203 NO_SESSION, pAdapter->sessionId));
13204
Wilson Yangf80a0542013-10-07 13:02:37 -070013205 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013206 ret = wlan_hdd_validate_context(pHddCtx);
13207 if (0 != ret)
Jeff Johnson295189b2012-06-20 16:38:30 -070013208 {
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013209 return ret;
Wilson Yangf80a0542013-10-07 13:02:37 -070013210 }
13211
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013212 if (pAdapter->request != NULL)
13213 {
13214 if ((pAdapter->request->n_ssids == 1)
13215 && (pAdapter->request->ssids != NULL)
13216 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
13217 is_p2p_scan = true;
13218 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013219 /*
13220 * start getting scan results and populate cgf80211 BSS database
13221 */
13222 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
13223
13224 /* no scan results */
13225 if (NULL == pResult)
13226 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013227 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
13228 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053013229 wlan_hdd_get_frame_logs(pAdapter,
13230 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070013231 return status;
13232 }
13233
13234 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
13235
13236 while (pScanResult)
13237 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013238 /*
13239 * cfg80211_inform_bss() is not updating ie field of bss entry, if
13240 * entry already exists in bss data base of cfg80211 for that
13241 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
13242 * bss entry instead of cfg80211_inform_bss, But this call expects
13243 * mgmt packet as input. As of now there is no possibility to get
13244 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070013245 * ieee80211_mgmt(probe response) and passing to c
13246 * fg80211_inform_bss_frame.
13247 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013248 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
13249 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
13250 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013251 pScanResult = sme_ScanResultGetNext(hHal, pResult);
13252 continue; //Skip the non p2p bss entries
13253 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013254 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
13255 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013256
Jeff Johnson295189b2012-06-20 16:38:30 -070013257
13258 if (NULL == bss_status)
13259 {
13260 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013261 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013262 }
13263 else
13264 {
Yue Maf49ba872013-08-19 12:04:25 -070013265 cfg80211_put_bss(
13266#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
13267 wiphy,
13268#endif
13269 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070013270 }
13271
13272 pScanResult = sme_ScanResultGetNext(hHal, pResult);
13273 }
13274
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013275 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013276 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013277 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013278}
13279
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013280void
13281hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
13282{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013283 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080013284 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013285} /****** end hddPrintMacAddr() ******/
13286
13287void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070013288hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013289{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013290 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013291 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070013292 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
13293 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
13294 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013295} /****** end hddPrintPmkId() ******/
13296
13297//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
13298//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
13299
13300//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
13301//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
13302
13303#define dump_bssid(bssid) \
13304 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070013305 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
13306 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013307 }
13308
13309#define dump_pmkid(pMac, pmkid) \
13310 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070013311 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
13312 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013313 }
13314
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070013315#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013316/*
13317 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
13318 * This function is used to notify the supplicant of a new PMKSA candidate.
13319 */
13320int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013321 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013322 int index, bool preauth )
13323{
Jeff Johnsone7245742012-09-05 17:12:55 -070013324#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013325 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070013326 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013327
13328 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070013329 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013330
13331 if( NULL == pRoamInfo )
13332 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013333 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013334 return -EINVAL;
13335 }
13336
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070013337 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
13338 {
13339 dump_bssid(pRoamInfo->bssid);
13340 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013341 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070013342 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013343#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013344 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013345}
13346#endif //FEATURE_WLAN_LFR
13347
Yue Maef608272013-04-08 23:09:17 -070013348#ifdef FEATURE_WLAN_LFR_METRICS
13349/*
13350 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
13351 * 802.11r/LFR metrics reporting function to report preauth initiation
13352 *
13353 */
13354#define MAX_LFR_METRICS_EVENT_LENGTH 100
13355VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
13356 tCsrRoamInfo *pRoamInfo)
13357{
13358 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
13359 union iwreq_data wrqu;
13360
13361 ENTER();
13362
13363 if (NULL == pAdapter)
13364 {
13365 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
13366 return VOS_STATUS_E_FAILURE;
13367 }
13368
13369 /* create the event */
13370 memset(&wrqu, 0, sizeof(wrqu));
13371 memset(metrics_notification, 0, sizeof(metrics_notification));
13372
13373 wrqu.data.pointer = metrics_notification;
13374 wrqu.data.length = scnprintf(metrics_notification,
13375 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
13376 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
13377
13378 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
13379
13380 EXIT();
13381
13382 return VOS_STATUS_SUCCESS;
13383}
13384
13385/*
13386 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
13387 * 802.11r/LFR metrics reporting function to report preauth completion
13388 * or failure
13389 */
13390VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
13391 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
13392{
13393 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
13394 union iwreq_data wrqu;
13395
13396 ENTER();
13397
13398 if (NULL == pAdapter)
13399 {
13400 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
13401 return VOS_STATUS_E_FAILURE;
13402 }
13403
13404 /* create the event */
13405 memset(&wrqu, 0, sizeof(wrqu));
13406 memset(metrics_notification, 0, sizeof(metrics_notification));
13407
13408 scnprintf(metrics_notification, sizeof(metrics_notification),
13409 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
13410 MAC_ADDR_ARRAY(pRoamInfo->bssid));
13411
13412 if (1 == preauth_status)
13413 strncat(metrics_notification, " TRUE", 5);
13414 else
13415 strncat(metrics_notification, " FALSE", 6);
13416
13417 wrqu.data.pointer = metrics_notification;
13418 wrqu.data.length = strlen(metrics_notification);
13419
13420 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
13421
13422 EXIT();
13423
13424 return VOS_STATUS_SUCCESS;
13425}
13426
13427/*
13428 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
13429 * 802.11r/LFR metrics reporting function to report handover initiation
13430 *
13431 */
13432VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
13433 tCsrRoamInfo *pRoamInfo)
13434{
13435 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
13436 union iwreq_data wrqu;
13437
13438 ENTER();
13439
13440 if (NULL == pAdapter)
13441 {
13442 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
13443 return VOS_STATUS_E_FAILURE;
13444 }
13445
13446 /* create the event */
13447 memset(&wrqu, 0, sizeof(wrqu));
13448 memset(metrics_notification, 0, sizeof(metrics_notification));
13449
13450 wrqu.data.pointer = metrics_notification;
13451 wrqu.data.length = scnprintf(metrics_notification,
13452 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
13453 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
13454
13455 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
13456
13457 EXIT();
13458
13459 return VOS_STATUS_SUCCESS;
13460}
13461#endif
13462
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013463
13464/**
13465 * wlan_hdd_cfg80211_validate_scan_req - validate scan request
13466 * @scan_req: scan request to be checked
13467 *
13468 * Return: true or false
13469 */
13470#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
13471static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
13472 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053013473 *scan_req, hdd_context_t
13474 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013475{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053013476 if (!scan_req || !scan_req->wiphy ||
13477 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013478 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
13479 return false;
13480 }
13481 if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HDD, NULL)) {
13482 hddLog(VOS_TRACE_LEVEL_ERROR, "Load/Unload in progress");
13483 return false;
13484 }
13485 return true;
13486}
13487#else
13488static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
13489 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053013490 *scan_req, hdd_context_t
13491 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013492{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053013493 if (!scan_req || !scan_req->wiphy ||
13494 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013495 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
13496 return false;
13497 }
13498 return true;
13499}
13500#endif
13501
13502
Jeff Johnson295189b2012-06-20 16:38:30 -070013503/*
13504 * FUNCTION: hdd_cfg80211_scan_done_callback
13505 * scanning callback function, called after finishing scan
13506 *
13507 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013508static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070013509 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
13510{
13511 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013512 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070013513 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013514 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070013515 struct cfg80211_scan_request *req = NULL;
13516 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053013517 bool aborted = false;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013518#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
13519 bool iface_down = false;
13520#endif
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013521 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013522 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013523 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013524
13525 ENTER();
13526
c_manjee1b4ab9a2016-10-26 11:36:55 +053013527 if (!pAdapter || pAdapter->magic != WLAN_HDD_ADAPTER_MAGIC ||
13528 !pAdapter->dev) {
13529 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Adapter is not valid"));
13530 return 0;
13531 }
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013532 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053013533 if (NULL == pHddCtx) {
13534 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013535 return 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013536 }
13537
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053013538#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
13539 if (!(pAdapter->dev->flags & IFF_UP))
13540 {
13541 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Interface is down"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013542 iface_down = true;
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053013543 }
13544#endif
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013545 pScanInfo = &pHddCtx->scan_info;
13546
Jeff Johnson295189b2012-06-20 16:38:30 -070013547 hddLog(VOS_TRACE_LEVEL_INFO,
13548 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080013549 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013550 __func__, halHandle, pContext, (int) scanId, (int) status);
13551
Kiet Lamac06e2c2013-10-23 16:25:07 +053013552 pScanInfo->mScanPendingCounter = 0;
13553
Jeff Johnson295189b2012-06-20 16:38:30 -070013554 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013555 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070013556 &pScanInfo->scan_req_completion_event,
13557 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013558 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070013559 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013560 hddLog(VOS_TRACE_LEVEL_ERROR,
13561 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070013562 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070013563 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070013564 }
13565
Yue Maef608272013-04-08 23:09:17 -070013566 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070013567 {
13568 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070013569 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070013570 }
13571
13572 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013573 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070013574 {
13575 hddLog(VOS_TRACE_LEVEL_INFO,
13576 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080013577 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070013578 (int) scanId);
13579 }
13580
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053013581#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013582 if (!iface_down)
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053013583#endif
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013584 {
13585 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
13586 pAdapter);
13587 if (0 > ret)
13588 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053013589 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013590
Jeff Johnson295189b2012-06-20 16:38:30 -070013591 /* If any client wait scan result through WEXT
13592 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013593 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070013594 {
13595 /* The other scan request waiting for current scan finish
13596 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013597 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070013598 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013599 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070013600 }
13601 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013602 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070013603 {
13604 struct net_device *dev = pAdapter->dev;
13605 union iwreq_data wrqu;
13606 int we_event;
13607 char *msg;
13608
13609 memset(&wrqu, '\0', sizeof(wrqu));
13610 we_event = SIOCGIWSCAN;
13611 msg = NULL;
13612 wireless_send_event(dev, we_event, &wrqu, msg);
13613 }
13614 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013615 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013616
13617 /* Get the Scan Req */
13618 req = pAdapter->request;
mukul sharmae7041822015-12-03 15:09:21 +053013619 pAdapter->request = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013620
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013621 /* Scan is no longer pending */
13622 pScanInfo->mScanPending = VOS_FALSE;
13623
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053013624 if (!wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Jeff Johnson295189b2012-06-20 16:38:30 -070013625 {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013626#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
13627 hddLog(VOS_TRACE_LEVEL_ERROR, FL("interface state %s"),
13628 iface_down ? "up" : "down");
13629#endif
13630
13631 if (pAdapter->dev) {
13632 hddLog(VOS_TRACE_LEVEL_ERROR, FL("device name %s"),
13633 pAdapter->dev->name);
13634 }
mukul sharmae7041822015-12-03 15:09:21 +053013635 complete(&pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -070013636 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070013637 }
13638
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013639 /* last_scan_timestamp is used to decide if new scan
13640 * is needed or not on station interface. If last station
13641 * scan time and new station scan time is less then
13642 * last_scan_timestamp ; driver will return cached scan.
13643 */
13644 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
13645 {
13646 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
13647
13648 if ( req->n_channels )
13649 {
13650 for (i = 0; i < req->n_channels ; i++ )
13651 {
13652 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
13653 }
13654 /* store no of channel scanned */
13655 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
13656 }
13657
13658 }
13659
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070013660 /*
13661 * cfg80211_scan_done informing NL80211 about completion
13662 * of scanning
13663 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053013664 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
13665 {
13666 aborted = true;
13667 }
mukul sharmae7041822015-12-03 15:09:21 +053013668
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013669#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
13670 if (!iface_down)
13671#endif
13672 cfg80211_scan_done(req, aborted);
mukul sharmae7041822015-12-03 15:09:21 +053013673
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080013674 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070013675
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013676allow_suspend:
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053013677 if ((pHddCtx->cfg_ini->enableMacSpoofing == MAC_ADDR_SPOOFING_FW_HOST_ENABLE
13678 ) && (pHddCtx->spoofMacAddr.isEnabled
13679 || pHddCtx->spoofMacAddr.isReqDeferred)) {
Siddharth Bhal76972212014-10-15 16:22:51 +053013680 /* Generate new random mac addr for next scan */
13681 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +053013682
13683 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
13684 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhal76972212014-10-15 16:22:51 +053013685 }
13686
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070013687 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013688 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070013689
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070013690 /* Acquire wakelock to handle the case where APP's tries to suspend
13691 * immediatly after the driver gets connect request(i.e after scan)
13692 * from supplicant, this result in app's is suspending and not able
13693 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013694 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070013695
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013696#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
13697 if (!iface_down)
13698#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070013699#ifdef FEATURE_WLAN_TDLS
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013700 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070013701#endif
13702
Jeff Johnson295189b2012-06-20 16:38:30 -070013703 EXIT();
13704 return 0;
13705}
13706
13707/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053013708 * FUNCTION: hdd_isConnectionInProgress
13709 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013710 *
13711 */
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013712v_BOOL_t hdd_isConnectionInProgress(hdd_context_t *pHddCtx, v_U8_t *session_id,
13713 scan_reject_states *reason)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013714{
13715 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
13716 hdd_station_ctx_t *pHddStaCtx = NULL;
13717 hdd_adapter_t *pAdapter = NULL;
13718 VOS_STATUS status = 0;
13719 v_U8_t staId = 0;
13720 v_U8_t *staMac = NULL;
13721
13722 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
13723
13724 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
13725 {
13726 pAdapter = pAdapterNode->pAdapter;
13727
13728 if( pAdapter )
13729 {
13730 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013731 "%s: Adapter with device mode %s (%d) exists",
13732 __func__, hdd_device_modetoString(pAdapter->device_mode),
13733 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013734 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053013735 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
13736 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
13737 (eConnectionState_Connecting ==
13738 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
13739 {
13740 hddLog(VOS_TRACE_LEVEL_ERROR,
13741 "%s: %p(%d) Connection is in progress", __func__,
13742 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013743 if (session_id && reason)
13744 {
13745 *session_id = pAdapter->sessionId;
13746 *reason = eHDD_CONNECTION_IN_PROGRESS;
13747 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053013748 return VOS_TRUE;
13749 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013750 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053013751 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013752 {
13753 hddLog(VOS_TRACE_LEVEL_ERROR,
13754 "%s: %p(%d) Reassociation is in progress", __func__,
13755 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013756 if (session_id && reason)
13757 {
13758 *session_id = pAdapter->sessionId;
13759 *reason = eHDD_REASSOC_IN_PROGRESS;
13760 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013761 return VOS_TRUE;
13762 }
13763 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013764 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
13765 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013766 {
13767 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13768 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013769 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013770 {
13771 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
13772 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080013773 "%s: client " MAC_ADDRESS_STR
13774 " is in the middle of WPS/EAPOL exchange.", __func__,
13775 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013776 if (session_id && reason)
13777 {
13778 *session_id = pAdapter->sessionId;
13779 *reason = eHDD_EAPOL_IN_PROGRESS;
13780 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053013781 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013782 }
13783 }
13784 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
13785 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
13786 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013787 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
13788 ptSapContext pSapCtx = NULL;
13789 pSapCtx = VOS_GET_SAP_CB(pVosContext);
13790 if(pSapCtx == NULL){
13791 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13792 FL("psapCtx is NULL"));
13793 return VOS_FALSE;
13794 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013795 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
13796 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013797 if ((pSapCtx->aStaInfo[staId].isUsed) &&
13798 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013799 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013800 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013801
13802 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080013803 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
13804 "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_SAP_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 }
13815 }
13816 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13817 pAdapterNode = pNext;
13818 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053013819 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013820}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013821
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053013822/**
13823 * csr_scan_request_assign_bssid() - Set the BSSID received from Supplicant
13824 * to the Scan request
13825 * @scanRequest: Pointer to the csr scan request
13826 * @request: Pointer to the scan request from supplicant
13827 *
13828 * Return: None
13829 */
13830#ifdef CFG80211_SCAN_BSSID
13831static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
13832 struct cfg80211_scan_request *request)
13833{
13834 vos_mem_copy(scanRequest->bssid, request->bssid, VOS_MAC_ADDR_SIZE);
13835}
13836#else
13837static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
13838 struct cfg80211_scan_request *request)
13839{
13840}
13841#endif
13842
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013843/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013844 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070013845 * this scan respond to scan trigger and update cfg80211 scan database
13846 * later, scan dump command can be used to recieve scan results
13847 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013848int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080013849#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13850 struct net_device *dev,
13851#endif
13852 struct cfg80211_scan_request *request)
13853{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013854 hdd_adapter_t *pAdapter = NULL;
13855 hdd_context_t *pHddCtx = NULL;
13856 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013857 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013858 tCsrScanRequest scanRequest;
13859 tANI_U8 *channelList = NULL, i;
13860 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013861 int status;
13862 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013863 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013864 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053013865 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013866 bool is_p2p_scan = false;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013867 v_U8_t curr_session_id;
13868 scan_reject_states curr_reason;
Jeff Johnson295189b2012-06-20 16:38:30 -070013869
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013870#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
13871 struct net_device *dev = NULL;
13872 if (NULL == request)
13873 {
13874 hddLog(VOS_TRACE_LEVEL_ERROR,
13875 "%s: scan req param null", __func__);
13876 return -EINVAL;
13877 }
13878 dev = request->wdev->netdev;
13879#endif
13880
13881 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
13882 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
13883 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13884
Jeff Johnson295189b2012-06-20 16:38:30 -070013885 ENTER();
13886
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013887 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13888 __func__, hdd_device_modetoString(pAdapter->device_mode),
13889 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013890
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013891 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013892 if (0 != status)
13893 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013894 return status;
13895 }
13896
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013897 if (NULL == pwextBuf)
13898 {
13899 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
13900 __func__);
13901 return -EIO;
13902 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013903 cfg_param = pHddCtx->cfg_ini;
13904 pScanInfo = &pHddCtx->scan_info;
13905
Jeff Johnson295189b2012-06-20 16:38:30 -070013906#ifdef WLAN_BTAMP_FEATURE
13907 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013908 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070013909 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080013910 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013911 "%s: No scanning when AMP is on", __func__);
13912 return -EOPNOTSUPP;
13913 }
13914#endif
13915 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013916 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070013917 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013918 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013919 "%s: Not scanning on device_mode = %s (%d)",
13920 __func__, hdd_device_modetoString(pAdapter->device_mode),
13921 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013922 return -EOPNOTSUPP;
13923 }
13924
13925 if (TRUE == pScanInfo->mScanPending)
13926 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053013927 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
13928 {
13929 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
13930 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013931 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070013932 }
13933
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053013934 // Don't allow scan if PNO scan is going on.
13935 if (pHddCtx->isPnoEnable)
13936 {
13937 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13938 FL("pno scan in progress"));
13939 return -EBUSY;
13940 }
13941
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013942 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070013943 //Channel and action frame is pending
13944 //Otherwise Cancel Remain On Channel and allow Scan
13945 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013946 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070013947 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053013948 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070013949 return -EBUSY;
13950 }
13951
Jeff Johnson295189b2012-06-20 16:38:30 -070013952 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
13953 {
13954 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080013955 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013956 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013957 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013958 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
13959 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013960 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013961 "%s: MAX TM Level Scan not allowed", __func__);
13962 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013963 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070013964 }
13965 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
13966
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013967 /* Check if scan is allowed at this point of time.
13968 */
Hanumanth Reddy Pothulaec960842016-09-14 19:04:26 +053013969 if (TRUE == pHddCtx->btCoexModeSet)
13970 {
13971 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13972 FL("BTCoex Mode operation in progress"));
13973 return -EBUSY;
13974 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013975 if (hdd_isConnectionInProgress(pHddCtx, &curr_session_id, &curr_reason))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013976 {
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053013977 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Scan not allowed"));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013978 if (pHddCtx->last_scan_reject_session_id != curr_session_id ||
13979 pHddCtx->last_scan_reject_reason != curr_reason ||
13980 !pHddCtx->last_scan_reject_timestamp)
13981 {
13982 pHddCtx->last_scan_reject_session_id = curr_session_id;
13983 pHddCtx->last_scan_reject_reason = curr_reason;
Abhishek Singh3e500772017-07-17 10:13:43 +053013984 pHddCtx->last_scan_reject_timestamp =
13985 jiffies_to_msecs(jiffies) + SCAN_REJECT_THRESHOLD_TIME;
Abhishek Singhe4b12562017-06-20 16:53:39 +053013986 pHddCtx->scan_reject_cnt = 0;
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053013987 }
Abhishek Singhe4b12562017-06-20 16:53:39 +053013988 else
13989 {
13990 pHddCtx->scan_reject_cnt++;
13991
Abhishek Singh3e500772017-07-17 10:13:43 +053013992 hddLog(LOGE, FL("Session %d reason %d reject cnt %d threshold time has elapsed? %d"),
13993 curr_session_id, curr_reason, pHddCtx->scan_reject_cnt,
13994 vos_system_time_after(jiffies_to_msecs(jiffies),
Abhishek Singhe4b12562017-06-20 16:53:39 +053013995 pHddCtx->last_scan_reject_timestamp));
13996
13997 if ((pHddCtx->scan_reject_cnt >=
13998 SCAN_REJECT_THRESHOLD) &&
Abhishek Singh3e500772017-07-17 10:13:43 +053013999 vos_system_time_after(jiffies_to_msecs(jiffies),
14000 pHddCtx->last_scan_reject_timestamp))
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014001 {
14002 pHddCtx->last_scan_reject_timestamp = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053014003 pHddCtx->scan_reject_cnt = 0;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014004 if (pHddCtx->cfg_ini->enableFatalEvent)
14005 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
14006 WLAN_LOG_INDICATOR_HOST_DRIVER,
14007 WLAN_LOG_REASON_SCAN_NOT_ALLOWED,
14008 FALSE, FALSE);
14009 else
14010 {
14011 hddLog(LOGE, FL("Triggering SSR"));
14012 vos_wlanRestart();
14013 }
14014 }
14015 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014016 return -EBUSY;
14017 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014018 pHddCtx->last_scan_reject_timestamp = 0;
14019 pHddCtx->last_scan_reject_session_id = 0xFF;
14020 pHddCtx->last_scan_reject_reason = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053014021 pHddCtx->scan_reject_cnt = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014022
Jeff Johnson295189b2012-06-20 16:38:30 -070014023 vos_mem_zero( &scanRequest, sizeof(scanRequest));
14024
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014025 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
14026 * Becasue of this, driver is assuming that this is not wildcard scan and so
14027 * is not aging out the scan results.
14028 */
14029 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070014030 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014031 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014032 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014033
14034 if ((request->ssids) && (0 < request->n_ssids))
14035 {
14036 tCsrSSIDInfo *SsidInfo;
14037 int j;
14038 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
14039 /* Allocate num_ssid tCsrSSIDInfo structure */
14040 SsidInfo = scanRequest.SSIDs.SSIDList =
14041 ( tCsrSSIDInfo *)vos_mem_malloc(
14042 request->n_ssids*sizeof(tCsrSSIDInfo));
14043
14044 if(NULL == scanRequest.SSIDs.SSIDList)
14045 {
14046 hddLog(VOS_TRACE_LEVEL_ERROR,
14047 "%s: memory alloc failed SSIDInfo buffer", __func__);
14048 return -ENOMEM;
14049 }
14050
14051 /* copy all the ssid's and their length */
14052 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
14053 {
14054 /* get the ssid length */
14055 SsidInfo->SSID.length = request->ssids[j].ssid_len;
14056 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
14057 SsidInfo->SSID.length);
14058 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
14059 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
14060 j, SsidInfo->SSID.ssId);
14061 }
14062 /* set the scan type to active */
14063 scanRequest.scanType = eSIR_ACTIVE_SCAN;
14064 }
14065 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070014066 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053014067 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14068 TRACE_CODE_HDD_CFG80211_SCAN,
14069 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070014070 /* set the scan type to active */
14071 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070014072 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014073 else
14074 {
14075 /*Set the scan type to default type, in this case it is ACTIVE*/
14076 scanRequest.scanType = pScanInfo->scan_mode;
14077 }
14078 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
14079 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070014080
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053014081 csr_scan_request_assign_bssid(&scanRequest, request);
14082
Jeff Johnson295189b2012-06-20 16:38:30 -070014083 /* set BSSType to default type */
14084 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
14085
14086 /*TODO: scan the requested channels only*/
14087
14088 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014089 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070014090 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014091 hddLog(VOS_TRACE_LEVEL_WARN,
14092 "No of Scan Channels exceeded limit: %d", request->n_channels);
14093 request->n_channels = MAX_CHANNEL;
14094 }
14095
14096 hddLog(VOS_TRACE_LEVEL_INFO,
14097 "No of Scan Channels: %d", request->n_channels);
14098
14099
14100 if( request->n_channels )
14101 {
14102 char chList [(request->n_channels*5)+1];
14103 int len;
14104 channelList = vos_mem_malloc( request->n_channels );
14105 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053014106 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014107 hddLog(VOS_TRACE_LEVEL_ERROR,
14108 "%s: memory alloc failed channelList", __func__);
14109 status = -ENOMEM;
14110 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053014111 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014112
14113 for( i = 0, len = 0; i < request->n_channels ; i++ )
14114 {
14115 channelList[i] = request->channels[i]->hw_value;
14116 len += snprintf(chList+len, 5, "%d ", channelList[i]);
14117 }
14118
Nirav Shah20ac06f2013-12-12 18:14:06 +053014119 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014120 "Channel-List: %s ", chList);
14121 }
c_hpothu53512302014-04-15 18:49:53 +053014122
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014123 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
14124 scanRequest.ChannelInfo.ChannelList = channelList;
14125
14126 /* set requestType to full scan */
14127 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
14128
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014129 /* if there is back to back scan happening in driver with in
14130 * nDeferScanTimeInterval interval driver should defer new scan request
14131 * and should provide last cached scan results instead of new channel list.
14132 * This rule is not applicable if scan is p2p scan.
14133 * This condition will work only in case when last request no of channels
14134 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053014135 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053014136 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014137 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014138
Sushant Kaushik86592172015-04-27 16:35:03 +053014139 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
14140 /* if wps ie is NULL , then only defer scan */
14141 if ( pWpsIe == NULL &&
14142 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053014143 {
14144 if ( pScanInfo->last_scan_timestamp !=0 &&
14145 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
14146 {
14147 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
14148 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
14149 vos_mem_compare(pScanInfo->last_scan_channelList,
14150 channelList, pScanInfo->last_scan_numChannels))
14151 {
14152 hddLog(VOS_TRACE_LEVEL_WARN,
14153 " New and old station scan time differ is less then %u",
14154 pHddCtx->cfg_ini->nDeferScanTimeInterval);
14155
14156 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014157 pAdapter);
14158
Agarwal Ashish57e84372014-12-05 18:26:53 +053014159 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053014160 "Return old cached scan as all channels and no of channels are same");
14161
Agarwal Ashish57e84372014-12-05 18:26:53 +053014162 if (0 > ret)
14163 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014164
Agarwal Ashish57e84372014-12-05 18:26:53 +053014165 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053014166
14167 status = eHAL_STATUS_SUCCESS;
14168 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053014169 }
14170 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014171 }
14172
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014173 /* Flush the scan results(only p2p beacons) for STA scan and P2P
14174 * search (Flush on both full scan and social scan but not on single
14175 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
14176 */
14177
14178 /* Supplicant does single channel scan after 8-way handshake
14179 * and in that case driver shoudnt flush scan results. If
14180 * driver flushes the scan results here and unfortunately if
14181 * the AP doesnt respond to our probe req then association
14182 * fails which is not desired
14183 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053014184 if ((request->n_ssids == 1)
14185 && (request->ssids != NULL)
14186 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
14187 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014188
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053014189 if( is_p2p_scan ||
14190 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014191 {
14192 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
14193 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
14194 pAdapter->sessionId );
14195 }
14196
14197 if( request->ie_len )
14198 {
14199 /* save this for future association (join requires this) */
14200 /*TODO: Array needs to be converted to dynamic allocation,
14201 * as multiple ie.s can be sent in cfg80211_scan_request structure
14202 * CR 597966
14203 */
14204 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
14205 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
14206 pScanInfo->scanAddIE.length = request->ie_len;
14207
14208 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
14209 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
14210 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070014211 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014212 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070014213 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014214 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
14215 memcpy( pwextBuf->roamProfile.addIEScan,
14216 request->ie, request->ie_len);
14217 }
14218 else
14219 {
14220 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
14221 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070014222 }
14223
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014224 }
14225 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
14226 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
14227
14228 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
14229 request->ie_len);
14230 if (pP2pIe != NULL)
14231 {
14232#ifdef WLAN_FEATURE_P2P_DEBUG
14233 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
14234 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
14235 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053014236 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014237 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
14238 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
14239 "Go nego completed to Connection is started");
14240 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
14241 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053014242 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014243 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
14244 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070014245 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014246 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
14247 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
14248 "Disconnected state to Connection is started");
14249 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
14250 "for 4way Handshake");
14251 }
14252#endif
14253
14254 /* no_cck will be set during p2p find to disable 11b rates */
14255 if(TRUE == request->no_cck)
14256 {
14257 hddLog(VOS_TRACE_LEVEL_INFO,
14258 "%s: This is a P2P Search", __func__);
14259 scanRequest.p2pSearch = 1;
14260
14261 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053014262 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014263 /* set requestType to P2P Discovery */
14264 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
14265 }
14266
14267 /*
14268 Skip Dfs Channel in case of P2P Search
14269 if it is set in ini file
14270 */
14271 if(cfg_param->skipDfsChnlInP2pSearch)
14272 {
14273 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053014274 }
14275 else
14276 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014277 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053014278 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014279
Agarwal Ashish4f616132013-12-30 23:32:50 +053014280 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014281 }
14282 }
14283
14284 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
14285
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014286#ifdef FEATURE_WLAN_TDLS
14287 /* if tdls disagree scan right now, return immediately.
14288 tdls will schedule the scan when scan is allowed. (return SUCCESS)
14289 or will reject the scan if any TDLS is in progress. (return -EBUSY)
14290 */
14291 status = wlan_hdd_tdls_scan_callback (pAdapter,
14292 wiphy,
14293#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
14294 dev,
14295#endif
14296 request);
Abhishek Singhe2b63952016-01-05 18:27:29 +053014297 if (status <= 0)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014298 {
Abhishek Singhe2b63952016-01-05 18:27:29 +053014299 if (!status)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014300 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
14301 "scan rejected %d", __func__, status);
14302 else
14303 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
14304 __func__, status);
Abhishek Singhe2b63952016-01-05 18:27:29 +053014305 hdd_wlan_block_scan_by_tdls();
Gupta, Kapil2ebf3e02016-03-17 19:45:19 +053014306 goto free_mem;
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014307 }
14308#endif
14309
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070014310 /* acquire the wakelock to avoid the apps suspend during the scan. To
14311 * address the following issues.
14312 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
14313 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
14314 * for long time, this result in apps running at full power for long time.
14315 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
14316 * be stuck in full power because of resume BMPS
14317 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014318 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070014319
Nirav Shah20ac06f2013-12-12 18:14:06 +053014320 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
14321 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014322 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
14323 scanRequest.requestType, scanRequest.scanType,
14324 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053014325 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
14326
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053014327 if (pHddCtx->spoofMacAddr.isEnabled &&
14328 pHddCtx->cfg_ini->enableMacSpoofing == 1)
Siddharth Bhal76972212014-10-15 16:22:51 +053014329 {
14330 hddLog(VOS_TRACE_LEVEL_INFO,
14331 "%s: MAC Spoofing enabled for current scan", __func__);
14332 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
14333 * to fill TxBds for probe request during current scan
14334 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053014335 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053014336 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053014337
14338 if(status != VOS_STATUS_SUCCESS)
14339 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014340 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053014341 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053014342#ifdef FEATURE_WLAN_TDLS
14343 wlan_hdd_tdls_scan_done_callback(pAdapter);
14344#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053014345 goto free_mem;
14346 }
Siddharth Bhal76972212014-10-15 16:22:51 +053014347 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053014348 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070014349 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070014350 pAdapter->sessionId, &scanRequest, &scanId,
14351 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070014352
Jeff Johnson295189b2012-06-20 16:38:30 -070014353 if (eHAL_STATUS_SUCCESS != status)
14354 {
14355 hddLog(VOS_TRACE_LEVEL_ERROR,
14356 "%s: sme_ScanRequest returned error %d", __func__, status);
14357 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070014358 if(eHAL_STATUS_RESOURCES == status)
14359 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014360 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
14361 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070014362 status = -EBUSY;
14363 } else {
14364 status = -EIO;
14365 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014366 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014367
14368#ifdef FEATURE_WLAN_TDLS
14369 wlan_hdd_tdls_scan_done_callback(pAdapter);
14370#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014371 goto free_mem;
14372 }
14373
14374 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053014375 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070014376 pAdapter->request = request;
14377 pScanInfo->scanId = scanId;
14378
14379 complete(&pScanInfo->scan_req_completion_event);
14380
14381free_mem:
14382 if( scanRequest.SSIDs.SSIDList )
14383 {
14384 vos_mem_free(scanRequest.SSIDs.SSIDList);
14385 }
14386
14387 if( channelList )
14388 vos_mem_free( channelList );
14389
14390 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014391 return status;
14392}
14393
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014394int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
14395#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
14396 struct net_device *dev,
14397#endif
14398 struct cfg80211_scan_request *request)
14399{
14400 int ret;
14401
14402 vos_ssr_protect(__func__);
14403 ret = __wlan_hdd_cfg80211_scan(wiphy,
14404#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
14405 dev,
14406#endif
14407 request);
14408 vos_ssr_unprotect(__func__);
14409
14410 return ret;
14411}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014412
14413void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
14414{
14415 v_U8_t iniDot11Mode =
14416 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
14417 eHddDot11Mode hddDot11Mode = iniDot11Mode;
14418
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014419 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
14420 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014421 switch ( iniDot11Mode )
14422 {
14423 case eHDD_DOT11_MODE_AUTO:
14424 case eHDD_DOT11_MODE_11ac:
14425 case eHDD_DOT11_MODE_11ac_ONLY:
14426#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053014427 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
14428 sme_IsFeatureSupportedByFW(DOT11AC) )
14429 hddDot11Mode = eHDD_DOT11_MODE_11ac;
14430 else
14431 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014432#else
14433 hddDot11Mode = eHDD_DOT11_MODE_11n;
14434#endif
14435 break;
14436 case eHDD_DOT11_MODE_11n:
14437 case eHDD_DOT11_MODE_11n_ONLY:
14438 hddDot11Mode = eHDD_DOT11_MODE_11n;
14439 break;
14440 default:
14441 hddDot11Mode = iniDot11Mode;
14442 break;
14443 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053014444#ifdef WLAN_FEATURE_AP_HT40_24G
14445 if (operationChannel > SIR_11B_CHANNEL_END)
14446#endif
14447 {
14448 /* This call decides required channel bonding mode */
14449 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014450 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
14451 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053014452 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014453}
14454
Jeff Johnson295189b2012-06-20 16:38:30 -070014455/*
14456 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014457 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070014458 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014459int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053014460 const u8 *ssid, size_t ssid_len, const u8 *bssid,
14461 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070014462{
14463 int status = 0;
14464 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080014465 hdd_context_t *pHddCtx;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053014466 hdd_station_ctx_t *hdd_sta_ctx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014467 v_U32_t roamId;
14468 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070014469 eCsrAuthType RSNAuthType;
14470
14471 ENTER();
14472
14473 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080014474 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053014475 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080014476
14477 status = wlan_hdd_validate_context(pHddCtx);
14478 if (status)
14479 {
Yue Mae36e3552014-03-05 17:06:20 -080014480 return status;
14481 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014482
Jeff Johnson295189b2012-06-20 16:38:30 -070014483 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
14484 {
14485 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
14486 return -EINVAL;
14487 }
14488
Nitesh Shah9b066282017-06-06 18:05:52 +053014489 wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
14490
Jeff Johnson295189b2012-06-20 16:38:30 -070014491 pRoamProfile = &pWextState->roamProfile;
14492
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014493 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070014494 {
Jeff Johnsone7245742012-09-05 17:12:55 -070014495 hdd_station_ctx_t *pHddStaCtx;
14496 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Abhishek Singh6782c9e2017-06-06 13:37:45 +053014497 pHddStaCtx->get_mgmt_log_sent = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014498
Siddharth Bhalda0d1622015-04-24 15:47:49 +053014499 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
14500
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014501 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070014502 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
14503 {
14504 /*QoS not enabled in cfg file*/
14505 pRoamProfile->uapsd_mask = 0;
14506 }
14507 else
14508 {
14509 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014510 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070014511 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
14512 }
14513
14514 pRoamProfile->SSIDs.numOfSSIDs = 1;
14515 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
14516 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014517 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070014518 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
14519 ssid, ssid_len);
14520
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014521 vos_mem_zero(pRoamProfile->BSSIDs.bssid, WNI_CFG_BSSID_LEN);
14522 vos_mem_zero(pRoamProfile->bssid_hint, WNI_CFG_BSSID_LEN);
14523
Jeff Johnson295189b2012-06-20 16:38:30 -070014524 if (bssid)
14525 {
14526 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014527 vos_mem_copy(pRoamProfile->BSSIDs.bssid, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070014528 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014529 /* Save BSSID in seperate variable as well, as RoamProfile
14530 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070014531 case of join failure we should send valid BSSID to supplicant
14532 */
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014533 vos_mem_copy(pWextState->req_bssId, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070014534 WNI_CFG_BSSID_LEN);
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014535
Jeff Johnson295189b2012-06-20 16:38:30 -070014536 }
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014537 else if (bssid_hint)
Dhanashri Atre51981c62013-06-13 11:47:57 -070014538 {
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014539 /* Store bssid_hint to use in the scan filter. */
14540 vos_mem_copy(pRoamProfile->bssid_hint, bssid_hint,
14541 WNI_CFG_BSSID_LEN);
14542 /*
14543 * Save BSSID in seperate variable as well, as RoamProfile
14544 * BSSID is getting zeroed out in the association process. And in
14545 * case of join failure we should send valid BSSID to supplicant
14546 */
14547 vos_mem_copy(pWextState->req_bssId, bssid_hint,
14548 WNI_CFG_BSSID_LEN);
14549 hddLog(LOG1, FL(" bssid_hint: "MAC_ADDRESS_STR),
14550 MAC_ADDR_ARRAY(pRoamProfile->bssid_hint));
Dhanashri Atre51981c62013-06-13 11:47:57 -070014551 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014552
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014553
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014554 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
14555 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070014556 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
14557 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014558 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014559 /*set gen ie*/
14560 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
14561 /*set auth*/
14562 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
14563 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014564#ifdef FEATURE_WLAN_WAPI
14565 if (pAdapter->wapi_info.nWapiMode)
14566 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014567 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014568 switch (pAdapter->wapi_info.wapiAuthMode)
14569 {
14570 case WAPI_AUTH_MODE_PSK:
14571 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014572 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014573 pAdapter->wapi_info.wapiAuthMode);
14574 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
14575 break;
14576 }
14577 case WAPI_AUTH_MODE_CERT:
14578 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014579 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014580 pAdapter->wapi_info.wapiAuthMode);
14581 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
14582 break;
14583 }
14584 } // End of switch
14585 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
14586 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
14587 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014588 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014589 pRoamProfile->AuthType.numEntries = 1;
14590 pRoamProfile->EncryptionType.numEntries = 1;
14591 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
14592 pRoamProfile->mcEncryptionType.numEntries = 1;
14593 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
14594 }
14595 }
14596#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014597#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014598 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014599 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
14600 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
14601 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014602 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
14603 sizeof (tSirGtkOffloadParams));
14604 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014605 }
14606#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014607 pRoamProfile->csrPersona = pAdapter->device_mode;
14608
Jeff Johnson32d95a32012-09-10 13:15:23 -070014609 if( operatingChannel )
14610 {
14611 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
14612 pRoamProfile->ChannelInfo.numOfChannels = 1;
14613 }
Chet Lanctot186b5732013-03-18 10:26:30 -070014614 else
14615 {
14616 pRoamProfile->ChannelInfo.ChannelList = NULL;
14617 pRoamProfile->ChannelInfo.numOfChannels = 0;
14618 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014619 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
14620 {
14621 hdd_select_cbmode(pAdapter,operatingChannel);
14622 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014623
Agarwal Ashish40f9b872015-09-01 16:17:35 +053014624 /*
14625 * Change conn_state to connecting before sme_RoamConnect(),
14626 * because sme_RoamConnect() has a direct path to call
14627 * hdd_smeRoamCallback(), which will change the conn_state
14628 * If direct path, conn_state will be accordingly changed
14629 * to NotConnected or Associated by either
14630 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
14631 * in sme_RoamCallback()
14632 * if sme_RomConnect is to be queued,
14633 * Connecting state will remain until it is completed.
14634 * If connection state is not changed,
14635 * connection state will remain in eConnectionState_NotConnected state.
14636 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
14637 * if conn state is eConnectionState_NotConnected.
14638 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
14639 * informed of connect result indication which is an issue.
14640 */
14641
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053014642 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
14643 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053014644 {
14645 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053014646 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080014647 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
14648 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053014649 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014650 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070014651 pAdapter->sessionId, pRoamProfile, &roamId);
14652
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053014653 if ((eHAL_STATUS_SUCCESS != status) &&
14654 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
14655 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053014656
14657 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053014658 hddLog(VOS_TRACE_LEVEL_ERROR,
14659 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
14660 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080014661 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053014662 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080014663 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053014664 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080014665
14666 pRoamProfile->ChannelInfo.ChannelList = NULL;
14667 pRoamProfile->ChannelInfo.numOfChannels = 0;
14668
Jeff Johnson295189b2012-06-20 16:38:30 -070014669 }
14670 else
14671 {
14672 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
14673 return -EINVAL;
14674 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080014675 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014676 return status;
14677}
14678
14679/*
14680 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
14681 * This function is used to set the authentication type (OPEN/SHARED).
14682 *
14683 */
14684static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
14685 enum nl80211_auth_type auth_type)
14686{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014687 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014688 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14689
14690 ENTER();
14691
14692 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014693 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070014694 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014695 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053014696 hddLog(VOS_TRACE_LEVEL_INFO,
14697 "%s: set authentication type to AUTOSWITCH", __func__);
14698 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
14699 break;
14700
14701 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014702#ifdef WLAN_FEATURE_VOWIFI_11R
14703 case NL80211_AUTHTYPE_FT:
14704#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014705 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070014706 "%s: set authentication type to OPEN", __func__);
14707 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
14708 break;
14709
14710 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014711 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070014712 "%s: set authentication type to SHARED", __func__);
14713 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
14714 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080014715#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070014716 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014717 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070014718 "%s: set authentication type to CCKM WPA", __func__);
14719 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
14720 break;
14721#endif
14722
14723
14724 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014725 hddLog(VOS_TRACE_LEVEL_ERROR,
14726 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014727 auth_type);
14728 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
14729 return -EINVAL;
14730 }
14731
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014732 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070014733 pHddStaCtx->conn_info.authType;
14734 return 0;
14735}
14736
14737/*
14738 * FUNCTION: wlan_hdd_set_akm_suite
14739 * This function is used to set the key mgmt type(PSK/8021x).
14740 *
14741 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014742static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014743 u32 key_mgmt
14744 )
14745{
14746 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
14747 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053014748 /* Should be in ieee802_11_defs.h */
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053014749#ifndef WLAN_AKM_SUITE_8021X_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053014750#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053014751#endif
14752#ifndef WLAN_AKM_SUITE_PSK_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053014753#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053014754#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014755 /*set key mgmt type*/
14756 switch(key_mgmt)
14757 {
14758 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053014759 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053014760#ifdef WLAN_FEATURE_VOWIFI_11R
14761 case WLAN_AKM_SUITE_FT_PSK:
14762#endif
14763 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070014764 __func__);
14765 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
14766 break;
14767
14768 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053014769 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053014770#ifdef WLAN_FEATURE_VOWIFI_11R
14771 case WLAN_AKM_SUITE_FT_8021X:
14772#endif
14773 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070014774 __func__);
14775 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
14776 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080014777#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070014778#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
14779#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
14780 case WLAN_AKM_SUITE_CCKM:
14781 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
14782 __func__);
14783 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
14784 break;
14785#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070014786#ifndef WLAN_AKM_SUITE_OSEN
14787#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
14788 case WLAN_AKM_SUITE_OSEN:
14789 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
14790 __func__);
14791 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
14792 break;
14793#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014794
14795 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014796 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014797 __func__, key_mgmt);
14798 return -EINVAL;
14799
14800 }
14801 return 0;
14802}
14803
14804/*
14805 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014806 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070014807 * (NONE/WEP40/WEP104/TKIP/CCMP).
14808 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014809static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
14810 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070014811 bool ucast
14812 )
14813{
14814 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014815 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014816 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14817
14818 ENTER();
14819
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014820 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070014821 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053014822 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070014823 __func__, cipher);
14824 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
14825 }
14826 else
14827 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014828
Jeff Johnson295189b2012-06-20 16:38:30 -070014829 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014830 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070014831 {
14832 case IW_AUTH_CIPHER_NONE:
14833 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
14834 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014835
Jeff Johnson295189b2012-06-20 16:38:30 -070014836 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053014837 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070014838 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014839
Jeff Johnson295189b2012-06-20 16:38:30 -070014840 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053014841 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070014842 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014843
Jeff Johnson295189b2012-06-20 16:38:30 -070014844 case WLAN_CIPHER_SUITE_TKIP:
14845 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
14846 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014847
Jeff Johnson295189b2012-06-20 16:38:30 -070014848 case WLAN_CIPHER_SUITE_CCMP:
14849 encryptionType = eCSR_ENCRYPT_TYPE_AES;
14850 break;
14851#ifdef FEATURE_WLAN_WAPI
14852 case WLAN_CIPHER_SUITE_SMS4:
14853 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
14854 break;
14855#endif
14856
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080014857#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070014858 case WLAN_CIPHER_SUITE_KRK:
14859 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
14860 break;
14861#endif
14862 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014863 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014864 __func__, cipher);
14865 return -EOPNOTSUPP;
14866 }
14867 }
14868
14869 if (ucast)
14870 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014871 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014872 __func__, encryptionType);
14873 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
14874 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014875 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070014876 encryptionType;
14877 }
14878 else
14879 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014880 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014881 __func__, encryptionType);
14882 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
14883 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
14884 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
14885 }
14886
14887 return 0;
14888}
14889
14890
14891/*
14892 * FUNCTION: wlan_hdd_cfg80211_set_ie
14893 * This function is used to parse WPA/RSN IE's.
14894 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014895int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014896#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14897 const u8 *ie,
14898#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014899 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014900#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014901 size_t ie_len
14902 )
14903{
14904 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014905#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14906 const u8 *genie = ie;
14907#else
Jeff Johnson295189b2012-06-20 16:38:30 -070014908 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014909#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014910 v_U16_t remLen = ie_len;
14911#ifdef FEATURE_WLAN_WAPI
14912 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
14913 u16 *tmp;
14914 v_U16_t akmsuiteCount;
14915 int *akmlist;
14916#endif
14917 ENTER();
14918
14919 /* clear previous assocAddIE */
14920 pWextState->assocAddIE.length = 0;
14921 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070014922 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014923
14924 while (remLen >= 2)
14925 {
14926 v_U16_t eLen = 0;
14927 v_U8_t elementId;
14928 elementId = *genie++;
14929 eLen = *genie++;
14930 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014931
Nachiket Kukade4aba5f02017-06-09 15:43:48 +053014932 /* Sanity check on eLen */
14933 if (eLen > remLen) {
14934 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid IE length[%d] for IE[0x%X]",
14935 __func__, eLen, elementId);
14936 VOS_ASSERT(0);
14937 return -EINVAL;
14938 }
14939
Arif Hussain6d2a3322013-11-17 19:50:10 -080014940 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070014941 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014942
14943 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070014944 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014945 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014946 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 -070014947 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014948 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014949 "%s: Invalid WPA IE", __func__);
14950 return -EINVAL;
14951 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014952 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070014953 {
14954 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014955 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070014956 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014957
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014958 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070014959 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014960 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
14961 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070014962 VOS_ASSERT(0);
14963 return -ENOMEM;
14964 }
14965 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
14966 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14967 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014968
Jeff Johnson295189b2012-06-20 16:38:30 -070014969 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
14970 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14971 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14972 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014973 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
14974 {
Nachiket Kukade3d72b7e2017-06-09 16:58:24 +053014975 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
14976 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d]",
14977 __func__, eLen);
14978 VOS_ASSERT(0);
14979 return -EINVAL;
14980 }
14981
Jeff Johnson295189b2012-06-20 16:38:30 -070014982 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
14983 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
14984 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
14985 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
14986 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
14987 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014988 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053014989 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070014990 {
14991 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014992 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070014993 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014994
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014995 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070014996 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014997 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14998 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070014999 VOS_ASSERT(0);
15000 return -ENOMEM;
15001 }
15002 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
15003 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15004 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015005
Jeff Johnson295189b2012-06-20 16:38:30 -070015006 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15007 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15008 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015009#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015010 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
15011 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015012 /*Consider WFD IE, only for P2P Client */
15013 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
15014 {
15015 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015016 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070015017 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015018
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015019 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015020 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015021 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15022 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070015023 VOS_ASSERT(0);
15024 return -ENOMEM;
15025 }
15026 // WFD IE is saved to Additional IE ; it should be accumulated to handle
15027 // WPS IE + P2P IE + WFD IE
15028 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15029 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015030
Jeff Johnson295189b2012-06-20 16:38:30 -070015031 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15032 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15033 }
15034#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015035 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015036 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015037 HS20_OUI_TYPE_SIZE)) )
15038 {
15039 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015040 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015041 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015042
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015043 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015044 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015045 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15046 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015047 VOS_ASSERT(0);
15048 return -ENOMEM;
15049 }
15050 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15051 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015052
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015053 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15054 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15055 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070015056 /* Appending OSEN Information Element in Assiciation Request */
15057 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
15058 OSEN_OUI_TYPE_SIZE)) )
15059 {
15060 v_U16_t curAddIELen = pWextState->assocAddIE.length;
15061 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
15062 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015063
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015064 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070015065 {
15066 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15067 "Need bigger buffer space");
15068 VOS_ASSERT(0);
15069 return -ENOMEM;
15070 }
15071 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15072 pWextState->assocAddIE.length += eLen + 2;
15073
15074 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
15075 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15076 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15077 }
15078
Abhishek Singh4322e622015-06-10 15:42:54 +053015079 /* Update only for WPA IE */
15080 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
15081 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070015082
15083 /* populating as ADDIE in beacon frames */
15084 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015085 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070015086 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
15087 {
15088 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
15089 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
15090 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
15091 {
15092 hddLog(LOGE,
15093 "Coldn't pass "
15094 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
15095 }
15096 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
15097 else
15098 hddLog(LOGE,
15099 "Could not pass on "
15100 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
15101
15102 /* IBSS mode doesn't contain params->proberesp_ies still
15103 beaconIE's need to be populated in probe response frames */
15104 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
15105 {
15106 u16 rem_probe_resp_ie_len = eLen + 2;
15107 u8 probe_rsp_ie_len[3] = {0};
15108 u8 counter = 0;
15109
15110 /* Check Probe Resp Length if it is greater then 255 then
15111 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
15112 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
15113 not able Store More then 255 bytes into One Variable */
15114
15115 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
15116 {
15117 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
15118 {
15119 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
15120 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
15121 }
15122 else
15123 {
15124 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
15125 rem_probe_resp_ie_len = 0;
15126 }
15127 }
15128
15129 rem_probe_resp_ie_len = 0;
15130
15131 if (probe_rsp_ie_len[0] > 0)
15132 {
15133 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
15134 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
15135 (tANI_U8*)(genie - 2),
15136 probe_rsp_ie_len[0], NULL,
15137 eANI_BOOLEAN_FALSE)
15138 == eHAL_STATUS_FAILURE)
15139 {
15140 hddLog(LOGE,
15141 "Could not pass"
15142 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
15143 }
15144 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
15145 }
15146
15147 if (probe_rsp_ie_len[1] > 0)
15148 {
15149 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
15150 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
15151 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
15152 probe_rsp_ie_len[1], NULL,
15153 eANI_BOOLEAN_FALSE)
15154 == eHAL_STATUS_FAILURE)
15155 {
15156 hddLog(LOGE,
15157 "Could not pass"
15158 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
15159 }
15160 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
15161 }
15162
15163 if (probe_rsp_ie_len[2] > 0)
15164 {
15165 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
15166 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
15167 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
15168 probe_rsp_ie_len[2], NULL,
15169 eANI_BOOLEAN_FALSE)
15170 == eHAL_STATUS_FAILURE)
15171 {
15172 hddLog(LOGE,
15173 "Could not pass"
15174 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
15175 }
15176 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
15177 }
15178
15179 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
15180 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
15181 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
15182 {
15183 hddLog(LOGE,
15184 "Could not pass"
15185 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
15186 }
15187 }
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070015188 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070015189 break;
15190 case DOT11F_EID_RSN:
15191 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
15192 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
15193 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
15194 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
15195 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
15196 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053015197
Abhishek Singhb16f3562016-01-20 11:08:32 +053015198 /* Appending extended capabilities with Interworking or
15199 * bsstransition bit set in Assoc Req.
Abhishek Singh15d95602015-03-24 15:52:57 +053015200 *
15201 * In assoc req this EXT Cap will only be taken into account if
Abhishek Singhb16f3562016-01-20 11:08:32 +053015202 * interworkingService or bsstransition bit is set to 1.
15203 * Driver is only interested in interworkingService and
15204 * bsstransition capability from supplicant.
15205 * If in future any other EXT Cap info is
Abhishek Singh15d95602015-03-24 15:52:57 +053015206 * required from supplicat, it needs to be handled while
15207 * sending Assoc Req in LIM.
15208 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015209 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015210 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015211 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015212 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015213 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015214
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015215 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015216 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015217 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15218 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015219 VOS_ASSERT(0);
15220 return -ENOMEM;
15221 }
15222 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15223 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015224
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015225 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15226 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15227 break;
15228 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015229#ifdef FEATURE_WLAN_WAPI
15230 case WLAN_EID_WAPI:
15231 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070015232 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070015233 pAdapter->wapi_info.nWapiMode);
15234 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015235 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070015236 akmsuiteCount = WPA_GET_LE16(tmp);
15237 tmp = tmp + 1;
15238 akmlist = (int *)(tmp);
15239 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
15240 {
15241 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
15242 }
15243 else
15244 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015245 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070015246 VOS_ASSERT(0);
15247 return -EINVAL;
15248 }
15249
15250 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
15251 {
15252 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015253 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015254 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015255 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015256 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015257 {
Jeff Johnson295189b2012-06-20 16:38:30 -070015258 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015259 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015260 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
15261 }
15262 break;
15263#endif
15264 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015265 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015266 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015267 /* when Unknown IE is received we should break and continue
15268 * to the next IE in the buffer instead we were returning
15269 * so changing this to break */
15270 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070015271 }
15272 genie += eLen;
15273 remLen -= eLen;
15274 }
15275 EXIT();
15276 return 0;
15277}
15278
15279/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053015280 * FUNCTION: hdd_isWPAIEPresent
15281 * Parse the received IE to find the WPA IE
15282 *
15283 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015284static bool hdd_isWPAIEPresent(
15285#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
15286 const u8 *ie,
15287#else
15288 u8 *ie,
15289#endif
15290 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053015291{
15292 v_U8_t eLen = 0;
15293 v_U16_t remLen = ie_len;
15294 v_U8_t elementId = 0;
15295
15296 while (remLen >= 2)
15297 {
15298 elementId = *ie++;
15299 eLen = *ie++;
15300 remLen -= 2;
15301 if (eLen > remLen)
15302 {
15303 hddLog(VOS_TRACE_LEVEL_ERROR,
15304 "%s: IE length is wrong %d", __func__, eLen);
15305 return FALSE;
15306 }
15307 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
15308 {
15309 /* OUI - 0x00 0X50 0XF2
15310 WPA Information Element - 0x01
15311 WPA version - 0x01*/
15312 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
15313 return TRUE;
15314 }
15315 ie += eLen;
15316 remLen -= eLen;
15317 }
15318 return FALSE;
15319}
15320
15321/*
Jeff Johnson295189b2012-06-20 16:38:30 -070015322 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015323 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070015324 * parameters during connect operation.
15325 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015326int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070015327 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015328 )
Jeff Johnson295189b2012-06-20 16:38:30 -070015329{
15330 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015331 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070015332 ENTER();
15333
15334 /*set wpa version*/
15335 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
15336
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015337 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070015338 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053015339 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070015340 {
15341 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
15342 }
15343 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
15344 {
15345 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
15346 }
15347 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015348
15349 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015350 pWextState->wpaVersion);
15351
15352 /*set authentication type*/
15353 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
15354
15355 if (0 > status)
15356 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015357 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015358 "%s: failed to set authentication type ", __func__);
15359 return status;
15360 }
15361
15362 /*set key mgmt type*/
15363 if (req->crypto.n_akm_suites)
15364 {
15365 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
15366 if (0 > status)
15367 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015368 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070015369 __func__);
15370 return status;
15371 }
15372 }
15373
15374 /*set pairwise cipher type*/
15375 if (req->crypto.n_ciphers_pairwise)
15376 {
15377 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
15378 req->crypto.ciphers_pairwise[0], true);
15379 if (0 > status)
15380 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015381 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015382 "%s: failed to set unicast cipher type", __func__);
15383 return status;
15384 }
15385 }
15386 else
15387 {
15388 /*Reset previous cipher suite to none*/
15389 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
15390 if (0 > status)
15391 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015392 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015393 "%s: failed to set unicast cipher type", __func__);
15394 return status;
15395 }
15396 }
15397
15398 /*set group cipher type*/
15399 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
15400 false);
15401
15402 if (0 > status)
15403 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015404 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070015405 __func__);
15406 return status;
15407 }
15408
Chet Lanctot186b5732013-03-18 10:26:30 -070015409#ifdef WLAN_FEATURE_11W
15410 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
15411#endif
15412
Jeff Johnson295189b2012-06-20 16:38:30 -070015413 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
15414 if (req->ie_len)
15415 {
15416 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
15417 if ( 0 > status)
15418 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015419 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070015420 __func__);
15421 return status;
15422 }
15423 }
15424
15425 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015426 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070015427 {
15428 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
15429 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
15430 )
15431 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015432 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070015433 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
15434 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015435 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070015436 __func__);
15437 return -EOPNOTSUPP;
15438 }
15439 else
15440 {
15441 u8 key_len = req->key_len;
15442 u8 key_idx = req->key_idx;
15443
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015444 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070015445 && (CSR_MAX_NUM_KEY > key_idx)
15446 )
15447 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015448 hddLog(VOS_TRACE_LEVEL_INFO,
15449 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015450 __func__, key_idx, key_len);
15451 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015452 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070015453 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015454 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070015455 (u8)key_len;
15456 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
15457 }
15458 }
15459 }
15460 }
15461
15462 return status;
15463}
15464
15465/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015466 * FUNCTION: wlan_hdd_try_disconnect
15467 * This function is used to disconnect from previous
15468 * connection
15469 */
Agrawal Ashishc407f192017-01-23 17:18:35 +053015470int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015471{
15472 long ret = 0;
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015473 int status, result = 0;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015474 hdd_station_ctx_t *pHddStaCtx;
15475 eMib_dot11DesiredBssType connectedBssType;
Abhishek Singh19a7dd92015-12-30 16:31:51 +053015476 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015477
Abhishek Singh19a7dd92015-12-30 16:31:51 +053015478 ret = wlan_hdd_validate_context(pHddCtx);
15479 if (0 != ret)
15480 {
15481 return ret;
15482 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015483 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15484
15485 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
15486
15487 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
15488 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
Abhishek Singh630ff592016-01-07 18:15:53 +053015489 (eConnectionState_Connecting == pHddStaCtx->conn_info.connState) ||
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015490 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
15491 {
Abhishek Singh9f4df782017-03-15 17:29:10 +053015492 /* Indicate disconnect to SME so that in-progress connection or preauth
15493 * can be aborted
15494 */
15495 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
15496 pAdapter->sessionId);
Abhishek Singh19a7dd92015-12-30 16:31:51 +053015497 spin_lock_bh(&pAdapter->lock_for_active_session);
15498 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
15499 {
15500 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
15501 }
15502 spin_unlock_bh(&pAdapter->lock_for_active_session);
Abhishek Singhf7962582015-10-23 10:54:06 +053015503 hdd_connSetConnectionState(pHddStaCtx,
15504 eConnectionState_Disconnecting);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015505 /* Issue disconnect to CSR */
15506 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015507 status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015508 pAdapter->sessionId,
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015509 eCSR_DISCONNECT_REASON_UNSPECIFIED);
15510 if(eHAL_STATUS_CMD_NOT_QUEUED == status) {
15511 hddLog(LOG1,
15512 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
15513 } else if ( 0 != status ) {
15514 hddLog(LOGE,
15515 FL("csrRoamDisconnect failure, returned %d"),
15516 (int)status );
15517 result = -EINVAL;
15518 goto disconnected;
15519 }
15520 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015521 &pAdapter->disconnect_comp_var,
15522 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015523 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status)) {
15524 hddLog(LOGE,
15525 "%s: Failed to disconnect, timed out", __func__);
15526 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015527 }
15528 }
15529 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
15530 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015531 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015532 &pAdapter->disconnect_comp_var,
15533 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015534 if (!ret)
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015535 {
15536 hddLog(LOGE, FL("Failed to receive disconnect event"));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015537 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015538 }
15539 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015540disconnected:
15541 hddLog(LOG1,
15542 FL("Set HDD connState to eConnectionState_NotConnected"));
15543 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
15544 return result;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015545}
15546
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053015547/**
15548 * wlan_hdd_reassoc_bssid_hint() - Start reassociation if bssid is present
15549 * @adapter: Pointer to the HDD adapter
15550 * @req: Pointer to the structure cfg_connect_params receieved from user space
15551 *
15552 * This function will start reassociation if bssid hint, channel hint and
15553 * previous bssid parameters are present in the connect request
15554 *
15555 * Return: success if reassociation is happening
15556 * Error code if reassociation is not permitted or not happening
15557 */
15558#ifdef CFG80211_CONNECT_PREV_BSSID
15559static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
15560 struct cfg80211_connect_params *req)
15561{
15562 int status = -EPERM;
15563 if (req->bssid_hint && req->channel_hint && req->prev_bssid) {
15564 hddLog(VOS_TRACE_LEVEL_INFO,
15565 FL("REASSOC Attempt on channel %d to "MAC_ADDRESS_STR),
15566 req->channel_hint->hw_value,
15567 MAC_ADDR_ARRAY(req->bssid_hint));
15568 status = hdd_reassoc(adapter, req->bssid_hint,
15569 req->channel_hint->hw_value,
15570 CONNECT_CMD_USERSPACE);
15571 }
15572 return status;
15573}
15574#else
15575static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
15576 struct cfg80211_connect_params *req)
15577{
15578 return -EPERM;
15579}
15580#endif
15581
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015582/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053015583 * FUNCTION: __wlan_hdd_cfg80211_connect
15584 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070015585 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015586static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015587 struct net_device *ndev,
15588 struct cfg80211_connect_params *req
15589 )
15590{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015591 int status;
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053015592 u16 channel;
Edhar, Mahesh Kumar496c7f72016-03-18 12:47:44 +053015593#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) || \
15594 defined(CFG80211_BSSID_HINT_BACKPORT)
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053015595 const u8 *bssid_hint = req->bssid_hint;
15596#else
15597 const u8 *bssid_hint = NULL;
15598#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015599 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070015600 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053015601 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015602
15603 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015604
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015605 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15606 TRACE_CODE_HDD_CFG80211_CONNECT,
15607 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015608 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015609 "%s: device_mode = %s (%d)", __func__,
15610 hdd_device_modetoString(pAdapter->device_mode),
15611 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015612
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015613 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080015614 if (!pHddCtx)
15615 {
15616 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15617 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053015618 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080015619 }
15620
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015621 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015622 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070015623 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015624 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015625 }
15626
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053015627 status = wlan_hdd_reassoc_bssid_hint(pAdapter, req);
15628 if (0 == status)
15629 return status;
15630
Agarwal Ashish51325b52014-06-16 16:50:49 +053015631
Jeff Johnson295189b2012-06-20 16:38:30 -070015632#ifdef WLAN_BTAMP_FEATURE
15633 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015634 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070015635 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015636 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015637 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080015638 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070015639 }
15640#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015641
15642 //If Device Mode is Station Concurrent Sessions Exit BMps
15643 //P2P Mode will be taken care in Open/close adapter
15644 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053015645 (vos_concurrent_open_sessions_running())) {
15646 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
15647 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015648 }
15649
15650 /*Try disconnecting if already in connected state*/
15651 status = wlan_hdd_try_disconnect(pAdapter);
15652 if ( 0 > status)
15653 {
15654 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
15655 " connection"));
15656 return -EALREADY;
15657 }
Agrawal Ashish559530c2015-12-01 18:04:20 +053015658 /* Check for max concurrent connections after doing disconnect if any*/
15659 if (vos_max_concurrent_connections_reached()) {
15660 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
15661 return -ECONNREFUSED;
15662 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015663
Jeff Johnson295189b2012-06-20 16:38:30 -070015664 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015665 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070015666
15667 if ( 0 > status)
15668 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015669 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070015670 __func__);
15671 return status;
15672 }
Sravan Kumar Kairam589c5722016-01-27 20:28:53 +053015673
15674 if (pHddCtx->spoofMacAddr.isEnabled)
15675 {
15676 hddLog(VOS_TRACE_LEVEL_INFO,
15677 "%s: MAC Spoofing enabled ", __func__);
15678 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
15679 * to fill TxBds for probe request during SSID scan which may happen
15680 * as part of connect command
15681 */
15682 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
15683 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
15684 if (status != VOS_STATUS_SUCCESS)
15685 return -ECONNREFUSED;
15686 }
15687
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053015688 if (req->channel)
15689 channel = req->channel->hw_value;
Mohit Khanna765234a2012-09-11 15:08:35 -070015690 else
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053015691 channel = 0;
Kapil Gupta312028a2016-10-25 14:15:20 +053015692
15693 /* Abort if any scan is going on */
15694 status = wlan_hdd_scan_abort(pAdapter);
15695 if (0 != status)
15696 hddLog(VOS_TRACE_LEVEL_ERROR, FL("scan abort failed"));
15697
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053015698 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
15699 req->ssid_len, req->bssid,
15700 bssid_hint, channel);
Jeff Johnson295189b2012-06-20 16:38:30 -070015701
Sushant Kaushikd7083982015-03-18 14:33:24 +053015702 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070015703 {
15704 //ReEnable BMPS if disabled
15705 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
15706 (NULL != pHddCtx))
15707 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053015708 if (pHddCtx->hdd_wlan_suspended)
15709 {
15710 hdd_set_pwrparams(pHddCtx);
15711 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015712 //ReEnable Bmps and Imps back
15713 hdd_enable_bmps_imps(pHddCtx);
15714 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053015715 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070015716 return status;
15717 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015718 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015719 EXIT();
15720 return status;
15721}
15722
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015723static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
15724 struct net_device *ndev,
15725 struct cfg80211_connect_params *req)
15726{
15727 int ret;
15728 vos_ssr_protect(__func__);
15729 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
15730 vos_ssr_unprotect(__func__);
15731
15732 return ret;
15733}
Jeff Johnson295189b2012-06-20 16:38:30 -070015734
15735/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015736 * FUNCTION: wlan_hdd_disconnect
15737 * This function is used to issue a disconnect request to SME
15738 */
15739int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
15740{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015741 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015742 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015743 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053015744 long ret;
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053015745 eConnectionState prev_conn_state;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015746
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015747 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015748
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015749 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015750 if (0 != status)
15751 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015752 return status;
15753 }
Abhishek Singh07e4a892015-11-23 11:29:57 +053015754 /* Indicate sme of disconnect so that in progress connection or preauth
15755 * can be aborted
15756 */
15757 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
Sushant Kaushikb4834d22015-07-15 15:29:05 +053015758 pAdapter->sessionId);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015759 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053015760
Agarwal Ashish47d18112014-08-04 19:55:07 +053015761 /* Need to apply spin lock before decreasing active sessions
15762 * as there can be chance for double decrement if context switch
15763 * Calls hdd_DisConnectHandler.
15764 */
15765
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053015766 prev_conn_state = pHddStaCtx->conn_info.connState;
15767
Agarwal Ashish47d18112014-08-04 19:55:07 +053015768 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053015769 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
15770 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053015771 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
15772 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053015773 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
15774 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053015775
Abhishek Singhf4669da2014-05-26 15:07:49 +053015776 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053015777 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
15778
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015779 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015780
Mihir Shete182a0b22014-08-18 16:08:48 +053015781 /*
15782 * stop tx queues before deleting STA/BSS context from the firmware.
15783 * tx has to be disabled because the firmware can get busy dropping
15784 * the tx frames after BSS/STA has been deleted and will not send
15785 * back a response resulting in WDI timeout
15786 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053015787 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053015788 netif_tx_disable(pAdapter->dev);
15789 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015790
Mihir Shete182a0b22014-08-18 16:08:48 +053015791 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015792 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
15793 pAdapter->sessionId, reason);
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053015794 if((eHAL_STATUS_CMD_NOT_QUEUED == status) &&
15795 prev_conn_state != eConnectionState_Connecting)
15796 {
15797 hddLog(LOG1,
15798 FL("status = %d, already disconnected"), status);
15799 result = 0;
15800 goto disconnected;
15801 }
15802 /*
15803 * Wait here instead of returning directly, this will block the next
15804 * connect command and allow processing of the scan for ssid and
15805 * the previous connect command in CSR. Else we might hit some
15806 * race conditions leading to SME and HDD out of sync.
15807 */
15808 else if(eHAL_STATUS_CMD_NOT_QUEUED == status)
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015809 {
15810 hddLog(LOG1,
15811 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053015812 }
15813 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015814 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015815 hddLog(LOGE,
15816 FL("csrRoamDisconnect failure, returned %d"),
15817 (int)status);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015818 result = -EINVAL;
15819 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015820 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015821 ret = wait_for_completion_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015822 &pAdapter->disconnect_comp_var,
15823 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015824 if (!ret && (eHAL_STATUS_CMD_NOT_QUEUED != status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015825 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015826 hddLog(LOGE,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053015827 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015828 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053015829 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015830disconnected:
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015831 hddLog(LOG1,
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053015832 FL("Set HDD connState to eConnectionState_NotConnected"));
15833 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Mahesh A Saptasagar936ffc32016-05-25 11:27:43 +053015834#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
15835 /* Sending disconnect event to userspace for kernel version < 3.11
15836 * is handled by __cfg80211_disconnect call to __cfg80211_disconnected
15837 */
15838 hddLog(LOG1, FL("Send disconnected event to userspace"));
15839
Mahesh A Saptasagarf5859b12016-06-01 17:17:50 +053015840 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, true,
Mahesh A Saptasagar936ffc32016-05-25 11:27:43 +053015841 WLAN_REASON_UNSPECIFIED);
15842#endif
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053015843
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015844 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015845 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015846}
15847
15848
15849/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015850 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070015851 * This function is used to issue a disconnect request to SME
15852 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015853static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015854 struct net_device *dev,
15855 u16 reason
15856 )
15857{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015858 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015859 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053015860 tCsrRoamProfile *pRoamProfile;
15861 hdd_station_ctx_t *pHddStaCtx;
15862 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015863#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015864 tANI_U8 staIdx;
15865#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015866
Jeff Johnson295189b2012-06-20 16:38:30 -070015867 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015868
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053015869 if (!pAdapter) {
15870 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
15871 return -EINVAL;
15872 }
15873
15874 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15875 if (!pHddStaCtx) {
15876 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
15877 return -EINVAL;
15878 }
15879
15880 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15881 status = wlan_hdd_validate_context(pHddCtx);
15882 if (0 != status)
15883 {
15884 return status;
15885 }
15886
15887 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
15888
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015889 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15890 TRACE_CODE_HDD_CFG80211_DISCONNECT,
15891 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015892 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
15893 __func__, hdd_device_modetoString(pAdapter->device_mode),
15894 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015895
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015896 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
15897 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070015898
Jeff Johnson295189b2012-06-20 16:38:30 -070015899 if (NULL != pRoamProfile)
15900 {
15901 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053015902 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
15903 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070015904 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015905 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070015906 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015907 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070015908 switch(reason)
15909 {
15910 case WLAN_REASON_MIC_FAILURE:
15911 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
15912 break;
15913
15914 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
15915 case WLAN_REASON_DISASSOC_AP_BUSY:
15916 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
15917 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
15918 break;
15919
15920 case WLAN_REASON_PREV_AUTH_NOT_VALID:
15921 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053015922 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070015923 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
15924 break;
15925
Jeff Johnson295189b2012-06-20 16:38:30 -070015926 default:
15927 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
15928 break;
15929 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015930 pScanInfo = &pHddCtx->scan_info;
15931 if (pScanInfo->mScanPending)
15932 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053015933 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015934 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053015935 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053015936 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015937 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053015938 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015939#ifdef FEATURE_WLAN_TDLS
15940 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080015941 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015942 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080015943 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
15944 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015945 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015946 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080015947 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015948 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015949 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080015950 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015951 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015952 status = sme_DeleteTdlsPeerSta(
15953 WLAN_HDD_GET_HAL_CTX(pAdapter),
15954 pAdapter->sessionId,
15955 mac);
15956 if (status != eHAL_STATUS_SUCCESS) {
15957 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
15958 return -EPERM;
15959 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015960 }
15961 }
15962#endif
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053015963
15964 hddLog(LOG1, FL("Disconnecting with reasoncode:%u connState %d"),
15965 reasonCode,
15966 pHddStaCtx->conn_info.connState);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015967 status = wlan_hdd_disconnect(pAdapter, reasonCode);
15968 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070015969 {
15970 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080015971 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015972 __func__, (int)status );
15973 return -EINVAL;
15974 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015975 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053015976 else
15977 {
15978 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
15979 "called while in %d state", __func__,
15980 pHddStaCtx->conn_info.connState);
15981 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015982 }
15983 else
15984 {
15985 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
15986 }
15987
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015988 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015989 return status;
15990}
15991
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015992static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
15993 struct net_device *dev,
15994 u16 reason
15995 )
15996{
15997 int ret;
15998 vos_ssr_protect(__func__);
15999 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
16000 vos_ssr_unprotect(__func__);
16001
16002 return ret;
16003}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016004
Jeff Johnson295189b2012-06-20 16:38:30 -070016005/*
16006 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016007 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070016008 * settings in IBSS mode.
16009 */
16010static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016011 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070016012 struct cfg80211_ibss_params *params
16013 )
16014{
16015 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016016 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016017 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
16018 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016019
Jeff Johnson295189b2012-06-20 16:38:30 -070016020 ENTER();
16021
16022 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070016023 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070016024
16025 if (params->ie_len && ( NULL != params->ie) )
16026 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016027 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
16028 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070016029 {
16030 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
16031 encryptionType = eCSR_ENCRYPT_TYPE_AES;
16032 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016033 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070016034 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070016035 tDot11fIEWPA dot11WPAIE;
16036 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016037 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070016038
Wilson Yang00256342013-10-10 23:13:38 -070016039 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016040 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
16041 params->ie_len, DOT11F_EID_WPA);
16042 if ( NULL != ie )
16043 {
16044 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
16045 // Unpack the WPA IE
16046 //Skip past the EID byte and length byte - and four byte WiFi OUI
16047 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
16048 &ie[2+4],
16049 ie[1] - 4,
16050 &dot11WPAIE);
16051 /*Extract the multicast cipher, the encType for unicast
16052 cipher for wpa-none is none*/
16053 encryptionType =
16054 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
16055 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016056 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016057
Jeff Johnson295189b2012-06-20 16:38:30 -070016058 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
16059
16060 if (0 > status)
16061 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016062 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070016063 __func__);
16064 return status;
16065 }
16066 }
16067
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016068 pWextState->roamProfile.AuthType.authType[0] =
16069 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070016070 eCSR_AUTH_TYPE_OPEN_SYSTEM;
16071
16072 if (params->privacy)
16073 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016074 /* Security enabled IBSS, At this time there is no information available
16075 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070016076 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016077 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070016078 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016079 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070016080 *enable privacy bit in beacons */
16081
16082 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
16083 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070016084 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
16085 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070016086 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
16087 pWextState->roamProfile.EncryptionType.numEntries = 1;
16088 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070016089 return status;
16090}
16091
16092/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016093 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016094 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070016095 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016096static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016097 struct net_device *dev,
16098 struct cfg80211_ibss_params *params
16099 )
16100{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016101 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070016102 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
16103 tCsrRoamProfile *pRoamProfile;
16104 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016105 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16106 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016107 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070016108
16109 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016110
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016111 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16112 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
16113 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016114 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016115 "%s: device_mode = %s (%d)", __func__,
16116 hdd_device_modetoString(pAdapter->device_mode),
16117 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070016118
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016119 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016120 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070016121 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016122 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016123 }
16124
16125 if (NULL == pWextState)
16126 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016127 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070016128 __func__);
16129 return -EIO;
16130 }
16131
Agarwal Ashish51325b52014-06-16 16:50:49 +053016132 if (vos_max_concurrent_connections_reached()) {
16133 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
16134 return -ECONNREFUSED;
16135 }
16136
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016137 /*Try disconnecting if already in connected state*/
16138 status = wlan_hdd_try_disconnect(pAdapter);
16139 if ( 0 > status)
16140 {
16141 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
16142 " IBSS connection"));
16143 return -EALREADY;
16144 }
16145
Jeff Johnson295189b2012-06-20 16:38:30 -070016146 pRoamProfile = &pWextState->roamProfile;
16147
16148 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
16149 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016150 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080016151 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016152 return -EINVAL;
16153 }
16154
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070016155 /* BSSID is provided by upper layers hence no need to AUTO generate */
16156 if (NULL != params->bssid) {
16157 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
16158 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
16159 hddLog (VOS_TRACE_LEVEL_ERROR,
16160 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
16161 return -EIO;
16162 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016163 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070016164 }
krunal sonie9002db2013-11-25 14:24:17 -080016165 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
16166 {
16167 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
16168 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
16169 {
16170 hddLog (VOS_TRACE_LEVEL_ERROR,
16171 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
16172 return -EIO;
16173 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016174
16175 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080016176 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016177 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080016178 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070016179
Jeff Johnson295189b2012-06-20 16:38:30 -070016180 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070016181 if (NULL !=
16182#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
16183 params->chandef.chan)
16184#else
16185 params->channel)
16186#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016187 {
16188 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016189 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
16190 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
16191 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
16192 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070016193
16194 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016195 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070016196 ieee80211_frequency_to_channel(
16197#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
16198 params->chandef.chan->center_freq);
16199#else
16200 params->channel->center_freq);
16201#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016202
16203 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
16204 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070016205 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016206 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
16207 __func__);
16208 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070016209 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016210
16211 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070016212 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016213 if (channelNum == validChan[indx])
16214 {
16215 break;
16216 }
16217 }
16218 if (indx >= numChans)
16219 {
16220 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016221 __func__, channelNum);
16222 return -EINVAL;
16223 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016224 /* Set the Operational Channel */
16225 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
16226 channelNum);
16227 pRoamProfile->ChannelInfo.numOfChannels = 1;
16228 pHddStaCtx->conn_info.operationChannel = channelNum;
16229 pRoamProfile->ChannelInfo.ChannelList =
16230 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070016231 }
16232
16233 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016234 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070016235 if (status < 0)
16236 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016237 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070016238 __func__);
16239 return status;
16240 }
16241
16242 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016243 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Abhishek Singh4d924682015-11-17 15:23:06 +053016244 params->ssid_len, (const u8 *)&bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016245 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070016246
16247 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070016248 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016249
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016250 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016251 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016252}
16253
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016254static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
16255 struct net_device *dev,
16256 struct cfg80211_ibss_params *params
16257 )
16258{
16259 int ret = 0;
16260
16261 vos_ssr_protect(__func__);
16262 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
16263 vos_ssr_unprotect(__func__);
16264
16265 return ret;
16266}
16267
Jeff Johnson295189b2012-06-20 16:38:30 -070016268/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016269 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016270 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070016271 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016272static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016273 struct net_device *dev
16274 )
16275{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016276 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016277 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
16278 tCsrRoamProfile *pRoamProfile;
16279 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016280 int status;
Abhishek Singh69de3302016-11-11 16:44:32 +053016281 eHalStatus hal_status;
Abhishek Singh7cd040e2016-01-07 10:51:04 +053016282#ifdef WLAN_FEATURE_RMC
16283 tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN] = {0};
16284#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016285
16286 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016287
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016288 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16289 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
16290 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016291 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016292 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016293 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016294 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016295 }
16296
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016297 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
16298 hdd_device_modetoString(pAdapter->device_mode),
16299 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070016300 if (NULL == pWextState)
16301 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016302 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070016303 __func__);
16304 return -EIO;
16305 }
16306
16307 pRoamProfile = &pWextState->roamProfile;
16308
16309 /* Issue disconnect only if interface type is set to IBSS */
16310 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
16311 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016312 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070016313 __func__);
16314 return -EINVAL;
16315 }
16316
Abhishek Singh7cd040e2016-01-07 10:51:04 +053016317#ifdef WLAN_FEATURE_RMC
16318 /* Clearing add IE of beacon */
16319 if (ccmCfgSetStr(pHddCtx->hHal,
16320 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0],
16321 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN,
16322 NULL, eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
16323 {
16324 hddLog (VOS_TRACE_LEVEL_ERROR,
16325 "%s: unable to clear PROBE_RSP_BCN_ADDNIE_DATA", __func__);
16326 return -EINVAL;
16327 }
16328 if (ccmCfgSetInt(pHddCtx->hHal,
16329 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0, NULL,
16330 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
16331 {
16332 hddLog (VOS_TRACE_LEVEL_ERROR,
16333 "%s: unable to clear WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
16334 __func__);
16335 return -EINVAL;
16336 }
16337
16338 // Reset WNI_CFG_PROBE_RSP Flags
16339 wlan_hdd_reset_prob_rspies(pAdapter);
16340
16341 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
16342 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 0,NULL,
16343 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
16344 {
16345 hddLog (VOS_TRACE_LEVEL_ERROR,
16346 "%s: unable to clear WNI_CFG_PROBE_RSP_ADDNIE_FLAG",
16347 __func__);
16348 return -EINVAL;
16349 }
16350#endif
16351
Jeff Johnson295189b2012-06-20 16:38:30 -070016352 /* Issue Disconnect request */
16353 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singh69de3302016-11-11 16:44:32 +053016354 hal_status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
16355 pAdapter->sessionId,
16356 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
16357 if (!HAL_STATUS_SUCCESS(hal_status)) {
16358 hddLog(LOGE,
16359 FL("sme_RoamDisconnect failed hal_status(%d)"),
16360 hal_status);
16361 return -EAGAIN;
16362 }
16363 status = wait_for_completion_timeout(
16364 &pAdapter->disconnect_comp_var,
16365 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
16366 if (!status) {
16367 hddLog(LOGE,
16368 FL("wait on disconnect_comp_var failed"));
16369 return -ETIMEDOUT;
16370 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016371
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016372 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016373 return 0;
16374}
16375
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016376static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
16377 struct net_device *dev
16378 )
16379{
16380 int ret = 0;
16381
16382 vos_ssr_protect(__func__);
16383 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
16384 vos_ssr_unprotect(__func__);
16385
16386 return ret;
16387}
16388
Jeff Johnson295189b2012-06-20 16:38:30 -070016389/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016390 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070016391 * This function is used to set the phy parameters
16392 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
16393 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016394static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016395 u32 changed)
16396{
16397 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
16398 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016399 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016400
16401 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016402
16403 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016404 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
16405 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016406
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016407 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016408 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016409 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016410 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016411 }
16412
Jeff Johnson295189b2012-06-20 16:38:30 -070016413 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
16414 {
16415 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
16416 WNI_CFG_RTS_THRESHOLD_STAMAX :
16417 wiphy->rts_threshold;
16418
16419 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016420 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070016421 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016422 hddLog(VOS_TRACE_LEVEL_ERROR,
16423 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016424 __func__, rts_threshold);
16425 return -EINVAL;
16426 }
16427
16428 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
16429 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016430 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016431 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016432 hddLog(VOS_TRACE_LEVEL_ERROR,
16433 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016434 __func__, rts_threshold);
16435 return -EIO;
16436 }
16437
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016438 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016439 rts_threshold);
16440 }
16441
16442 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
16443 {
16444 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
16445 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
16446 wiphy->frag_threshold;
16447
16448 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016449 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016450 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016451 hddLog(VOS_TRACE_LEVEL_ERROR,
16452 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016453 frag_threshold);
16454 return -EINVAL;
16455 }
16456
16457 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
16458 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016459 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016460 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016461 hddLog(VOS_TRACE_LEVEL_ERROR,
16462 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016463 __func__, frag_threshold);
16464 return -EIO;
16465 }
16466
16467 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
16468 frag_threshold);
16469 }
16470
16471 if ((changed & WIPHY_PARAM_RETRY_SHORT)
16472 || (changed & WIPHY_PARAM_RETRY_LONG))
16473 {
16474 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
16475 wiphy->retry_short :
16476 wiphy->retry_long;
16477
16478 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
16479 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
16480 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016481 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016482 __func__, retry_value);
16483 return -EINVAL;
16484 }
16485
16486 if (changed & WIPHY_PARAM_RETRY_SHORT)
16487 {
16488 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
16489 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016490 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016491 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016492 hddLog(VOS_TRACE_LEVEL_ERROR,
16493 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016494 __func__, retry_value);
16495 return -EIO;
16496 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016497 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016498 __func__, retry_value);
16499 }
16500 else if (changed & WIPHY_PARAM_RETRY_SHORT)
16501 {
16502 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
16503 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016504 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016505 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016506 hddLog(VOS_TRACE_LEVEL_ERROR,
16507 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016508 __func__, retry_value);
16509 return -EIO;
16510 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016511 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016512 __func__, retry_value);
16513 }
16514 }
16515
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016516 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016517 return 0;
16518}
16519
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016520static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
16521 u32 changed)
16522{
16523 int ret;
16524
16525 vos_ssr_protect(__func__);
16526 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
16527 vos_ssr_unprotect(__func__);
16528
16529 return ret;
16530}
16531
Jeff Johnson295189b2012-06-20 16:38:30 -070016532/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016533 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070016534 * This function is used to set the txpower
16535 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016536static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070016537#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16538 struct wireless_dev *wdev,
16539#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016540#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016541 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070016542#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016543 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070016544#endif
16545 int dbm)
16546{
16547 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016548 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070016549 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
16550 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016551 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016552
16553 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016554
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016555 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16556 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
16557 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016558 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016559 if (0 != status)
16560 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016561 return status;
16562 }
16563
16564 hHal = pHddCtx->hHal;
16565
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016566 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
16567 dbm, ccmCfgSetCallback,
16568 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016569 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016570 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016571 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
16572 return -EIO;
16573 }
16574
16575 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
16576 dbm);
16577
16578 switch(type)
16579 {
16580 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
16581 /* Fall through */
16582 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
16583 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
16584 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016585 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
16586 __func__);
16587 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070016588 }
16589 break;
16590 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016591 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070016592 __func__);
16593 return -EOPNOTSUPP;
16594 break;
16595 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016596 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
16597 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070016598 return -EIO;
16599 }
16600
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016601 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016602 return 0;
16603}
16604
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016605static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
16606#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16607 struct wireless_dev *wdev,
16608#endif
16609#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
16610 enum tx_power_setting type,
16611#else
16612 enum nl80211_tx_power_setting type,
16613#endif
16614 int dbm)
16615{
16616 int ret;
16617 vos_ssr_protect(__func__);
16618 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
16619#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16620 wdev,
16621#endif
16622#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
16623 type,
16624#else
16625 type,
16626#endif
16627 dbm);
16628 vos_ssr_unprotect(__func__);
16629
16630 return ret;
16631}
16632
Jeff Johnson295189b2012-06-20 16:38:30 -070016633/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016634 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070016635 * This function is used to read the txpower
16636 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016637static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070016638#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16639 struct wireless_dev *wdev,
16640#endif
16641 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070016642{
16643
16644 hdd_adapter_t *pAdapter;
16645 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016646 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016647
Jeff Johnsone7245742012-09-05 17:12:55 -070016648 ENTER();
16649
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016650 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016651 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016652 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016653 *dbm = 0;
16654 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016655 }
16656
Jeff Johnson295189b2012-06-20 16:38:30 -070016657 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
16658 if (NULL == pAdapter)
16659 {
16660 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
16661 return -ENOENT;
16662 }
16663
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016664 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16665 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
16666 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070016667 wlan_hdd_get_classAstats(pAdapter);
16668 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
16669
Jeff Johnsone7245742012-09-05 17:12:55 -070016670 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016671 return 0;
16672}
16673
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016674static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
16675#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16676 struct wireless_dev *wdev,
16677#endif
16678 int *dbm)
16679{
16680 int ret;
16681
16682 vos_ssr_protect(__func__);
16683 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
16684#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16685 wdev,
16686#endif
16687 dbm);
16688 vos_ssr_unprotect(__func__);
16689
16690 return ret;
16691}
16692
Dustin Brown8c1d4092017-07-28 18:08:01 +053016693/*
16694 * wlan_hdd_fill_summary_stats() - populate station_info summary stats
16695 * @stats: summary stats to use as a source
16696 * @info: kernel station_info struct to use as a destination
16697 *
16698 * Return: None
16699 */
16700static void wlan_hdd_fill_summary_stats(tCsrSummaryStatsInfo *stats,
16701 struct station_info *info)
16702{
16703 int i;
16704
16705 info->rx_packets = stats->rx_frm_cnt;
16706 info->tx_packets = 0;
16707 info->tx_retries = 0;
16708 info->tx_failed = 0;
16709
16710 for (i = 0; i < 4; ++i) {
16711 info->tx_packets += stats->tx_frm_cnt[i];
16712 info->tx_retries += stats->multiple_retry_cnt[i];
16713 info->tx_failed += stats->fail_cnt[i];
16714 }
16715
16716 info->filled |= STATION_INFO_TX_PACKETS |
16717 STATION_INFO_TX_RETRIES |
16718 STATION_INFO_TX_FAILED |
16719 STATION_INFO_RX_PACKETS;
16720}
16721
16722/**
16723 * wlan_hdd_get_sap_stats() - get aggregate SAP stats
16724 * @adapter: sap adapter to get stats for
16725 * @info: kernel station_info struct to populate
16726 *
16727 * Fetch the vdev-level aggregate stats for the given SAP adapter. This is to
16728 * support "station dump" and "station get" for SAP vdevs, even though they
16729 * aren't technically stations.
16730 *
16731 * Return: errno
16732 */
16733static int
16734wlan_hdd_get_sap_stats(hdd_adapter_t *adapter, struct station_info *info)
16735{
16736 VOS_STATUS status;
16737
16738 status = wlan_hdd_get_station_stats(adapter);
16739 if (!VOS_IS_STATUS_SUCCESS(status)) {
16740 hddLog(VOS_TRACE_LEVEL_ERROR,
16741 "Failed to get SAP stats; status:%d", status);
16742 return 0;
16743 }
16744
16745 wlan_hdd_fill_summary_stats(&adapter->hdd_stats.summary_stat, info);
16746
16747 return 0;
16748}
16749
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016750static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016751#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16752 const u8* mac,
16753#else
16754 u8* mac,
16755#endif
16756 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070016757{
16758 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
16759 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16760 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053016761 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070016762
16763 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
16764 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070016765
16766 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
16767 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
16768 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
16769 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
16770 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
16771 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
16772 tANI_U16 maxRate = 0;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053016773 int8_t snr = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070016774 tANI_U16 myRate;
16775 tANI_U16 currentRate = 0;
16776 tANI_U8 maxSpeedMCS = 0;
16777 tANI_U8 maxMCSIdx = 0;
16778 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053016779 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070016780 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016781 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016782
Leo Chang6f8870f2013-03-26 18:11:36 -070016783#ifdef WLAN_FEATURE_11AC
16784 tANI_U32 vht_mcs_map;
16785 eDataRate11ACMaxMcs vhtMaxMcs;
16786#endif /* WLAN_FEATURE_11AC */
16787
Jeff Johnsone7245742012-09-05 17:12:55 -070016788 ENTER();
16789
Dustin Brown8c1d4092017-07-28 18:08:01 +053016790 status = wlan_hdd_validate_context(pHddCtx);
16791 if (0 != status)
16792 {
16793 return status;
16794 }
16795
16796 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
16797 return wlan_hdd_get_sap_stats(pAdapter, sinfo);
16798
Jeff Johnson295189b2012-06-20 16:38:30 -070016799 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
16800 (0 == ssidlen))
16801 {
16802 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
16803 " Invalid ssidlen, %d", __func__, ssidlen);
16804 /*To keep GUI happy*/
16805 return 0;
16806 }
16807
Mukul Sharma811205f2014-07-09 21:07:30 +053016808 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
16809 {
16810 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16811 "%s: Roaming in progress, so unable to proceed this request", __func__);
Sachin Ahuja81ab1812016-08-19 21:35:58 +053016812 /* return a cached value */
16813 sinfo->signal = pAdapter->rssi;
Mukul Sharma811205f2014-07-09 21:07:30 +053016814 return 0;
16815 }
16816
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053016817 wlan_hdd_get_station_stats(pAdapter);
16818 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070016819
Kiet Lam3b17fc82013-09-27 05:24:08 +053016820 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053016821 wlan_hdd_get_snr(pAdapter, &snr);
16822 pHddStaCtx->conn_info.signal = sinfo->signal;
16823 pHddStaCtx->conn_info.noise = pHddStaCtx->conn_info.signal - snr;
Kiet Lam3b17fc82013-09-27 05:24:08 +053016824 sinfo->filled |= STATION_INFO_SIGNAL;
16825
c_hpothu09f19542014-05-30 21:53:31 +053016826 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053016827 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
16828 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053016829 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053016830 {
16831 rate_flags = pAdapter->maxRateFlags;
16832 }
c_hpothu44ff4e02014-05-08 00:13:57 +053016833
Jeff Johnson295189b2012-06-20 16:38:30 -070016834 //convert to the UI units of 100kbps
16835 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
16836
16837#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070016838 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 -070016839 sinfo->signal,
16840 pCfg->reportMaxLinkSpeed,
16841 myRate,
16842 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070016843 (int) pCfg->linkSpeedRssiMid,
16844 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070016845 (int) rate_flags,
16846 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070016847#endif //LINKSPEED_DEBUG_ENABLED
16848
16849 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
16850 {
16851 // we do not want to necessarily report the current speed
16852 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
16853 {
16854 // report the max possible speed
16855 rssidx = 0;
16856 }
16857 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
16858 {
16859 // report the max possible speed with RSSI scaling
16860 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
16861 {
16862 // report the max possible speed
16863 rssidx = 0;
16864 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070016865 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070016866 {
16867 // report middle speed
16868 rssidx = 1;
16869 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070016870 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
16871 {
16872 // report middle speed
16873 rssidx = 2;
16874 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016875 else
16876 {
16877 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070016878 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070016879 }
16880 }
16881 else
16882 {
16883 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
16884 hddLog(VOS_TRACE_LEVEL_ERROR,
16885 "%s: Invalid value for reportMaxLinkSpeed: %u",
16886 __func__, pCfg->reportMaxLinkSpeed);
16887 rssidx = 0;
16888 }
16889
16890 maxRate = 0;
16891
16892 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053016893 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
16894 OperationalRates, &ORLeng))
16895 {
16896 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
16897 /*To keep GUI happy*/
16898 return 0;
16899 }
16900
Jeff Johnson295189b2012-06-20 16:38:30 -070016901 for (i = 0; i < ORLeng; i++)
16902 {
Jeff Johnsone7245742012-09-05 17:12:55 -070016903 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070016904 {
16905 /* Validate Rate Set */
16906 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
16907 {
16908 currentRate = supported_data_rate[j].supported_rate[rssidx];
16909 break;
16910 }
16911 }
16912 /* Update MAX rate */
16913 maxRate = (currentRate > maxRate)?currentRate:maxRate;
16914 }
16915
16916 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053016917 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
16918 ExtendedRates, &ERLeng))
16919 {
16920 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
16921 /*To keep GUI happy*/
16922 return 0;
16923 }
16924
Jeff Johnson295189b2012-06-20 16:38:30 -070016925 for (i = 0; i < ERLeng; i++)
16926 {
Jeff Johnsone7245742012-09-05 17:12:55 -070016927 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070016928 {
16929 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
16930 {
16931 currentRate = supported_data_rate[j].supported_rate[rssidx];
16932 break;
16933 }
16934 }
16935 /* Update MAX rate */
16936 maxRate = (currentRate > maxRate)?currentRate:maxRate;
16937 }
c_hpothu79aab322014-07-14 21:11:01 +053016938
Kiet Lamb69f8dc2013-11-15 15:34:27 +053016939 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053016940 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053016941 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053016942 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070016943 {
c_hpothu79aab322014-07-14 21:11:01 +053016944 if (rate_flags & eHAL_TX_RATE_VHT80)
16945 mode = 2;
16946 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
16947 mode = 1;
16948 else
16949 mode = 0;
16950
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053016951 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
16952 MCSRates, &MCSLeng))
16953 {
16954 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
16955 /*To keep GUI happy*/
16956 return 0;
16957 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016958 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070016959#ifdef WLAN_FEATURE_11AC
16960 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016961 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070016962 {
Leo Chang6f8870f2013-03-26 18:11:36 -070016963 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016964 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070016965 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070016966 {
Leo Chang6f8870f2013-03-26 18:11:36 -070016967 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070016968 }
Leo Chang6f8870f2013-03-26 18:11:36 -070016969 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070016970 {
Leo Chang6f8870f2013-03-26 18:11:36 -070016971 maxMCSIdx = 7;
16972 }
16973 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
16974 {
16975 maxMCSIdx = 8;
16976 }
16977 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
16978 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016979 //VHT20 is supporting 0~8
16980 if (rate_flags & eHAL_TX_RATE_VHT20)
16981 maxMCSIdx = 8;
16982 else
16983 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070016984 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016985
c_hpothu79aab322014-07-14 21:11:01 +053016986 if (0 != rssidx)/*check for scaled */
16987 {
16988 //get middle rate MCS index if rssi=1/2
16989 for (i=0; i <= maxMCSIdx; i++)
16990 {
16991 if (sinfo->signal <= rssiMcsTbl[mode][i])
16992 {
16993 maxMCSIdx = i;
16994 break;
16995 }
16996 }
16997 }
16998
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016999 if (rate_flags & eHAL_TX_RATE_VHT80)
17000 {
17001 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
17002 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
17003 }
17004 else if (rate_flags & eHAL_TX_RATE_VHT40)
17005 {
17006 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
17007 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
17008 }
17009 else if (rate_flags & eHAL_TX_RATE_VHT20)
17010 {
17011 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
17012 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
17013 }
17014
Leo Chang6f8870f2013-03-26 18:11:36 -070017015 maxSpeedMCS = 1;
17016 if (currentRate > maxRate)
17017 {
17018 maxRate = currentRate;
17019 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017020
Leo Chang6f8870f2013-03-26 18:11:36 -070017021 }
17022 else
17023#endif /* WLAN_FEATURE_11AC */
17024 {
17025 if (rate_flags & eHAL_TX_RATE_HT40)
17026 {
17027 rateFlag |= 1;
17028 }
17029 if (rate_flags & eHAL_TX_RATE_SGI)
17030 {
17031 rateFlag |= 2;
17032 }
17033
Girish Gowli01abcee2014-07-31 20:18:55 +053017034 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053017035 if (rssidx == 1 || rssidx == 2)
17036 {
17037 //get middle rate MCS index if rssi=1/2
17038 for (i=0; i <= 7; i++)
17039 {
17040 if (sinfo->signal <= rssiMcsTbl[mode][i])
17041 {
17042 temp = i+1;
17043 break;
17044 }
17045 }
17046 }
c_hpothu79aab322014-07-14 21:11:01 +053017047
17048 for (i = 0; i < MCSLeng; i++)
17049 {
Leo Chang6f8870f2013-03-26 18:11:36 -070017050 for (j = 0; j < temp; j++)
17051 {
17052 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
17053 {
17054 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053017055 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070017056 break;
17057 }
17058 }
17059 if ((j < temp) && (currentRate > maxRate))
17060 {
17061 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070017062 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017063 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053017064 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070017065 }
17066 }
17067
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017068 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
17069 {
17070 maxRate = myRate;
17071 maxSpeedMCS = 1;
17072 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
17073 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017074 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053017075 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070017076 {
17077 maxRate = myRate;
17078 if (rate_flags & eHAL_TX_RATE_LEGACY)
17079 {
17080 maxSpeedMCS = 0;
17081 }
17082 else
17083 {
17084 maxSpeedMCS = 1;
17085 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
17086 }
17087 }
17088
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017089 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070017090 {
17091 sinfo->txrate.legacy = maxRate;
17092#ifdef LINKSPEED_DEBUG_ENABLED
17093 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
17094#endif //LINKSPEED_DEBUG_ENABLED
17095 }
17096 else
17097 {
17098 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070017099#ifdef WLAN_FEATURE_11AC
17100 sinfo->txrate.nss = 1;
17101 if (rate_flags & eHAL_TX_RATE_VHT80)
17102 {
17103 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017104 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070017105 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017106 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070017107 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017108 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
17109 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
17110 }
17111 else if (rate_flags & eHAL_TX_RATE_VHT20)
17112 {
17113 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
17114 }
17115#endif /* WLAN_FEATURE_11AC */
17116 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
17117 {
17118 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
17119 if (rate_flags & eHAL_TX_RATE_HT40)
17120 {
17121 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
17122 }
Leo Chang6f8870f2013-03-26 18:11:36 -070017123 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017124 if (rate_flags & eHAL_TX_RATE_SGI)
17125 {
17126 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
17127 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017128
Jeff Johnson295189b2012-06-20 16:38:30 -070017129#ifdef LINKSPEED_DEBUG_ENABLED
17130 pr_info("Reporting MCS rate %d flags %x\n",
17131 sinfo->txrate.mcs,
17132 sinfo->txrate.flags );
17133#endif //LINKSPEED_DEBUG_ENABLED
17134 }
17135 }
17136 else
17137 {
17138 // report current rate instead of max rate
17139
17140 if (rate_flags & eHAL_TX_RATE_LEGACY)
17141 {
17142 //provide to the UI in units of 100kbps
17143 sinfo->txrate.legacy = myRate;
17144#ifdef LINKSPEED_DEBUG_ENABLED
17145 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
17146#endif //LINKSPEED_DEBUG_ENABLED
17147 }
17148 else
17149 {
17150 //must be MCS
17151 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070017152#ifdef WLAN_FEATURE_11AC
17153 sinfo->txrate.nss = 1;
17154 if (rate_flags & eHAL_TX_RATE_VHT80)
17155 {
17156 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
17157 }
17158 else
17159#endif /* WLAN_FEATURE_11AC */
17160 {
17161 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
17162 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017163 if (rate_flags & eHAL_TX_RATE_SGI)
17164 {
17165 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
17166 }
17167 if (rate_flags & eHAL_TX_RATE_HT40)
17168 {
17169 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
17170 }
Leo Chang6f8870f2013-03-26 18:11:36 -070017171#ifdef WLAN_FEATURE_11AC
17172 else if (rate_flags & eHAL_TX_RATE_VHT80)
17173 {
17174 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
17175 }
17176#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070017177#ifdef LINKSPEED_DEBUG_ENABLED
17178 pr_info("Reporting actual MCS rate %d flags %x\n",
17179 sinfo->txrate.mcs,
17180 sinfo->txrate.flags );
17181#endif //LINKSPEED_DEBUG_ENABLED
17182 }
17183 }
17184 sinfo->filled |= STATION_INFO_TX_BITRATE;
17185
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070017186 sinfo->tx_packets =
17187 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
17188 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
17189 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
17190 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
17191
17192 sinfo->tx_retries =
17193 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
17194 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
17195 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
17196 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
17197
17198 sinfo->tx_failed =
17199 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
17200 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
17201 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
17202 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
17203
17204 sinfo->filled |=
17205 STATION_INFO_TX_PACKETS |
17206 STATION_INFO_TX_RETRIES |
17207 STATION_INFO_TX_FAILED;
17208
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053017209 sinfo->rx_packets = pAdapter->hdd_stats.summary_stat.rx_frm_cnt;
17210 sinfo->filled |= STATION_INFO_RX_PACKETS;
17211
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053017212 vos_mem_copy(&pHddStaCtx->conn_info.txrate,
17213 &sinfo->txrate, sizeof(sinfo->txrate));
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053017214 if (rate_flags & eHAL_TX_RATE_LEGACY)
17215 hddLog(LOG1, FL("Reporting RSSI:%d legacy rate %d pkt cnt tx %d rx %d"),
17216 sinfo->signal, sinfo->txrate.legacy, sinfo->tx_packets,
17217 sinfo->rx_packets);
17218 else
17219 hddLog(LOG1,
17220 FL("Reporting RSSI:%d MCS rate %d flags 0x%x pkt cnt tx %d rx %d"),
17221 sinfo->signal, sinfo->txrate.mcs, sinfo->txrate.flags,
17222 sinfo->tx_packets, sinfo->rx_packets);
17223
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017224 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17225 TRACE_CODE_HDD_CFG80211_GET_STA,
17226 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070017227 EXIT();
17228 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070017229}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017230#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
17231static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
17232 const u8* mac, struct station_info *sinfo)
17233#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017234static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
17235 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017236#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017237{
17238 int ret;
17239
17240 vos_ssr_protect(__func__);
17241 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
17242 vos_ssr_unprotect(__func__);
17243
17244 return ret;
17245}
17246
17247static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070017248 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070017249{
17250 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017251 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070017252 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017253 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017254
Jeff Johnsone7245742012-09-05 17:12:55 -070017255 ENTER();
17256
Jeff Johnson295189b2012-06-20 16:38:30 -070017257 if (NULL == pAdapter)
17258 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017259 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017260 return -ENODEV;
17261 }
17262
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017263 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17264 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
17265 pAdapter->sessionId, timeout));
17266
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017267 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017268 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017269 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017270 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017271 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017272 }
17273
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017274 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
17275 (TRUE == pHddCtx->hdd_wlan_suspended) &&
17276 (pHddCtx->cfg_ini->fhostArpOffload) &&
17277 (eConnectionState_Associated ==
17278 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
17279 {
Amar Singhald53568e2013-09-26 11:03:45 -070017280
17281 hddLog(VOS_TRACE_LEVEL_INFO,
17282 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053017283 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017284 if (!VOS_IS_STATUS_SUCCESS(vos_status))
17285 {
17286 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017287 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017288 __func__, vos_status);
17289 }
17290 }
17291
Jeff Johnson295189b2012-06-20 16:38:30 -070017292 /**The get power cmd from the supplicant gets updated by the nl only
17293 *on successful execution of the function call
17294 *we are oppositely mapped w.r.t mode in the driver
17295 **/
17296 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
17297
17298 if (VOS_STATUS_E_FAILURE == vos_status)
17299 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053017300 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17301 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017302 return -EINVAL;
17303 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017304 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017305 return 0;
17306}
17307
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017308static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
17309 struct net_device *dev, bool mode, int timeout)
17310{
17311 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070017312
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017313 vos_ssr_protect(__func__);
17314 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
17315 vos_ssr_unprotect(__func__);
17316
17317 return ret;
17318}
Sushant Kaushik084f6592015-09-10 13:11:56 +053017319
Jeff Johnson295189b2012-06-20 16:38:30 -070017320#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017321static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
17322 struct net_device *netdev,
17323 u8 key_index)
17324{
17325 ENTER();
17326 return 0;
17327}
17328
Jeff Johnson295189b2012-06-20 16:38:30 -070017329static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017330 struct net_device *netdev,
17331 u8 key_index)
17332{
17333 int ret;
17334 vos_ssr_protect(__func__);
17335 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
17336 vos_ssr_unprotect(__func__);
17337 return ret;
17338}
17339#endif //LINUX_VERSION_CODE
17340
17341#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
17342static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
17343 struct net_device *dev,
17344 struct ieee80211_txq_params *params)
17345{
17346 ENTER();
17347 return 0;
17348}
17349#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
17350static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
17351 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070017352{
Jeff Johnsone7245742012-09-05 17:12:55 -070017353 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070017354 return 0;
17355}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017356#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070017357
17358#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
17359static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017360 struct net_device *dev,
17361 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070017362{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017363 int ret;
17364
17365 vos_ssr_protect(__func__);
17366 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
17367 vos_ssr_unprotect(__func__);
17368 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070017369}
17370#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
17371static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
17372 struct ieee80211_txq_params *params)
17373{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017374 int ret;
17375
17376 vos_ssr_protect(__func__);
17377 ret = __wlan_hdd_set_txq_params(wiphy, params);
17378 vos_ssr_unprotect(__func__);
17379 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070017380}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017381#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017382
Naresh Jayaram69e3f282014-10-14 12:29:12 +053017383static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017384 struct net_device *dev,
17385 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070017386{
17387 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017388 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017389 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017390 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017391 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017392 v_CONTEXT_t pVosContext = NULL;
17393 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017394
Jeff Johnsone7245742012-09-05 17:12:55 -070017395 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017396
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017397 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070017398 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017399 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017400 return -EINVAL;
17401 }
17402
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017403 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17404 TRACE_CODE_HDD_CFG80211_DEL_STA,
17405 pAdapter->sessionId, pAdapter->device_mode));
17406
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017407 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17408 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017409 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017410 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017411 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017412 }
17413
Jeff Johnson295189b2012-06-20 16:38:30 -070017414 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070017415 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070017416 )
17417 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017418 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
17419 pSapCtx = VOS_GET_SAP_CB(pVosContext);
17420 if(pSapCtx == NULL){
17421 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17422 FL("psapCtx is NULL"));
17423 return -ENOENT;
17424 }
Agrawal Ashish306b75f2017-01-11 19:16:25 +053017425 if (pHddCtx->cfg_ini->enable_sap_auth_offload)
17426 {
17427 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
17428 "Change reason code to eSIR_MAC_DISASSOC_LEAVING_BSS_REASON in sap auth offload");
17429 pDelStaParams->reason_code = eSIR_MAC_DISASSOC_LEAVING_BSS_REASON;
17430 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017431 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070017432 {
17433 v_U16_t i;
17434 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
17435 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017436 if ((pSapCtx->aStaInfo[i].isUsed) &&
17437 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070017438 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017439 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017440 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017441 ETHER_ADDR_LEN);
17442
Jeff Johnson295189b2012-06-20 16:38:30 -070017443 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080017444 "%s: Delete STA with MAC::"
17445 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017446 __func__,
17447 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
17448 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070017449 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017450 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070017451 }
17452 }
17453 }
17454 else
17455 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017456
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017457 vos_status = hdd_softap_GetStaId(pAdapter,
17458 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017459 if (!VOS_IS_STATUS_SUCCESS(vos_status))
17460 {
17461 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080017462 "%s: Skip this DEL STA as this is not used::"
17463 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017464 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017465 return -ENOENT;
17466 }
17467
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017468 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017469 {
17470 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080017471 "%s: Skip this DEL STA as deauth is in progress::"
17472 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017473 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017474 return -ENOENT;
17475 }
17476
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017477 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017478
Jeff Johnson295189b2012-06-20 16:38:30 -070017479 hddLog(VOS_TRACE_LEVEL_INFO,
17480 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080017481 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070017482 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017483 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017484
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017485 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017486 if (!VOS_IS_STATUS_SUCCESS(vos_status))
17487 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017488 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017489 hddLog(VOS_TRACE_LEVEL_INFO,
17490 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080017491 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017492 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017493 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017494 return -ENOENT;
17495 }
17496
Jeff Johnson295189b2012-06-20 16:38:30 -070017497 }
17498 }
17499
17500 EXIT();
17501
17502 return 0;
17503}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053017504
17505#ifdef CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053017506int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Naresh Jayaram69e3f282014-10-14 12:29:12 +053017507 struct net_device *dev,
17508 struct station_del_parameters *param)
17509#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017510#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
Kapil Gupta137ef892016-12-13 19:38:00 +053017511int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017512 struct net_device *dev, const u8 *mac)
17513#else
Kapil Gupta137ef892016-12-13 19:38:00 +053017514int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017515 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053017516#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017517#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017518{
17519 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017520 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070017521
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017522 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017523
Naresh Jayaram69e3f282014-10-14 12:29:12 +053017524#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017525 if (NULL == param) {
17526 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017527 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017528 return -EINVAL;
17529 }
17530
17531 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
17532 param->subtype, &delStaParams);
17533
Naresh Jayaram69e3f282014-10-14 12:29:12 +053017534#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053017535 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017536 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053017537#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017538 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
17539
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017540 vos_ssr_unprotect(__func__);
17541
17542 return ret;
17543}
17544
17545static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017546 struct net_device *dev,
17547#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17548 const u8 *mac,
17549#else
17550 u8 *mac,
17551#endif
17552 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017553{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017554 hdd_adapter_t *pAdapter;
17555 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017556 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017557#ifdef FEATURE_WLAN_TDLS
17558 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017559
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017560 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017561
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017562 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17563 if (NULL == pAdapter)
17564 {
17565 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17566 "%s: Adapter is NULL",__func__);
17567 return -EINVAL;
17568 }
17569 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17570 status = wlan_hdd_validate_context(pHddCtx);
17571 if (0 != status)
17572 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017573 return status;
17574 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017575
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017576 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17577 TRACE_CODE_HDD_CFG80211_ADD_STA,
17578 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017579 mask = params->sta_flags_mask;
17580
17581 set = params->sta_flags_set;
17582
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017583 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017584 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
17585 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017586
17587 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
17588 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080017589 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017590 }
17591 }
17592#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017593 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017594 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017595}
17596
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017597#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
17598static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
17599 struct net_device *dev, const u8 *mac,
17600 struct station_parameters *params)
17601#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017602static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
17603 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017604#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017605{
17606 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017607
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017608 vos_ssr_protect(__func__);
17609 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
17610 vos_ssr_unprotect(__func__);
17611
17612 return ret;
17613}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017614#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070017615
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017616static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070017617 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017618{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017619 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17620 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017621 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017622 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017623 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017624 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070017625
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017626 ENTER();
17627
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017628 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017629 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017630 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017631 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017632 return -EINVAL;
17633 }
17634
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017635 if (!pmksa) {
17636 hddLog(LOGE, FL("pmksa is NULL"));
17637 return -EINVAL;
17638 }
17639
17640 if (!pmksa->bssid || !pmksa->pmkid) {
17641 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
17642 pmksa->bssid, pmksa->pmkid);
17643 return -EINVAL;
17644 }
17645
17646 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
17647 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
17648
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017649 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17650 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017651 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017652 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017653 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017654 }
17655
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017656 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017657 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
17658
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017659 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
17660 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017661
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017662 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017663 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017664 &pmk_id, 1, FALSE);
17665
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017666 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17667 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
17668 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017669
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017670 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017671 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017672}
17673
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017674static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
17675 struct cfg80211_pmksa *pmksa)
17676{
17677 int ret;
17678
17679 vos_ssr_protect(__func__);
17680 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
17681 vos_ssr_unprotect(__func__);
17682
17683 return ret;
17684}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017685
Wilson Yang6507c4e2013-10-01 20:11:19 -070017686
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017687static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070017688 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017689{
Wilson Yang6507c4e2013-10-01 20:11:19 -070017690 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17691 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017692 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080017693 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017694
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017695 ENTER();
17696
Wilson Yang6507c4e2013-10-01 20:11:19 -070017697 /* Validate pAdapter */
17698 if (NULL == pAdapter)
17699 {
17700 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
17701 return -EINVAL;
17702 }
17703
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017704 if (!pmksa) {
17705 hddLog(LOGE, FL("pmksa is NULL"));
17706 return -EINVAL;
17707 }
17708
17709 if (!pmksa->bssid) {
17710 hddLog(LOGE, FL("pmksa->bssid is NULL"));
17711 return -EINVAL;
17712 }
17713
Kiet Lam98c46a12014-10-31 15:34:57 -070017714 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
17715 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
17716
Wilson Yang6507c4e2013-10-01 20:11:19 -070017717 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17718 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070017719 if (0 != status)
17720 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070017721 return status;
17722 }
17723
17724 /*Retrieve halHandle*/
17725 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
17726
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017727 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17728 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
17729 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017730 /* Delete the PMKID CSR cache */
17731 if (eHAL_STATUS_SUCCESS !=
17732 sme_RoamDelPMKIDfromCache(halHandle,
17733 pAdapter->sessionId, pmksa->bssid, FALSE)) {
17734 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
17735 MAC_ADDR_ARRAY(pmksa->bssid));
17736 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017737 }
17738
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017739 EXIT();
17740 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017741}
17742
Wilson Yang6507c4e2013-10-01 20:11:19 -070017743
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017744static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
17745 struct cfg80211_pmksa *pmksa)
17746{
17747 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017748
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017749 vos_ssr_protect(__func__);
17750 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
17751 vos_ssr_unprotect(__func__);
17752
17753 return ret;
17754
17755}
17756
17757static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017758{
Wilson Yang6507c4e2013-10-01 20:11:19 -070017759 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17760 tHalHandle halHandle;
17761 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080017762 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017763
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017764 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070017765
17766 /* Validate pAdapter */
17767 if (NULL == pAdapter)
17768 {
17769 hddLog(VOS_TRACE_LEVEL_ERROR,
17770 "%s: Invalid Adapter" ,__func__);
17771 return -EINVAL;
17772 }
17773
17774 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17775 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070017776 if (0 != status)
17777 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070017778 return status;
17779 }
17780
17781 /*Retrieve halHandle*/
17782 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
17783
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017784 /* Flush the PMKID cache in CSR */
17785 if (eHAL_STATUS_SUCCESS !=
17786 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
17787 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
17788 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017789 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017790 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080017791 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017792}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017793
17794static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
17795{
17796 int ret;
17797
17798 vos_ssr_protect(__func__);
17799 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
17800 vos_ssr_unprotect(__func__);
17801
17802 return ret;
17803}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017804#endif
17805
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017806#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017807static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
17808 struct net_device *dev,
17809 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017810{
17811 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17812 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017813 hdd_context_t *pHddCtx;
17814 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017815
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017816 ENTER();
17817
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017818 if (NULL == pAdapter)
17819 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017820 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017821 return -ENODEV;
17822 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017823 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17824 ret = wlan_hdd_validate_context(pHddCtx);
17825 if (0 != ret)
17826 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017827 return ret;
17828 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017829 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017830 if (NULL == pHddStaCtx)
17831 {
17832 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
17833 return -EINVAL;
17834 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017835
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017836 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17837 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
17838 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017839 // Added for debug on reception of Re-assoc Req.
17840 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
17841 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017842 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017843 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080017844 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017845 }
17846
17847#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080017848 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017849 ftie->ie_len);
17850#endif
17851
17852 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053017853 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
17854 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017855 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017856
17857 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017858 return 0;
17859}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017860
17861static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
17862 struct net_device *dev,
17863 struct cfg80211_update_ft_ies_params *ftie)
17864{
17865 int ret;
17866
17867 vos_ssr_protect(__func__);
17868 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
17869 vos_ssr_unprotect(__func__);
17870
17871 return ret;
17872}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017873#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017874
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017875#ifdef FEATURE_WLAN_SCAN_PNO
17876
17877void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
17878 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
17879{
17880 int ret;
17881 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
17882 hdd_context_t *pHddCtx;
17883
Nirav Shah80830bf2013-12-31 16:35:12 +053017884 ENTER();
17885
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017886 if (NULL == pAdapter)
17887 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053017888 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017889 "%s: HDD adapter is Null", __func__);
17890 return ;
17891 }
17892
17893 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17894 if (NULL == pHddCtx)
17895 {
17896 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17897 "%s: HDD context is Null!!!", __func__);
17898 return ;
17899 }
17900
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017901 spin_lock(&pHddCtx->schedScan_lock);
17902 if (TRUE == pHddCtx->isWiphySuspended)
17903 {
17904 pHddCtx->isSchedScanUpdatePending = TRUE;
17905 spin_unlock(&pHddCtx->schedScan_lock);
17906 hddLog(VOS_TRACE_LEVEL_INFO,
17907 "%s: Update cfg80211 scan database after it resume", __func__);
17908 return ;
17909 }
17910 spin_unlock(&pHddCtx->schedScan_lock);
17911
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017912 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
17913
17914 if (0 > ret)
17915 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagarfb49cdd2015-10-16 18:41:59 +053017916 else
17917 {
17918 /* Acquire wakelock to handle the case where APP's tries to suspend
17919 * immediatly after the driver gets connect request(i.e after pno)
17920 * from supplicant, this result in app's is suspending and not able
17921 * to process the connect request to AP */
17922 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
17923 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017924 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017925 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17926 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017927}
17928
17929/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017930 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053017931 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017932 */
17933static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
17934{
17935 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
17936 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017937 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017938 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17939 int status = 0;
Agrawal Ashishcff31692016-12-16 17:17:50 +053017940
17941 if (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
17942 {
17943 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17944 "%s: PNO is allowed only in STA interface", __func__);
17945 return eHAL_STATUS_FAILURE;
17946 }
17947
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017948 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
17949
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053017950 /* The current firmware design does not allow PNO during any
Agrawal Ashishcff31692016-12-16 17:17:50 +053017951 * active sessions. PNO is allowed only in case when sap session
17952 * is present and sapo auth offload feature enabled in firmare.
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053017953 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017954 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
17955 {
17956 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017957 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017958
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017959 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
17960 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
17961 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
17962 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
Agrawal Ashishcff31692016-12-16 17:17:50 +053017963 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode &&
17964 !pHddCtx->cfg_ini->enable_sap_auth_offload)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053017965 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017966 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017967 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017968 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017969 }
17970 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
17971 pAdapterNode = pNext;
17972 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017973 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017974}
17975
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017976void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
17977{
17978 hdd_adapter_t *pAdapter = callbackContext;
17979 hdd_context_t *pHddCtx;
17980
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017981 ENTER();
17982
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017983 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
17984 {
17985 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17986 FL("Invalid adapter or adapter has invalid magic"));
17987 return;
17988 }
17989
17990 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17991 if (0 != wlan_hdd_validate_context(pHddCtx))
17992 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017993 return;
17994 }
17995
c_hpothub53c45d2014-08-18 16:53:14 +053017996 if (VOS_STATUS_SUCCESS != status)
17997 {
17998 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017999 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053018000 pHddCtx->isPnoEnable = FALSE;
18001 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018002
18003 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
18004 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018005 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018006}
18007
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018008#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) || \
18009 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
18010/**
18011 * hdd_config_sched_scan_plan() - configures the sched scan plans
18012 * from the framework.
18013 * @pno_req: pointer to PNO scan request
18014 * @request: pointer to scan request from framework
18015 *
18016 * Return: None
18017 */
18018static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
18019 struct cfg80211_sched_scan_request *request,
18020 hdd_context_t *hdd_ctx)
18021{
18022 v_U32_t i = 0;
18023
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018024 pno_req->scanTimers.ucScanTimersCount = request->n_scan_plans;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018025 for (i = 0; i < request->n_scan_plans; i++)
18026 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018027 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
18028 request->scan_plans[i].iterations;
18029 pno_req->scanTimers.aTimerValues[i].uTimerValue =
18030 request->scan_plans[i].interval;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018031 }
18032}
18033#else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018034static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018035 struct cfg80211_sched_scan_request *request,
18036 hdd_context_t *hdd_ctx)
18037{
18038 v_U32_t i, temp_int;
18039 /* Driver gets only one time interval which is hardcoded in
18040 * supplicant for 10000ms. Taking power consumption into account 6
18041 * timers will be used, Timervalue is increased exponentially
18042 * i.e 10,20,40, 80,160,320 secs. And number of scan cycle for each
18043 * timer is configurable through INI param gPNOScanTimerRepeatValue.
18044 * If it is set to 0 only one timer will be used and PNO scan cycle
18045 * will be repeated after each interval specified by supplicant
18046 * till PNO is disabled.
18047 */
18048 if (0 == hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue)
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018049 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018050 HDD_PNO_SCAN_TIMERS_SET_ONE;
18051 else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018052 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018053 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
18054
18055 temp_int = (request->interval)/1000;
18056 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18057 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
18058 temp_int, hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue);
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018059 for ( i = 0; i < pno_req->scanTimers.ucScanTimersCount; i++)
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018060 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018061 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018062 hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue;
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018063 pno_req->scanTimers.aTimerValues[i].uTimerValue = temp_int;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018064 temp_int *= 2;
18065 }
18066 //Repeat last timer until pno disabled.
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018067 pno_req->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018068}
18069#endif
18070
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018071/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018072 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
18073 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018074 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018075static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018076 struct net_device *dev, struct cfg80211_sched_scan_request *request)
18077{
18078 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018079 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018080 hdd_context_t *pHddCtx;
18081 tHalHandle hHal;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018082 v_U32_t i, indx, num_ch, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053018083 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
18084 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018085 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
18086 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018087 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053018088 hdd_config_t *pConfig = NULL;
18089 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018090
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018091 ENTER();
18092
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018093 if (NULL == pAdapter)
18094 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018095 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018096 "%s: HDD adapter is Null", __func__);
18097 return -ENODEV;
18098 }
18099
18100 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018101 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018102
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018103 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018104 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018105 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018106 }
18107
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053018108 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018109 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
18110 if (NULL == hHal)
18111 {
18112 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18113 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018114 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018115 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018116 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18117 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
18118 pAdapter->sessionId, pAdapter->device_mode));
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053018119 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053018120 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053018121 {
18122 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18123 "%s: aborting the existing scan is unsuccessfull", __func__);
18124 return -EBUSY;
18125 }
18126
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018127 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018128 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053018129 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018130 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018131 return -EBUSY;
18132 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018133
c_hpothu37f21312014-04-09 21:49:54 +053018134 if (TRUE == pHddCtx->isPnoEnable)
18135 {
18136 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
18137 FL("already PNO is enabled"));
18138 return -EBUSY;
18139 }
c_hpothu225aa7c2014-10-22 17:45:13 +053018140
18141 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
18142 {
18143 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18144 "%s: abort ROC failed ", __func__);
18145 return -EBUSY;
18146 }
18147
c_hpothu37f21312014-04-09 21:49:54 +053018148 pHddCtx->isPnoEnable = TRUE;
18149
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018150 pnoRequest.enable = 1; /*Enable PNO */
18151 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018152
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018153 if (( !pnoRequest.ucNetworksCount ) ||
18154 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018155 {
18156 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053018157 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018158 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053018159 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018160 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018161 goto error;
18162 }
18163
18164 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
18165 {
18166 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053018167 "%s: Incorrect number of channels %d",
18168 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018169 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018170 goto error;
18171 }
18172
18173 /* Framework provides one set of channels(all)
18174 * common for all saved profile */
18175 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
18176 channels_allowed, &num_channels_allowed))
18177 {
18178 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18179 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018180 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018181 goto error;
18182 }
18183 /* Checking each channel against allowed channel list */
18184 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053018185 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018186 {
Nirav Shah80830bf2013-12-31 16:35:12 +053018187 char chList [(request->n_channels*5)+1];
18188 int len;
18189 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018190 {
Nirav Shah80830bf2013-12-31 16:35:12 +053018191 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018192 {
Nirav Shah80830bf2013-12-31 16:35:12 +053018193 if (request->channels[i]->hw_value == channels_allowed[indx])
18194 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053018195 if ((!pConfig->enableDFSPnoChnlScan) &&
18196 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
18197 {
18198 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18199 "%s : Dropping DFS channel : %d",
18200 __func__,channels_allowed[indx]);
18201 num_ignore_dfs_ch++;
18202 break;
18203 }
18204
Nirav Shah80830bf2013-12-31 16:35:12 +053018205 valid_ch[num_ch++] = request->channels[i]->hw_value;
18206 len += snprintf(chList+len, 5, "%d ",
18207 request->channels[i]->hw_value);
18208 break ;
18209 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018210 }
18211 }
Nirav Shah80830bf2013-12-31 16:35:12 +053018212 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018213
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053018214 /*If all channels are DFS and dropped, then ignore the PNO request*/
18215 if (num_ignore_dfs_ch == request->n_channels)
18216 {
18217 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18218 "%s : All requested channels are DFS channels", __func__);
18219 ret = -EINVAL;
18220 goto error;
18221 }
18222 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018223
18224 pnoRequest.aNetworks =
18225 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
18226 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018227 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018228 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
18229 FL("failed to allocate memory aNetworks %u"),
18230 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
18231 goto error;
18232 }
18233 vos_mem_zero(pnoRequest.aNetworks,
18234 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
18235
18236 /* Filling per profile params */
18237 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
18238 {
18239 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018240 request->match_sets[i].ssid.ssid_len;
18241
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018242 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
18243 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018244 {
18245 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053018246 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018247 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018248 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018249 goto error;
18250 }
18251
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018252 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018253 request->match_sets[i].ssid.ssid,
18254 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053018255 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18256 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018257 i, pnoRequest.aNetworks[i].ssId.ssId);
18258 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
18259 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
18260 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018261
18262 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018263 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
18264 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018265
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018266 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018267 }
18268
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018269 for (i = 0; i < request->n_ssids; i++)
18270 {
18271 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018272 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018273 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018274 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018275 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018276 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018277 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018278 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018279 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018280 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018281 break;
18282 }
18283 j++;
18284 }
18285 }
18286 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18287 "Number of hidden networks being Configured = %d",
18288 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053018289 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080018290 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018291
18292 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
18293 if (pnoRequest.p24GProbeTemplate == NULL)
18294 {
18295 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
18296 FL("failed to allocate memory p24GProbeTemplate %u"),
18297 SIR_PNO_MAX_PB_REQ_SIZE);
18298 goto error;
18299 }
18300
18301 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
18302 if (pnoRequest.p5GProbeTemplate == NULL)
18303 {
18304 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
18305 FL("failed to allocate memory p5GProbeTemplate %u"),
18306 SIR_PNO_MAX_PB_REQ_SIZE);
18307 goto error;
18308 }
18309
18310 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
18311 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
18312
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053018313 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
18314 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053018315 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018316 pnoRequest.us24GProbeTemplateLen = request->ie_len;
18317 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
18318 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053018319
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018320 pnoRequest.us5GProbeTemplateLen = request->ie_len;
18321 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
18322 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053018323 }
18324
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018325 hdd_config_sched_scan_plan(&pnoRequest, request, pHddCtx);
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053018326
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018327 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018328
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018329 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018330 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
18331 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018332 pAdapter->pno_req_status = 0;
18333
Nirav Shah80830bf2013-12-31 16:35:12 +053018334 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18335 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018336 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
18337 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053018338
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018339 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018340 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018341 hdd_cfg80211_sched_scan_done_callback, pAdapter);
18342 if (eHAL_STATUS_SUCCESS != status)
18343 {
18344 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053018345 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018346 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018347 goto error;
18348 }
18349
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018350 ret = wait_for_completion_timeout(
18351 &pAdapter->pno_comp_var,
18352 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
18353 if (0 >= ret)
18354 {
18355 // Did not receive the response for PNO enable in time.
18356 // Assuming the PNO enable was success.
18357 // Returning error from here, because we timeout, results
18358 // in side effect of Wifi (Wifi Setting) not to work.
18359 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18360 FL("Timed out waiting for PNO to be Enabled"));
18361 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018362 }
18363
18364 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053018365 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018366
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018367error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018368 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18369 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053018370 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018371 if (pnoRequest.aNetworks)
18372 vos_mem_free(pnoRequest.aNetworks);
18373 if (pnoRequest.p24GProbeTemplate)
18374 vos_mem_free(pnoRequest.p24GProbeTemplate);
18375 if (pnoRequest.p5GProbeTemplate)
18376 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018377
18378 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018379 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018380}
18381
18382/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018383 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
18384 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018385 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018386static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
18387 struct net_device *dev, struct cfg80211_sched_scan_request *request)
18388{
18389 int ret;
18390
18391 vos_ssr_protect(__func__);
18392 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
18393 vos_ssr_unprotect(__func__);
18394
18395 return ret;
18396}
18397
18398/*
18399 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
18400 * Function to disable PNO
18401 */
18402static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018403 struct net_device *dev)
18404{
18405 eHalStatus status = eHAL_STATUS_FAILURE;
18406 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18407 hdd_context_t *pHddCtx;
18408 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018409 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018410 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018411
18412 ENTER();
18413
18414 if (NULL == pAdapter)
18415 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018416 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018417 "%s: HDD adapter is Null", __func__);
18418 return -ENODEV;
18419 }
18420
18421 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018422
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018423 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018424 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018425 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018426 "%s: HDD context is Null", __func__);
18427 return -ENODEV;
18428 }
18429
18430 /* The return 0 is intentional when isLogpInProgress and
18431 * isLoadUnloadInProgress. We did observe a crash due to a return of
18432 * failure in sched_scan_stop , especially for a case where the unload
18433 * of the happens at the same time. The function __cfg80211_stop_sched_scan
18434 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
18435 * success. If it returns a failure , then its next invocation due to the
18436 * clean up of the second interface will have the dev pointer corresponding
18437 * to the first one leading to a crash.
18438 */
18439 if (pHddCtx->isLogpInProgress)
18440 {
18441 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18442 "%s: LOGP in Progress. Ignore!!!", __func__);
Mahesh A Saptasagar0c11d822015-10-08 19:54:08 +053018443 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018444 return ret;
18445 }
18446
Mihir Shete18156292014-03-11 15:38:30 +053018447 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018448 {
18449 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18450 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
18451 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018452 }
18453
18454 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
18455 if (NULL == hHal)
18456 {
18457 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18458 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018459 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018460 }
18461
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018462 pnoRequest.enable = 0; /* Disable PNO */
18463 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018464
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018465 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18466 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
18467 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053018468
18469 INIT_COMPLETION(pAdapter->pno_comp_var);
18470 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
18471 pnoRequest.callbackContext = pAdapter;
18472 pAdapter->pno_req_status = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018473 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018474 pAdapter->sessionId,
18475 NULL, pAdapter);
18476 if (eHAL_STATUS_SUCCESS != status)
18477 {
18478 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18479 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018480 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018481 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018482 }
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053018483 ret = wait_for_completion_timeout(
18484 &pAdapter->pno_comp_var,
18485 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
18486 if (0 >= ret)
18487 {
18488 // Did not receive the response for PNO disable in time.
18489 // Assuming the PNO disable was success.
18490 // Returning error from here, because we timeout, results
18491 // in side effect of Wifi (Wifi Setting) not to work.
Anurag Chouhan96b41cb2016-09-28 18:54:47 +053018492 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053018493 FL("Timed out waiting for PNO to be disabled"));
18494 ret = 0;
18495 }
18496
18497 ret = pAdapter->pno_req_status;
18498 pHddCtx->isPnoEnable = (ret == 0) ? FALSE : TRUE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018499
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018500error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018501 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018502 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018503
18504 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018505 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018506}
18507
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018508/*
18509 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
18510 * NL interface to disable PNO
18511 */
18512static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
18513 struct net_device *dev)
18514{
18515 int ret;
18516
18517 vos_ssr_protect(__func__);
18518 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
18519 vos_ssr_unprotect(__func__);
18520
18521 return ret;
18522}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018523#endif /*FEATURE_WLAN_SCAN_PNO*/
18524
18525
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018526#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018527#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018528static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18529 struct net_device *dev,
18530 u8 *peer, u8 action_code,
18531 u8 dialog_token,
18532 u16 status_code, u32 peer_capability,
18533 const u8 *buf, size_t len)
18534#else /* TDLS_MGMT_VERSION2 */
18535#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
18536static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18537 struct net_device *dev,
18538 const u8 *peer, u8 action_code,
18539 u8 dialog_token, u16 status_code,
18540 u32 peer_capability, bool initiator,
18541 const u8 *buf, size_t len)
18542#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
18543static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18544 struct net_device *dev,
18545 const u8 *peer, u8 action_code,
18546 u8 dialog_token, u16 status_code,
18547 u32 peer_capability, const u8 *buf,
18548 size_t len)
18549#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
18550static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18551 struct net_device *dev,
18552 u8 *peer, u8 action_code,
18553 u8 dialog_token,
18554 u16 status_code, u32 peer_capability,
18555 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018556#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018557static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18558 struct net_device *dev,
18559 u8 *peer, u8 action_code,
18560 u8 dialog_token,
18561 u16 status_code, const u8 *buf,
18562 size_t len)
18563#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018564#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018565{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018566 hdd_adapter_t *pAdapter;
18567 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018568 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070018569 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080018570 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070018571 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018572 int ret;
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053018573 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018574#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018575 u32 peer_capability = 0;
18576#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053018577 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018578 hdd_station_ctx_t *pHddStaCtx = NULL;
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053018579 tdlsCtx_t *pHddTdlsCtx;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018580
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018581 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18582 if (NULL == pAdapter)
18583 {
18584 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18585 "%s: Adapter is NULL",__func__);
18586 return -EINVAL;
18587 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018588 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18589 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
18590 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018591
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018592 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018593 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018594 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018595 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018596 "Invalid arguments");
18597 return -EINVAL;
18598 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018599
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080018600 if (pHddCtx->isLogpInProgress)
18601 {
18602 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18603 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053018604 wlan_hdd_tdls_set_link_status(pAdapter,
18605 peer,
18606 eTDLS_LINK_IDLE,
18607 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080018608 return -EBUSY;
18609 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018610
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018611 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
18612 {
18613 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18614 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
18615 return -EAGAIN;
18616 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018617
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053018618 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
18619 if (!pHddTdlsCtx) {
18620 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18621 "%s: pHddTdlsCtx not valid.", __func__);
18622 }
18623
Hoonki Lee27511902013-03-14 18:19:06 -070018624 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018625 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018626 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070018627 "%s: TDLS mode is disabled OR not enabled in FW."
18628 MAC_ADDRESS_STR " action %d declined.",
18629 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018630 return -ENOTSUPP;
18631 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018632
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018633 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18634
18635 if( NULL == pHddStaCtx )
18636 {
18637 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18638 "%s: HDD station context NULL ",__func__);
18639 return -EINVAL;
18640 }
18641
18642 /* STA should be connected and authenticated
18643 * before sending any TDLS frames
18644 */
18645 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
18646 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
18647 {
18648 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18649 "STA is not connected or unauthenticated. "
18650 "connState %u, uIsAuthenticated %u",
18651 pHddStaCtx->conn_info.connState,
18652 pHddStaCtx->conn_info.uIsAuthenticated);
18653 return -EAGAIN;
18654 }
18655
Hoonki Lee27511902013-03-14 18:19:06 -070018656 /* other than teardown frame, other mgmt frames are not sent if disabled */
18657 if (SIR_MAC_TDLS_TEARDOWN != action_code)
18658 {
18659 /* if tdls_mode is disabled to respond to peer's request */
18660 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
18661 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018662 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070018663 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070018664 " TDLS mode is disabled. action %d declined.",
18665 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070018666
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018667 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070018668 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053018669
18670 if (vos_max_concurrent_connections_reached())
18671 {
18672 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
18673 return -EINVAL;
18674 }
Hoonki Lee27511902013-03-14 18:19:06 -070018675 }
18676
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018677 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
18678 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053018679 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018680 {
18681 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018682 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070018683 " TDLS setup is ongoing. action %d declined.",
18684 __func__, MAC_ADDR_ARRAY(peer), action_code);
18685 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018686 }
18687 }
18688
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018689 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
18690 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080018691 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053018692 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
18693 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080018694 {
18695 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
18696 we return error code at 'add_station()'. Hence we have this
18697 check again in addtion to add_station().
18698 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018699 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080018700 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018701 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18702 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053018703 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
18704 __func__, MAC_ADDR_ARRAY(peer), action_code,
18705 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053018706 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080018707 }
18708 else
18709 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018710 /* maximum reached. tweak to send error code to peer and return
18711 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080018712 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018713 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18714 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053018715 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
18716 __func__, MAC_ADDR_ARRAY(peer), status_code,
18717 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070018718 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018719 /* fall through to send setup resp with failure status
18720 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080018721 }
18722 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018723 else
18724 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018725 mutex_lock(&pHddCtx->tdls_lock);
18726 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018727 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018728 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018729 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018730 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070018731 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
18732 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018733 return -EPERM;
18734 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018735 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018736 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018737 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018738
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018739 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053018740 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018741 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
18742 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018743
Hoonki Leea34dd892013-02-05 22:56:02 -080018744 /*Except teardown responder will not be used so just make 0*/
18745 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018746 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080018747 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070018748
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018749 mutex_lock(&pHddCtx->tdls_lock);
18750 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070018751
18752 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
18753 responder = pTdlsPeer->is_responder;
18754 else
Hoonki Leea34dd892013-02-05 22:56:02 -080018755 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070018756 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053018757 "%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 -070018758 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
18759 dialog_token, status_code, len);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018760 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070018761 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080018762 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018763 mutex_unlock(&pHddCtx->tdls_lock);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018764 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018765
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053018766 /* Discard TDLS setup if peer is removed by user app */
18767 if ((pHddCtx->cfg_ini->fTDLSExternalControl) &&
18768 ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
18769 (SIR_MAC_TDLS_SETUP_CNF == action_code) ||
18770 (SIR_MAC_TDLS_DIS_REQ == action_code))) {
18771
18772 mutex_lock(&pHddCtx->tdls_lock);
18773 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18774 if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) {
18775 mutex_unlock(&pHddCtx->tdls_lock);
18776 hddLog(LOGE, FL("TDLS External Control enabled, but peer "
18777 MAC_ADDRESS_STR " is not forced, so reject the action code %d"),
18778 MAC_ADDR_ARRAY(peer), action_code);
18779 return -EINVAL;
18780 }
18781 mutex_unlock(&pHddCtx->tdls_lock);
18782 }
18783
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053018784 /* For explicit trigger of DIS_REQ come out of BMPS for
18785 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070018786 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Deepthi Gowrif78f1f72016-03-21 13:13:28 +053018787 (SIR_MAC_TDLS_SETUP_CNF== action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053018788 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
18789 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070018790 {
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053018791 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter))) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018792 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053018793 "%s: Sending frame action_code %u.Disable BMPS", __func__,
18794 action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018795 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
18796 if (status != VOS_STATUS_SUCCESS) {
18797 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053018798 } else {
18799 pHddTdlsCtx->is_tdls_disabled_bmps = true;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018800 }
Hoonki Lee14621352013-04-16 17:51:19 -070018801 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018802 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018803 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018804 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
18805 }
18806 }
Hoonki Lee14621352013-04-16 17:51:19 -070018807 }
18808
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018809 /* make sure doesn't call send_mgmt() while it is pending */
18810 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
18811 {
18812 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080018813 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018814 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018815 ret = -EBUSY;
18816 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018817 }
18818
18819 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018820 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
18821
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018822 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
18823 pAdapter->sessionId, peer, action_code, dialog_token,
18824 status_code, peer_capability, (tANI_U8 *)buf, len,
18825 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018826
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018827 if (VOS_STATUS_SUCCESS != status)
18828 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018829 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18830 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018831 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018832 ret = -EINVAL;
18833 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018834 }
18835
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018836 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18837 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
18838 WAIT_TIME_TDLS_MGMT);
18839
Hoonki Leed37cbb32013-04-20 00:31:14 -070018840 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
18841 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
18842
18843 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018844 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070018845 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070018846 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070018847 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018848 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080018849
18850 if (pHddCtx->isLogpInProgress)
18851 {
18852 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18853 "%s: LOGP in Progress. Ignore!!!", __func__);
18854 return -EAGAIN;
18855 }
Abhishek Singh837adf22015-10-01 17:37:37 +053018856 if (rc <= 0)
18857 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
18858 WLAN_LOG_INDICATOR_HOST_DRIVER,
18859 WLAN_LOG_REASON_HDD_TIME_OUT,
18860 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080018861
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018862 ret = -EINVAL;
18863 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018864 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018865 else
18866 {
18867 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18868 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
18869 __func__, rc, pAdapter->mgmtTxCompletionStatus);
18870 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018871
Gopichand Nakkala05922802013-03-14 12:23:19 -070018872 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070018873 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018874 ret = max_sta_failed;
18875 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070018876 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018877
Hoonki Leea34dd892013-02-05 22:56:02 -080018878 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
18879 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018880 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018881 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
18882 }
Hoonki Leea34dd892013-02-05 22:56:02 -080018883 }
18884 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
18885 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018886 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018887 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
18888 }
Hoonki Leea34dd892013-02-05 22:56:02 -080018889 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018890
18891 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018892
18893tx_failed:
18894 /* add_station will be called before sending TDLS_SETUP_REQ and
18895 * TDLS_SETUP_RSP and as part of add_station driver will enable
18896 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
18897 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
18898 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
18899 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
18900 */
18901
18902 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
18903 (SIR_MAC_TDLS_SETUP_RSP == action_code))
18904 wlan_hdd_tdls_check_bmps(pAdapter);
18905 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018906}
18907
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018908#if TDLS_MGMT_VERSION2
18909static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
18910 u8 *peer, u8 action_code, u8 dialog_token,
18911 u16 status_code, u32 peer_capability,
18912 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018913#else /* TDLS_MGMT_VERSION2 */
18914#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
18915static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18916 struct net_device *dev,
18917 const u8 *peer, u8 action_code,
18918 u8 dialog_token, u16 status_code,
18919 u32 peer_capability, bool initiator,
18920 const u8 *buf, size_t len)
18921#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18922static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18923 struct net_device *dev,
18924 const u8 *peer, u8 action_code,
18925 u8 dialog_token, u16 status_code,
18926 u32 peer_capability, const u8 *buf,
18927 size_t len)
18928#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
18929static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18930 struct net_device *dev,
18931 u8 *peer, u8 action_code,
18932 u8 dialog_token,
18933 u16 status_code, u32 peer_capability,
18934 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018935#else
18936static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
18937 u8 *peer, u8 action_code, u8 dialog_token,
18938 u16 status_code, const u8 *buf, size_t len)
18939#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018940#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018941{
18942 int ret;
18943
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018944 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018945#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018946 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
18947 dialog_token, status_code,
18948 peer_capability, buf, len);
18949#else /* TDLS_MGMT_VERSION2 */
18950#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
18951 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
18952 dialog_token, status_code,
18953 peer_capability, initiator,
18954 buf, len);
18955#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
18956 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
18957 dialog_token, status_code,
18958 peer_capability, buf, len);
18959#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
18960 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
18961 dialog_token, status_code,
18962 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018963#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018964 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
18965 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018966#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018967#endif
18968 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018969
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018970 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018971}
Atul Mittal115287b2014-07-08 13:26:33 +053018972
18973int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018974#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18975 const u8 *peer,
18976#else
Atul Mittal115287b2014-07-08 13:26:33 +053018977 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018978#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018979 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053018980 cfg80211_exttdls_callback callback)
18981{
18982
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018983 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053018984 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053018985 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053018986 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18987 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
18988 __func__, MAC_ADDR_ARRAY(peer));
18989
18990 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
18991 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
18992
18993 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018994 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
18995 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
18996 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053018997 return -ENOTSUPP;
18998 }
18999
19000 /* To cater the requirement of establishing the TDLS link
19001 * irrespective of the data traffic , get an entry of TDLS peer.
19002 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053019003 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019004 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
19005 if (pTdlsPeer == NULL) {
19006 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19007 "%s: peer " MAC_ADDRESS_STR " not existing",
19008 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053019009 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019010 return -EINVAL;
19011 }
19012
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053019013 /* check FW TDLS Off Channel capability */
19014 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053019015 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053019016 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019017 {
19018 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
19019 pTdlsPeer->peerParams.global_operating_class =
19020 tdls_peer_params->global_operating_class;
19021 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
19022 pTdlsPeer->peerParams.min_bandwidth_kbps =
19023 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053019024 /* check configured channel is valid, non dfs and
19025 * not current operating channel */
19026 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
19027 tdls_peer_params->channel)) &&
19028 (pHddStaCtx) &&
19029 (tdls_peer_params->channel !=
19030 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019031 {
19032 pTdlsPeer->isOffChannelConfigured = TRUE;
19033 }
19034 else
19035 {
19036 pTdlsPeer->isOffChannelConfigured = FALSE;
19037 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19038 "%s: Configured Tdls Off Channel is not valid", __func__);
19039
19040 }
19041 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053019042 "%s: tdls_off_channel %d isOffChannelConfigured %d "
19043 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019044 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053019045 pTdlsPeer->isOffChannelConfigured,
19046 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019047 }
19048 else
19049 {
19050 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053019051 "%s: TDLS off channel FW capability %d, "
19052 "host capab %d or Invalid TDLS Peer Params", __func__,
19053 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
19054 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019055 }
19056
Atul Mittal115287b2014-07-08 13:26:33 +053019057 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
19058
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019059 mutex_unlock(&pHddCtx->tdls_lock);
19060
Atul Mittal115287b2014-07-08 13:26:33 +053019061 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19062 " %s TDLS Add Force Peer Failed",
19063 __func__);
19064 return -EINVAL;
19065 }
19066 /*EXT TDLS*/
19067
19068 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019069 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019070 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19071 " %s TDLS set callback Failed",
19072 __func__);
19073 return -EINVAL;
19074 }
19075
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019076 mutex_unlock(&pHddCtx->tdls_lock);
19077
Atul Mittal115287b2014-07-08 13:26:33 +053019078 return(0);
19079
19080}
19081
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019082int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
19083#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19084 const u8 *peer
19085#else
19086 u8 *peer
19087#endif
19088)
Atul Mittal115287b2014-07-08 13:26:33 +053019089{
19090
19091 hddTdlsPeer_t *pTdlsPeer;
19092 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053019093
Atul Mittal115287b2014-07-08 13:26:33 +053019094 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19095 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
19096 __func__, MAC_ADDR_ARRAY(peer));
19097
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053019098 if (0 != wlan_hdd_validate_context(pHddCtx)) {
19099 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
19100 return -EINVAL;
19101 }
19102
Atul Mittal115287b2014-07-08 13:26:33 +053019103 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
19104 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
19105
19106 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019107 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
19108 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
19109 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053019110 return -ENOTSUPP;
19111 }
19112
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019113 mutex_lock(&pHddCtx->tdls_lock);
19114 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Atul Mittal115287b2014-07-08 13:26:33 +053019115
19116 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019117 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019118 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019119 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053019120 __func__, MAC_ADDR_ARRAY(peer));
19121 return -EINVAL;
19122 }
19123 else {
19124 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
19125 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053019126 hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_EXT_CTRL,
19127 pTdlsPeer->peerMac);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019128 /* if channel switch is configured, reset
19129 the channel for this peer */
19130 if (TRUE == pTdlsPeer->isOffChannelConfigured)
19131 {
19132 pTdlsPeer->peerParams.channel = 0;
19133 pTdlsPeer->isOffChannelConfigured = FALSE;
19134 }
Atul Mittal115287b2014-07-08 13:26:33 +053019135 }
19136
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019137 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019138 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019139 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053019140 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019141 }
Atul Mittal115287b2014-07-08 13:26:33 +053019142
19143 /*EXT TDLS*/
19144
19145 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019146 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019147 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19148 " %s TDLS set callback Failed",
19149 __func__);
19150 return -EINVAL;
19151 }
Atul Mittal115287b2014-07-08 13:26:33 +053019152
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019153 mutex_unlock(&pHddCtx->tdls_lock);
19154
19155 return(0);
Atul Mittal115287b2014-07-08 13:26:33 +053019156}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019157static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019158#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19159 const u8 *peer,
19160#else
19161 u8 *peer,
19162#endif
19163 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019164{
19165 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19166 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019167 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019168 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019169
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019170 ENTER();
19171
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053019172 if (!pAdapter) {
19173 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
19174 return -EINVAL;
19175 }
19176
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019177 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19178 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
19179 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019180 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019181 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019182 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070019183 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019184 return -EINVAL;
19185 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080019186
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019187 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019188 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080019189 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019190 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080019191 }
19192
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019193
19194 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080019195 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019196 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080019197 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019198 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
19199 "Cannot process TDLS commands",
19200 pHddCtx->cfg_ini->fEnableTDLSSupport,
19201 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019202 return -ENOTSUPP;
19203 }
19204
19205 switch (oper) {
19206 case NL80211_TDLS_ENABLE_LINK:
19207 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019208 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019209 long ret;
Hanumantha Reddy Pothulada389492016-02-11 17:29:27 +053019210 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams = { {0}, 0,
19211 0, 0, 0, 0, 0, 0, {0}, 0, {0} };
Agarwal Ashish16020c42014-12-29 22:01:11 +053019212 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019213 tANI_U16 numCurrTdlsPeers = 0;
19214 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053019215 tANI_U8 suppChannelLen = 0;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019216 tSirMacAddr peerMac;
19217 int channel;
19218 tTDLSLinkStatus peer_status = eTDLS_LINK_IDLE;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019219
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019220 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19221 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
19222 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019223
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019224 mutex_lock(&pHddCtx->tdls_lock);
19225 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053019226 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053019227 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019228 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053019229 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
19230 " (oper %d) not exsting. ignored",
19231 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
19232 return -EINVAL;
19233 }
19234
19235 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19236 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
19237 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
19238 "NL80211_TDLS_ENABLE_LINK");
19239
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070019240 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
19241 {
19242 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
19243 MAC_ADDRESS_STR " failed",
19244 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019245 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070019246 return -EINVAL;
19247 }
19248
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053019249 /* before starting tdls connection, set tdls
19250 * off channel established status to default value */
19251 pTdlsPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019252
19253 mutex_unlock(&pHddCtx->tdls_lock);
19254
Deepthi Gowri2d85bbf2016-07-25 15:43:31 +053019255 wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019256 /* TDLS Off Channel, Disable tdls channel switch,
19257 when there are more than one tdls link */
19258 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053019259 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019260 {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019261 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019262 /* get connected peer and send disable tdls off chan */
19263 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019264 if ((connPeer) &&
19265 (connPeer->isOffChannelSupported == TRUE) &&
19266 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019267 {
19268 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19269 "%s: More then one peer connected, Disable "
19270 "TDLS channel switch", __func__);
19271
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053019272 connPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019273 vos_mem_copy(peerMac, connPeer->peerMac, sizeof (tSirMacAddr));
19274 channel = connPeer->peerParams.channel;
19275
19276 mutex_unlock(&pHddCtx->tdls_lock);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019277
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019278 ret = sme_SendTdlsChanSwitchReq(
19279 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019280 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019281 peerMac,
19282 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019283 TDLS_OFF_CHANNEL_BW_OFFSET,
19284 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019285 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019286 hddLog(VOS_TRACE_LEVEL_ERROR,
19287 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019288 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019289 }
19290 else
19291 {
19292 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19293 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019294 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019295 "isOffChannelConfigured %d",
19296 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019297 (connPeer ? (connPeer->isOffChannelSupported)
19298 : -1),
19299 (connPeer ? (connPeer->isOffChannelConfigured)
19300 : -1));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019301 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019302 }
19303 }
19304
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019305 mutex_lock(&pHddCtx->tdls_lock);
19306 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
19307 if ( NULL == pTdlsPeer ) {
19308 mutex_unlock(&pHddCtx->tdls_lock);
19309 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19310 "%s: " MAC_ADDRESS_STR
19311 " (oper %d) peer got freed in other context. ignored",
19312 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
19313 return -EINVAL;
19314 }
19315 peer_status = pTdlsPeer->link_status;
19316 mutex_unlock(&pHddCtx->tdls_lock);
19317
19318 if (eTDLS_LINK_CONNECTED != peer_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019319 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019320 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053019321
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019322 if (0 != wlan_hdd_tdls_get_link_establish_params(
19323 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019324 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019325 return -EINVAL;
19326 }
19327 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053019328
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019329 ret = sme_SendTdlsLinkEstablishParams(
19330 WLAN_HDD_GET_HAL_CTX(pAdapter),
19331 pAdapter->sessionId, peer,
19332 &tdlsLinkEstablishParams);
19333 if (ret != VOS_STATUS_SUCCESS) {
19334 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
19335 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019336 /* Send TDLS peer UAPSD capabilities to the firmware and
19337 * register with the TL on after the response for this operation
19338 * is received .
19339 */
19340 ret = wait_for_completion_interruptible_timeout(
19341 &pAdapter->tdls_link_establish_req_comp,
19342 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
Masti, Narayanraddie1892a52015-12-15 15:01:01 +053019343
19344 mutex_lock(&pHddCtx->tdls_lock);
19345 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
19346 if ( NULL == pTdlsPeer ) {
19347 mutex_unlock(&pHddCtx->tdls_lock);
19348 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19349 "%s %d: " MAC_ADDRESS_STR
19350 " (oper %d) peer got freed in other context. ignored",
19351 __func__, __LINE__, MAC_ADDR_ARRAY(peer),
19352 (int)oper);
19353 return -EINVAL;
19354 }
19355 peer_status = pTdlsPeer->link_status;
19356 mutex_unlock(&pHddCtx->tdls_lock);
19357
19358 if (ret <= 0 || (peer_status == eTDLS_LINK_TEARING))
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019359 {
19360 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019361 FL("Link Establish Request Failed Status %ld"),
19362 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019363 return -EINVAL;
19364 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053019365 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019366
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019367 mutex_lock(&pHddCtx->tdls_lock);
19368 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
19369 if ( NULL == pTdlsPeer ) {
19370 mutex_unlock(&pHddCtx->tdls_lock);
19371 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19372 "%s: " MAC_ADDRESS_STR
19373 " (oper %d) peer got freed in other context. ignored",
19374 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
19375 return -EINVAL;
19376 }
19377
Atul Mittal115287b2014-07-08 13:26:33 +053019378 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
19379 eTDLS_LINK_CONNECTED,
19380 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053019381 staDesc.ucSTAId = pTdlsPeer->staId;
19382 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053019383
19384 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19385 "%s: tdlsLinkEstablishParams of peer "
19386 MAC_ADDRESS_STR "uapsdQueues: %d"
19387 "qos: %d maxSp: %d isBufSta: %d isOffChannelSupported: %d"
19388 "isResponder: %d peerstaId: %d",
19389 __func__,
19390 MAC_ADDR_ARRAY(tdlsLinkEstablishParams.peerMac),
19391 tdlsLinkEstablishParams.uapsdQueues,
19392 tdlsLinkEstablishParams.qos,
19393 tdlsLinkEstablishParams.maxSp,
19394 tdlsLinkEstablishParams.isBufSta,
19395 tdlsLinkEstablishParams.isOffChannelSupported,
19396 tdlsLinkEstablishParams.isResponder,
19397 pTdlsPeer->staId);
19398
19399 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19400 "%s: StaDesc ucSTAId: %d ucQosEnabled: %d",
19401 __func__,
19402 staDesc.ucSTAId,
19403 staDesc.ucQosEnabled);
19404
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019405 ret = WLANTL_UpdateTdlsSTAClient(
19406 pHddCtx->pvosContext,
19407 &staDesc);
19408 if (ret != VOS_STATUS_SUCCESS) {
19409 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
19410 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053019411
Gopichand Nakkala471708b2013-06-04 20:03:01 +053019412 /* Mark TDLS client Authenticated .*/
19413 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
19414 pTdlsPeer->staId,
19415 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070019416 if (VOS_STATUS_SUCCESS == status)
19417 {
Hoonki Lee14621352013-04-16 17:51:19 -070019418 if (pTdlsPeer->is_responder == 0)
19419 {
19420 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053019421 tdlsConnInfo_t *tdlsInfo;
19422
19423 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
19424
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053019425 if (!vos_timer_is_initialized(
19426 &pTdlsPeer->initiatorWaitTimeoutTimer))
19427 {
19428 /* Initialize initiator wait callback */
19429 vos_timer_init(
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053019430 &pTdlsPeer->initiatorWaitTimeoutTimer,
19431 VOS_TIMER_TYPE_SW,
19432 wlan_hdd_tdls_initiator_wait_cb,
19433 tdlsInfo);
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053019434 }
Hoonki Lee14621352013-04-16 17:51:19 -070019435 wlan_hdd_tdls_timer_restart(pAdapter,
19436 &pTdlsPeer->initiatorWaitTimeoutTimer,
19437 WAIT_TIME_TDLS_INITIATOR);
19438 /* suspend initiator TX until it receives direct packet from the
19439 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019440 ret = WLANTL_SuspendDataTx(
19441 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
19442 &staId, NULL);
19443 if (ret != VOS_STATUS_SUCCESS) {
19444 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
19445 }
Hoonki Lee14621352013-04-16 17:51:19 -070019446 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019447
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053019448 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019449 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053019450 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019451 suppChannelLen =
19452 tdlsLinkEstablishParams.supportedChannelsLen;
19453
19454 if ((suppChannelLen > 0) &&
19455 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
19456 {
19457 tANI_U8 suppPeerChannel = 0;
19458 int i = 0;
19459 for (i = 0U; i < suppChannelLen; i++)
19460 {
19461 suppPeerChannel =
19462 tdlsLinkEstablishParams.supportedChannels[i];
19463
19464 pTdlsPeer->isOffChannelSupported = FALSE;
19465 if (suppPeerChannel ==
19466 pTdlsPeer->peerParams.channel)
19467 {
19468 pTdlsPeer->isOffChannelSupported = TRUE;
19469 break;
19470 }
19471 }
19472 }
19473 else
19474 {
19475 pTdlsPeer->isOffChannelSupported = FALSE;
19476 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053019477 }
19478 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19479 "%s: TDLS channel switch request for channel "
19480 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019481 "%d isOffChannelSupported %d", __func__,
19482 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053019483 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019484 suppChannelLen,
19485 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053019486
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019487 /* TDLS Off Channel, Enable tdls channel switch,
19488 when their is only one tdls link and it supports */
19489 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
19490 if ((numCurrTdlsPeers == 1) &&
19491 (TRUE == pTdlsPeer->isOffChannelSupported) &&
19492 (TRUE == pTdlsPeer->isOffChannelConfigured))
19493 {
19494 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19495 "%s: Send TDLS channel switch request for channel %d",
19496 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053019497
19498 pTdlsPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019499 vos_mem_copy(peerMac, pTdlsPeer->peerMac, sizeof (tSirMacAddr));
19500 channel = pTdlsPeer->peerParams.channel;
19501
19502 mutex_unlock(&pHddCtx->tdls_lock);
19503
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019504 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
19505 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019506 peerMac,
19507 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019508 TDLS_OFF_CHANNEL_BW_OFFSET,
19509 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019510 if (ret != VOS_STATUS_SUCCESS) {
19511 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
19512 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019513 }
19514 else
19515 {
19516 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19517 "%s: TDLS channel switch request not sent"
19518 " numCurrTdlsPeers %d "
19519 "isOffChannelSupported %d "
19520 "isOffChannelConfigured %d",
19521 __func__, numCurrTdlsPeers,
19522 pTdlsPeer->isOffChannelSupported,
19523 pTdlsPeer->isOffChannelConfigured);
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019524 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019525 }
19526
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070019527 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019528 else
19529 mutex_unlock(&pHddCtx->tdls_lock);
19530
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019531 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053019532
19533 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053019534 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
19535 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053019536 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053019537 int ac;
19538 uint8 ucAc[4] = { WLANTL_AC_VO,
19539 WLANTL_AC_VI,
19540 WLANTL_AC_BK,
19541 WLANTL_AC_BE };
19542 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
19543 for(ac=0; ac < 4; ac++)
19544 {
19545 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
19546 pTdlsPeer->staId, ucAc[ac],
19547 tlTid[ac], tlTid[ac], 0, 0,
19548 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019549 if (status != VOS_STATUS_SUCCESS) {
19550 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
19551 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053019552 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053019553 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019554 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019555
Bhargav Shah66896792015-10-01 18:17:37 +053019556 /* stop TCP delack timer if TDLS is enable */
19557 set_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
19558 hdd_manage_delack_timer(pHddCtx);
Abhishek Singh67fa6bc2016-01-05 15:57:19 +053019559 hdd_wlan_tdls_enable_link_event(peer,
19560 pTdlsPeer->isOffChannelSupported,
19561 pTdlsPeer->isOffChannelConfigured,
19562 pTdlsPeer->isOffChannelEstablished);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019563 }
19564 break;
19565 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080019566 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019567 tANI_U16 numCurrTdlsPeers = 0;
19568 hddTdlsPeer_t *connPeer = NULL;
19569
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019570 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19571 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
19572 __func__, MAC_ADDR_ARRAY(peer));
19573
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019574 mutex_lock(&pHddCtx->tdls_lock);
19575 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Sunil Dutt41de4e22013-11-14 18:09:02 +053019576
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019577
Sunil Dutt41de4e22013-11-14 18:09:02 +053019578 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019579 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053019580 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
19581 " (oper %d) not exsting. ignored",
19582 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
19583 return -EINVAL;
19584 }
19585
19586 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19587 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
19588 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
19589 "NL80211_TDLS_DISABLE_LINK");
19590
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019591 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080019592 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019593 long status;
19594
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053019595 /* set tdls off channel status to false for this peer */
19596 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053019597 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
19598 eTDLS_LINK_TEARING,
19599 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
19600 eTDLS_LINK_UNSPECIFIED:
19601 eTDLS_LINK_DROPPED_BY_REMOTE);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019602 mutex_unlock(&pHddCtx->tdls_lock);
19603
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019604 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
19605
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019606 status = sme_DeleteTdlsPeerSta(
19607 WLAN_HDD_GET_HAL_CTX(pAdapter),
19608 pAdapter->sessionId, peer );
19609 if (status != VOS_STATUS_SUCCESS) {
19610 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
19611 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019612
19613 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
19614 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019615
19616 mutex_lock(&pHddCtx->tdls_lock);
19617 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
19618 if ( NULL == pTdlsPeer ) {
19619 mutex_unlock(&pHddCtx->tdls_lock);
19620 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
19621 " peer was freed in other context",
19622 __func__, MAC_ADDR_ARRAY(peer));
19623 return -EINVAL;
19624 }
19625
Atul Mittal271a7652014-09-12 13:18:22 +053019626 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053019627 eTDLS_LINK_IDLE,
19628 eTDLS_LINK_UNSPECIFIED);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019629 mutex_unlock(&pHddCtx->tdls_lock);
19630
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019631 if (status <= 0)
19632 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019633 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19634 "%s: Del station failed status %ld",
19635 __func__, status);
19636 return -EPERM;
19637 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019638
19639 /* TDLS Off Channel, Enable tdls channel switch,
19640 when their is only one tdls link and it supports */
19641 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
19642 if (numCurrTdlsPeers == 1)
19643 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019644 tSirMacAddr peerMac;
19645 int channel;
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053019646
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019647 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019648 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053019649
19650 if (connPeer == NULL) {
19651 mutex_unlock(&pHddCtx->tdls_lock);
19652 hddLog(VOS_TRACE_LEVEL_ERROR,
19653 "%s connPeer is NULL", __func__);
19654 return -EINVAL;
19655 }
19656
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019657 vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr));
19658 channel = connPeer->peerParams.channel;
19659
19660 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19661 "%s: TDLS channel switch "
19662 "isOffChannelSupported %d "
19663 "isOffChannelConfigured %d "
19664 "isOffChannelEstablished %d",
19665 __func__,
19666 (connPeer ? connPeer->isOffChannelSupported : -1),
19667 (connPeer ? connPeer->isOffChannelConfigured : -1),
19668 (connPeer ? connPeer->isOffChannelEstablished : -1));
19669
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019670 if ((connPeer) &&
19671 (connPeer->isOffChannelSupported == TRUE) &&
19672 (connPeer->isOffChannelConfigured == TRUE))
19673 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053019674 connPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019675 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019676 status = sme_SendTdlsChanSwitchReq(
19677 WLAN_HDD_GET_HAL_CTX(pAdapter),
19678 pAdapter->sessionId,
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019679 peerMac,
19680 channel,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019681 TDLS_OFF_CHANNEL_BW_OFFSET,
19682 TDLS_CHANNEL_SWITCH_ENABLE);
19683 if (status != VOS_STATUS_SUCCESS) {
19684 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
19685 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019686 }
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019687 else
19688 mutex_unlock(&pHddCtx->tdls_lock);
19689 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019690 else
19691 {
19692 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19693 "%s: TDLS channel switch request not sent "
19694 "numCurrTdlsPeers %d ",
19695 __func__, numCurrTdlsPeers);
19696 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080019697 }
19698 else
19699 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019700 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019701 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19702 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080019703 }
Bhargav Shah66896792015-10-01 18:17:37 +053019704 if (numCurrTdlsPeers == 0) {
19705 /* start TCP delack timer if TDLS is disable */
19706 clear_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
19707 hdd_manage_delack_timer(pHddCtx);
19708 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080019709 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019710 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019711 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053019712 {
Atul Mittal115287b2014-07-08 13:26:33 +053019713 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053019714
Atul Mittal115287b2014-07-08 13:26:33 +053019715 if (0 != status)
19716 {
19717 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019718 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053019719 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053019720 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053019721 break;
19722 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019723 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053019724 {
Atul Mittal115287b2014-07-08 13:26:33 +053019725 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
19726 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019727 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053019728 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053019729
Atul Mittal115287b2014-07-08 13:26:33 +053019730 if (0 != status)
19731 {
19732 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019733 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053019734 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053019735 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053019736 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053019737 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019738 case NL80211_TDLS_DISCOVERY_REQ:
19739 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019740 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019741 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019742 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019743 return -ENOTSUPP;
19744 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019745 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19746 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019747 return -ENOTSUPP;
19748 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019749
19750 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019751 return 0;
19752}
Chilam NG571c65a2013-01-19 12:27:36 +053019753
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019754static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019755#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19756 const u8 *peer,
19757#else
19758 u8 *peer,
19759#endif
19760 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019761{
19762 int ret;
19763
19764 vos_ssr_protect(__func__);
19765 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
19766 vos_ssr_unprotect(__func__);
19767
19768 return ret;
19769}
19770
Chilam NG571c65a2013-01-19 12:27:36 +053019771int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
19772 struct net_device *dev, u8 *peer)
19773{
Arif Hussaina7c8e412013-11-20 11:06:42 -080019774 hddLog(VOS_TRACE_LEVEL_INFO,
19775 "tdls send discover req: "MAC_ADDRESS_STR,
19776 MAC_ADDR_ARRAY(peer));
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019777#if TDLS_MGMT_VERSION2
19778 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19779 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
19780#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019781#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
19782 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19783 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
19784#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
19785 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19786 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
19787#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
19788 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19789 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
19790#else
Chilam NG571c65a2013-01-19 12:27:36 +053019791 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19792 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019793#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019794#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053019795}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019796#endif
19797
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019798#ifdef WLAN_FEATURE_GTK_OFFLOAD
19799/*
19800 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
19801 * Callback rountine called upon receiving response for
19802 * get offload info
19803 */
19804void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
19805 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
19806{
19807
19808 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019809 tANI_U8 tempReplayCounter[8];
19810 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019811
19812 ENTER();
19813
19814 if (NULL == pAdapter)
19815 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053019816 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019817 "%s: HDD adapter is Null", __func__);
19818 return ;
19819 }
19820
19821 if (NULL == pGtkOffloadGetInfoRsp)
19822 {
19823 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19824 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
19825 return ;
19826 }
19827
19828 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
19829 {
19830 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19831 "%s: wlan Failed to get replay counter value",
19832 __func__);
19833 return ;
19834 }
19835
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019836 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
19837 /* Update replay counter */
19838 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
19839 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
19840
19841 {
19842 /* changing from little to big endian since supplicant
19843 * works on big endian format
19844 */
19845 int i;
19846 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
19847
19848 for (i = 0; i < 8; i++)
19849 {
19850 tempReplayCounter[7-i] = (tANI_U8)p[i];
19851 }
19852 }
19853
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019854 /* Update replay counter to NL */
19855 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019856 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019857}
19858
19859/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019860 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019861 * This function is used to offload GTK rekeying job to the firmware.
19862 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019863int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019864 struct cfg80211_gtk_rekey_data *data)
19865{
19866 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19867 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
19868 hdd_station_ctx_t *pHddStaCtx;
19869 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019870 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019871 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019872 eHalStatus status = eHAL_STATUS_FAILURE;
19873
19874 ENTER();
19875
19876 if (NULL == pAdapter)
19877 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019878 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019879 "%s: HDD adapter is Null", __func__);
19880 return -ENODEV;
19881 }
19882
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019883 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19884 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
19885 pAdapter->sessionId, pAdapter->device_mode));
19886
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019887 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019888 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019889 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019890 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019891 }
19892
19893 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
19894 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
19895 if (NULL == hHal)
19896 {
19897 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19898 "%s: HAL context is Null!!!", __func__);
19899 return -EAGAIN;
19900 }
19901
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019902 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
19903 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
19904 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
19905 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019906 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019907 {
19908 /* changing from big to little endian since driver
19909 * works on little endian format
19910 */
19911 tANI_U8 *p =
19912 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
19913 int i;
19914
19915 for (i = 0; i < 8; i++)
19916 {
19917 p[7-i] = data->replay_ctr[i];
19918 }
19919 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019920
19921 if (TRUE == pHddCtx->hdd_wlan_suspended)
19922 {
19923 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019924 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
19925 sizeof (tSirGtkOffloadParams));
19926 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019927 pAdapter->sessionId);
19928
19929 if (eHAL_STATUS_SUCCESS != status)
19930 {
19931 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19932 "%s: sme_SetGTKOffload failed, returned %d",
19933 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053019934
19935 /* Need to clear any trace of key value in the memory.
19936 * Thus zero out the memory even though it is local
19937 * variable.
19938 */
19939 vos_mem_zero(&hddGtkOffloadReqParams,
19940 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019941 return status;
19942 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019943 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19944 "%s: sme_SetGTKOffload successfull", __func__);
19945 }
19946 else
19947 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019948 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19949 "%s: wlan not suspended GTKOffload request is stored",
19950 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019951 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019952
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053019953 /* Need to clear any trace of key value in the memory.
19954 * Thus zero out the memory even though it is local
19955 * variable.
19956 */
19957 vos_mem_zero(&hddGtkOffloadReqParams,
19958 sizeof(hddGtkOffloadReqParams));
19959
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019960 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019961 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019962}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019963
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019964int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
19965 struct cfg80211_gtk_rekey_data *data)
19966{
19967 int ret;
19968
19969 vos_ssr_protect(__func__);
19970 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
19971 vos_ssr_unprotect(__func__);
19972
19973 return ret;
19974}
19975#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019976/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019977 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019978 * This function is used to set access control policy
19979 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019980static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
19981 struct net_device *dev,
19982 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019983{
19984 int i;
19985 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19986 hdd_hostapd_state_t *pHostapdState;
19987 tsap_Config_t *pConfig;
19988 v_CONTEXT_t pVosContext = NULL;
19989 hdd_context_t *pHddCtx;
19990 int status;
19991
19992 ENTER();
19993
19994 if (NULL == pAdapter)
19995 {
19996 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19997 "%s: HDD adapter is Null", __func__);
19998 return -ENODEV;
19999 }
20000
20001 if (NULL == params)
20002 {
20003 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20004 "%s: params is Null", __func__);
20005 return -EINVAL;
20006 }
20007
20008 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
20009 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020010 if (0 != status)
20011 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020012 return status;
20013 }
20014
20015 pVosContext = pHddCtx->pvosContext;
20016 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
20017
20018 if (NULL == pHostapdState)
20019 {
20020 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20021 "%s: pHostapdState is Null", __func__);
20022 return -EINVAL;
20023 }
20024
20025 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
20026 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053020027 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20028 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
20029 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020030
20031 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
20032 {
20033 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
20034
20035 /* default value */
20036 pConfig->num_accept_mac = 0;
20037 pConfig->num_deny_mac = 0;
20038
20039 /**
20040 * access control policy
20041 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
20042 * listed in hostapd.deny file.
20043 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
20044 * listed in hostapd.accept file.
20045 */
20046 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
20047 {
20048 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
20049 }
20050 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
20051 {
20052 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
20053 }
20054 else
20055 {
20056 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20057 "%s:Acl Policy : %d is not supported",
20058 __func__, params->acl_policy);
20059 return -ENOTSUPP;
20060 }
20061
20062 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
20063 {
20064 pConfig->num_accept_mac = params->n_acl_entries;
20065 for (i = 0; i < params->n_acl_entries; i++)
20066 {
20067 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20068 "** Add ACL MAC entry %i in WhiletList :"
20069 MAC_ADDRESS_STR, i,
20070 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
20071
20072 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
20073 sizeof(qcmacaddr));
20074 }
20075 }
20076 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
20077 {
20078 pConfig->num_deny_mac = params->n_acl_entries;
20079 for (i = 0; i < params->n_acl_entries; i++)
20080 {
20081 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20082 "** Add ACL MAC entry %i in BlackList :"
20083 MAC_ADDRESS_STR, i,
20084 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
20085
20086 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
20087 sizeof(qcmacaddr));
20088 }
20089 }
20090
20091 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
20092 {
20093 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20094 "%s: SAP Set Mac Acl fail", __func__);
20095 return -EINVAL;
20096 }
20097 }
20098 else
20099 {
20100 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053020101 "%s: Invalid device_mode = %s (%d)",
20102 __func__, hdd_device_modetoString(pAdapter->device_mode),
20103 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020104 return -EINVAL;
20105 }
20106
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020107 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020108 return 0;
20109}
20110
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020111static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
20112 struct net_device *dev,
20113 const struct cfg80211_acl_data *params)
20114{
20115 int ret;
20116 vos_ssr_protect(__func__);
20117 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
20118 vos_ssr_unprotect(__func__);
20119
20120 return ret;
20121}
20122
Leo Chang9056f462013-08-01 19:21:11 -070020123#ifdef WLAN_NL80211_TESTMODE
20124#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070020125void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070020126(
20127 void *pAdapter,
20128 void *indCont
20129)
20130{
Leo Changd9df8aa2013-09-26 13:32:26 -070020131 tSirLPHBInd *lphbInd;
20132 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053020133 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070020134
20135 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070020136 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070020137
c_hpothu73f35e62014-04-18 13:40:08 +053020138 if (pAdapter == NULL)
20139 {
20140 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20141 "%s: pAdapter is NULL\n",__func__);
20142 return;
20143 }
20144
Leo Chang9056f462013-08-01 19:21:11 -070020145 if (NULL == indCont)
20146 {
20147 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070020148 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070020149 return;
20150 }
20151
c_hpothu73f35e62014-04-18 13:40:08 +053020152 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070020153 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070020154 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053020155 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070020156 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070020157 GFP_ATOMIC);
20158 if (!skb)
20159 {
20160 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20161 "LPHB timeout, NL buffer alloc fail");
20162 return;
20163 }
20164
Leo Changac3ba772013-10-07 09:47:04 -070020165 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070020166 {
20167 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20168 "WLAN_HDD_TM_ATTR_CMD put fail");
20169 goto nla_put_failure;
20170 }
Leo Changac3ba772013-10-07 09:47:04 -070020171 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070020172 {
20173 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20174 "WLAN_HDD_TM_ATTR_TYPE put fail");
20175 goto nla_put_failure;
20176 }
Leo Changac3ba772013-10-07 09:47:04 -070020177 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070020178 sizeof(tSirLPHBInd), lphbInd))
20179 {
20180 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20181 "WLAN_HDD_TM_ATTR_DATA put fail");
20182 goto nla_put_failure;
20183 }
Leo Chang9056f462013-08-01 19:21:11 -070020184 cfg80211_testmode_event(skb, GFP_ATOMIC);
20185 return;
20186
20187nla_put_failure:
20188 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20189 "NLA Put fail");
20190 kfree_skb(skb);
20191
20192 return;
20193}
20194#endif /* FEATURE_WLAN_LPHB */
20195
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020196static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070020197{
20198 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
20199 int err = 0;
20200#ifdef FEATURE_WLAN_LPHB
20201 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070020202 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020203
20204 ENTER();
20205
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053020206 err = wlan_hdd_validate_context(pHddCtx);
20207 if (0 != err)
20208 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053020209 return err;
20210 }
Leo Chang9056f462013-08-01 19:21:11 -070020211#endif /* FEATURE_WLAN_LPHB */
20212
20213 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
20214 if (err)
20215 {
20216 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20217 "%s Testmode INV ATTR", __func__);
20218 return err;
20219 }
20220
20221 if (!tb[WLAN_HDD_TM_ATTR_CMD])
20222 {
20223 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20224 "%s Testmode INV CMD", __func__);
20225 return -EINVAL;
20226 }
20227
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053020228 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20229 TRACE_CODE_HDD_CFG80211_TESTMODE,
20230 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070020231 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
20232 {
20233#ifdef FEATURE_WLAN_LPHB
20234 /* Low Power Heartbeat configuration request */
20235 case WLAN_HDD_TM_CMD_WLAN_HB:
20236 {
20237 int buf_len;
20238 void *buf;
20239 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080020240 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070020241
20242 if (!tb[WLAN_HDD_TM_ATTR_DATA])
20243 {
20244 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20245 "%s Testmode INV DATA", __func__);
20246 return -EINVAL;
20247 }
20248
20249 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
20250 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080020251
Manjeet Singh3c577442017-02-10 19:03:38 +053020252 if (buf_len > sizeof(*hb_params)) {
20253 hddLog(LOGE, FL("buf_len=%d exceeded hb_params size limit"),
20254 buf_len);
20255 return -ERANGE;
20256 }
20257
Amar Singhal05852702014-02-04 14:40:00 -080020258 hb_params_temp =(tSirLPHBReq *)buf;
20259 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
20260 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
20261 return -EINVAL;
20262
Leo Chang9056f462013-08-01 19:21:11 -070020263 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
20264 if (NULL == hb_params)
20265 {
20266 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20267 "%s Request Buffer Alloc Fail", __func__);
20268 return -EINVAL;
20269 }
20270
Ashish Kumar Dhanotiya3a8c0a72017-07-13 18:58:59 +053020271 vos_mem_zero(hb_params, sizeof(tSirLPHBReq));
Leo Chang9056f462013-08-01 19:21:11 -070020272 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070020273 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
20274 hb_params,
20275 wlan_hdd_cfg80211_lphb_ind_handler);
20276 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070020277 {
Leo Changd9df8aa2013-09-26 13:32:26 -070020278 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20279 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070020280 vos_mem_free(hb_params);
20281 }
Leo Chang9056f462013-08-01 19:21:11 -070020282 return 0;
20283 }
20284#endif /* FEATURE_WLAN_LPHB */
20285 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020286 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20287 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070020288 return -EOPNOTSUPP;
20289 }
20290
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020291 EXIT();
20292 return err;
Leo Chang9056f462013-08-01 19:21:11 -070020293}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020294
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053020295static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
20296#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
20297 struct wireless_dev *wdev,
20298#endif
20299 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020300{
20301 int ret;
20302
20303 vos_ssr_protect(__func__);
20304 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
20305 vos_ssr_unprotect(__func__);
20306
20307 return ret;
20308}
Leo Chang9056f462013-08-01 19:21:11 -070020309#endif /* CONFIG_NL80211_TESTMODE */
20310
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053020311extern void hdd_set_wlan_suspend_mode(bool suspend);
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020312static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020313 struct net_device *dev,
20314 int idx, struct survey_info *survey)
20315{
20316 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20317 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053020318 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020319 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053020320 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020321 v_S7_t snr,rssi;
20322 int status, i, j, filled = 0;
20323
20324 ENTER();
20325
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020326 if (NULL == pAdapter)
20327 {
20328 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20329 "%s: HDD adapter is Null", __func__);
20330 return -ENODEV;
20331 }
20332
20333 if (NULL == wiphy)
20334 {
20335 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20336 "%s: wiphy is Null", __func__);
20337 return -ENODEV;
20338 }
20339
20340 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
20341 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020342 if (0 != status)
20343 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020344 return status;
20345 }
20346
Mihir Sheted9072e02013-08-21 17:02:29 +053020347 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
20348
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020349 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053020350 0 != pAdapter->survey_idx ||
20351 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020352 {
20353 /* The survey dump ops when implemented completely is expected to
20354 * return a survey of all channels and the ops is called by the
20355 * kernel with incremental values of the argument 'idx' till it
20356 * returns -ENONET. But we can only support the survey for the
20357 * operating channel for now. survey_idx is used to track
20358 * that the ops is called only once and then return -ENONET for
20359 * the next iteration
20360 */
20361 pAdapter->survey_idx = 0;
20362 return -ENONET;
20363 }
20364
Mukul Sharma9d5233b2015-06-11 20:28:20 +053020365 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
20366 {
20367 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20368 "%s: Roaming in progress, hence return ", __func__);
20369 return -ENONET;
20370 }
20371
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020372 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
20373
20374 wlan_hdd_get_snr(pAdapter, &snr);
20375 wlan_hdd_get_rssi(pAdapter, &rssi);
20376
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053020377 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20378 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
20379 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020380 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
20381 hdd_wlan_get_freq(channel, &freq);
20382
20383
20384 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
20385 {
20386 if (NULL == wiphy->bands[i])
20387 {
20388 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
20389 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
20390 continue;
20391 }
20392
20393 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
20394 {
20395 struct ieee80211_supported_band *band = wiphy->bands[i];
20396
20397 if (band->channels[j].center_freq == (v_U16_t)freq)
20398 {
20399 survey->channel = &band->channels[j];
20400 /* The Rx BDs contain SNR values in dB for the received frames
20401 * while the supplicant expects noise. So we calculate and
20402 * return the value of noise (dBm)
20403 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
20404 */
20405 survey->noise = rssi - snr;
20406 survey->filled = SURVEY_INFO_NOISE_DBM;
20407 filled = 1;
20408 }
20409 }
20410 }
20411
20412 if (filled)
20413 pAdapter->survey_idx = 1;
20414 else
20415 {
20416 pAdapter->survey_idx = 0;
20417 return -ENONET;
20418 }
20419
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020420 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020421 return 0;
20422}
20423
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020424static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
20425 struct net_device *dev,
20426 int idx, struct survey_info *survey)
20427{
20428 int ret;
20429
20430 vos_ssr_protect(__func__);
20431 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
20432 vos_ssr_unprotect(__func__);
20433
20434 return ret;
20435}
20436
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020437/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053020438 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020439 * this is called when cfg80211 driver resume
20440 * driver updates latest sched_scan scan result(if any) to cfg80211 database
20441 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053020442int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020443{
20444 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
20445 hdd_adapter_t *pAdapter;
20446 hdd_adapter_list_node_t *pAdapterNode, *pNext;
20447 VOS_STATUS status = VOS_STATUS_SUCCESS;
20448
20449 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020450
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053020451 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020452 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020453 return 0;
20454 }
20455
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053020456 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
20457 NO_SESSION, pHddCtx->isWiphySuspended));
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053020458
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053020459 if (pHddCtx->is_ap_mode_wow_supported)
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053020460 {
20461 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20462 "%s: Resume SoftAP", __func__);
20463 hdd_set_wlan_suspend_mode(false);
20464 }
20465
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020466 spin_lock(&pHddCtx->schedScan_lock);
20467 pHddCtx->isWiphySuspended = FALSE;
20468 if (TRUE != pHddCtx->isSchedScanUpdatePending)
20469 {
20470 spin_unlock(&pHddCtx->schedScan_lock);
20471 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20472 "%s: Return resume is not due to PNO indication", __func__);
20473 return 0;
20474 }
20475 // Reset flag to avoid updatating cfg80211 data old results again
20476 pHddCtx->isSchedScanUpdatePending = FALSE;
20477 spin_unlock(&pHddCtx->schedScan_lock);
20478
20479 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
20480
20481 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
20482 {
20483 pAdapter = pAdapterNode->pAdapter;
20484 if ( (NULL != pAdapter) &&
20485 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
20486 {
20487 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053020488 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020489 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
20490 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053020491 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020492 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053020493 {
20494 /* Acquire wakelock to handle the case where APP's tries to
20495 * suspend immediately after updating the scan results. Whis
20496 * results in app's is in suspended state and not able to
20497 * process the connect request to AP
20498 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053020499 hdd_prevent_suspend_timeout(2000,
20500 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020501 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053020502 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020503
20504 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20505 "%s : cfg80211 scan result database updated", __func__);
20506
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020507 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020508 return 0;
20509
20510 }
20511 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
20512 pAdapterNode = pNext;
20513 }
20514
20515 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20516 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020517 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020518 return 0;
20519}
20520
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053020521int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
20522{
20523 int ret;
20524
20525 vos_ssr_protect(__func__);
20526 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
20527 vos_ssr_unprotect(__func__);
20528
20529 return ret;
20530}
20531
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020532/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053020533 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020534 * this is called when cfg80211 driver suspends
20535 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053020536int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020537 struct cfg80211_wowlan *wow)
20538{
20539 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053020540 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020541
20542 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020543
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053020544 ret = wlan_hdd_validate_context(pHddCtx);
20545 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020546 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053020547 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020548 }
20549
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053020550 if (pHddCtx->is_ap_mode_wow_supported) {
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053020551 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20552 "%s: Suspend SoftAP", __func__);
20553 hdd_set_wlan_suspend_mode(true);
20554 }
20555
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053020556
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053020557 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20558 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
20559 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020560 pHddCtx->isWiphySuspended = TRUE;
20561
20562 EXIT();
20563
20564 return 0;
20565}
20566
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053020567int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
20568 struct cfg80211_wowlan *wow)
20569{
20570 int ret;
20571
20572 vos_ssr_protect(__func__);
20573 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
20574 vos_ssr_unprotect(__func__);
20575
20576 return ret;
20577}
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053020578
20579#ifdef FEATURE_OEM_DATA_SUPPORT
20580static void wlan_hdd_cfg80211_oem_data_rsp_ind_new(void *ctx,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053020581 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053020582{
20583 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
20584
20585 ENTER();
20586
20587 if (wlan_hdd_validate_context(pHddCtx)) {
20588 return;
20589 }
20590 if (!pMsg)
20591 {
20592 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
20593 return;
20594 }
20595
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053020596 send_oem_data_rsp_msg(evLen, pMsg);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053020597
20598 EXIT();
20599 return;
20600
20601}
20602
20603void wlan_hdd_cfg80211_oemdata_callback(void *ctx, const tANI_U16 evType,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053020604 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053020605{
20606 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
20607
20608 ENTER();
20609
20610 if (wlan_hdd_validate_context(pHddCtx)) {
20611 return;
20612 }
20613
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053020614 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d) evLen %d"), evType, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053020615
20616 switch(evType) {
20617 case SIR_HAL_START_OEM_DATA_RSP_IND_NEW:
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053020618 wlan_hdd_cfg80211_oem_data_rsp_ind_new(ctx, pMsg, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053020619 break;
20620 default:
20621 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
20622 break;
20623 }
20624 EXIT();
20625}
20626#endif
20627
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053020628#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
20629 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053020630/**
20631 * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api
20632 * @wiphy: Pointer to wiphy
20633 * @wdev: Pointer to wireless device structure
20634 *
20635 * This function is used to abort an ongoing scan
20636 *
20637 * Return: None
20638 */
20639static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
20640 struct wireless_dev *wdev)
20641{
20642 struct net_device *dev = wdev->netdev;
20643 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
20644 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
20645 int ret;
20646
20647 ENTER();
20648
20649 if (NULL == adapter) {
20650 hddLog(VOS_TRACE_LEVEL_FATAL, FL("HDD adapter is NULL"));
20651 return;
20652 }
20653
20654 ret = wlan_hdd_validate_context(hdd_ctx);
20655 if (0 != ret)
20656 return;
20657
20658 wlan_hdd_scan_abort(adapter);
20659
20660 return;
20661}
20662
20663/**
20664 * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api
20665 * @wiphy: Pointer to wiphy
20666 * @wdev: Pointer to wireless device structure
20667 *
20668 * Return: None
20669 */
20670void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
20671 struct wireless_dev *wdev)
20672{
20673 vos_ssr_protect(__func__);
20674 __wlan_hdd_cfg80211_abort_scan(wiphy, wdev);
20675 vos_ssr_unprotect(__func__);
20676
20677 return;
20678}
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053020679#endif
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053020680
Jeff Johnson295189b2012-06-20 16:38:30 -070020681/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053020682static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070020683{
20684 .add_virtual_intf = wlan_hdd_add_virtual_intf,
20685 .del_virtual_intf = wlan_hdd_del_virtual_intf,
20686 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
20687 .change_station = wlan_hdd_change_station,
20688#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
20689 .add_beacon = wlan_hdd_cfg80211_add_beacon,
20690 .del_beacon = wlan_hdd_cfg80211_del_beacon,
20691 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070020692#else
20693 .start_ap = wlan_hdd_cfg80211_start_ap,
20694 .change_beacon = wlan_hdd_cfg80211_change_beacon,
20695 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070020696#endif
20697 .change_bss = wlan_hdd_cfg80211_change_bss,
20698 .add_key = wlan_hdd_cfg80211_add_key,
20699 .get_key = wlan_hdd_cfg80211_get_key,
20700 .del_key = wlan_hdd_cfg80211_del_key,
20701 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080020702#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070020703 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080020704#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070020705 .scan = wlan_hdd_cfg80211_scan,
20706 .connect = wlan_hdd_cfg80211_connect,
20707 .disconnect = wlan_hdd_cfg80211_disconnect,
20708 .join_ibss = wlan_hdd_cfg80211_join_ibss,
20709 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
20710 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
20711 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
20712 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070020713 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
20714 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053020715 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070020716#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
20717 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
20718 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
20719 .set_txq_params = wlan_hdd_set_txq_params,
20720#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070020721 .get_station = wlan_hdd_cfg80211_get_station,
20722 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
20723 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070020724 .add_station = wlan_hdd_cfg80211_add_station,
20725#ifdef FEATURE_WLAN_LFR
20726 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
20727 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
20728 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
20729#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070020730#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
20731 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
20732#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020733#ifdef FEATURE_WLAN_TDLS
20734 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
20735 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
20736#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020737#ifdef WLAN_FEATURE_GTK_OFFLOAD
20738 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
20739#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020740#ifdef FEATURE_WLAN_SCAN_PNO
20741 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
20742 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
20743#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020744 .resume = wlan_hdd_cfg80211_resume_wlan,
20745 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020746 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070020747#ifdef WLAN_NL80211_TESTMODE
20748 .testmode_cmd = wlan_hdd_cfg80211_testmode,
20749#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020750 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053020751#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
20752 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053020753 .abort_scan = wlan_hdd_cfg80211_abort_scan,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053020754#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070020755};
20756