blob: 214d9aa7247808792db2bdad71db20db82b08353 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Abhishek Singhb3e376c2017-01-04 15:27:13 +05302 * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lama7f454d2014-07-24 12:04:06 -070023 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +053026 *
Kiet Lamaa8e15a2014-02-11 23:30:06 -080027 */
Kiet Lam842dad02014-02-18 18:44:02 -080028
29
Kiet Lama7f454d2014-07-24 12:04:06 -070030
31
Jeff Johnson295189b2012-06-20 16:38:30 -070032/**========================================================================
33
34 \file wlan_hdd_cfg80211.c
35
36 \brief WLAN Host Device Driver implementation
37
Jeff Johnson295189b2012-06-20 16:38:30 -070038 ========================================================================*/
39
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070040/**=========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -070041
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070042 EDIT HISTORY FOR FILE
Jeff Johnson295189b2012-06-20 16:38:30 -070043
44
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070045 This section contains comments describing changes made to the module.
46 Notice that changes are listed in reverse chronological order.
Jeff Johnson295189b2012-06-20 16:38:30 -070047
48
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070049 $Header:$ $DateTime: $ $Author: $
Jeff Johnson295189b2012-06-20 16:38:30 -070050
51
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070052 when who what, where, why
Jeff Johnson295189b2012-06-20 16:38:30 -070053 -------- --- --------------------------------------------------------
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070054 21/12/09 Ashwani Created module.
Jeff Johnson295189b2012-06-20 16:38:30 -070055
56 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070057 Ganesh K
Jeff Johnson295189b2012-06-20 16:38:30 -070058 ==========================================================================*/
59
Jeff Johnson295189b2012-06-20 16:38:30 -070060
61#include <linux/version.h>
62#include <linux/module.h>
63#include <linux/kernel.h>
64#include <linux/init.h>
65#include <linux/wireless.h>
66#include <wlan_hdd_includes.h>
67#include <net/arp.h>
68#include <net/cfg80211.h>
69#include <linux/wireless.h>
70#include <wlan_hdd_wowl.h>
71#include <aniGlobal.h>
72#include "ccmApi.h"
73#include "sirParams.h"
74#include "dot11f.h"
75#include "wlan_hdd_assoc.h"
76#include "wlan_hdd_wext.h"
77#include "sme_Api.h"
78#include "wlan_hdd_p2p.h"
79#include "wlan_hdd_cfg80211.h"
80#include "wlan_hdd_hostapd.h"
81#include "sapInternal.h"
82#include "wlan_hdd_softap_tx_rx.h"
83#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053084#include "wlan_hdd_assoc.h"
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053085#include "wlan_hdd_power.h"
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053086#include "wlan_hdd_trace.h"
87#include "vos_types.h"
88#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070089#ifdef WLAN_BTAMP_FEATURE
90#include "bap_hdd_misc.h"
91#endif
92#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080093#include "wlan_hdd_tdls.h"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053094#include "wlan_hdd_wmm.h"
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053095#include "wlan_qct_wda.h"
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053096#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070097#include "wlan_hdd_dev_pwr.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +053098#include "qwlan_version.h"
c_manjeecfd1efb2015-09-25 19:32:34 +053099#include "wlan_logging_sock_svc.h"
Agrawal Ashishcfe83282016-09-29 13:03:45 +0530100#include "wlan_hdd_misc.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +0530101
Jeff Johnson295189b2012-06-20 16:38:30 -0700102
103#define g_mode_rates_size (12)
104#define a_mode_rates_size (8)
105#define FREQ_BASE_80211G (2407)
106#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700107#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530108#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700109#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800110 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700111
112#define HDD2GHZCHAN(freq, chan, flag) { \
113 .band = IEEE80211_BAND_2GHZ, \
114 .center_freq = (freq), \
115 .hw_value = (chan),\
116 .flags = (flag), \
117 .max_antenna_gain = 0 ,\
118 .max_power = 30, \
119}
120
121#define HDD5GHZCHAN(freq, chan, flag) { \
122 .band = IEEE80211_BAND_5GHZ, \
123 .center_freq = (freq), \
124 .hw_value = (chan),\
125 .flags = (flag), \
126 .max_antenna_gain = 0 ,\
127 .max_power = 30, \
128}
129
130#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
131{\
132 .bitrate = rate, \
133 .hw_value = rate_id, \
134 .flags = flag, \
135}
136
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530137#ifdef WLAN_FEATURE_VOWIFI_11R
138#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
139#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
140#endif
141
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530142#define HDD_CHANNEL_14 14
Dasari Srinivase18b2cf2014-10-28 17:09:42 +0530143#define WLAN_HDD_MAX_FEATURE_SET 8
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530144
Sunil Duttc69bccb2014-05-26 21:30:20 +0530145#ifdef WLAN_FEATURE_LINK_LAYER_STATS
146/*
147 * Used to allocate the size of 4096 for the link layer stats.
148 * The size of 4096 is considered assuming that all data per
149 * respective event fit with in the limit.Please take a call
150 * on the limit based on the data requirements on link layer
151 * statistics.
152 */
153#define LL_STATS_EVENT_BUF_SIZE 4096
154#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +0530155#ifdef WLAN_FEATURE_EXTSCAN
156/*
157 * Used to allocate the size of 4096 for the EXTScan NL data.
158 * The size of 4096 is considered assuming that all data per
159 * respective event fit with in the limit.Please take a call
160 * on the limit based on the data requirements.
161 */
162
163#define EXTSCAN_EVENT_BUF_SIZE 4096
164#define EXTSCAN_MAX_CACHED_RESULTS_PER_IND 32
165#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +0530166
Atul Mittal115287b2014-07-08 13:26:33 +0530167/*EXT TDLS*/
168/*
169 * Used to allocate the size of 4096 for the TDLS.
170 * The size of 4096 is considered assuming that all data per
171 * respective event fit with in the limit.Please take a call
172 * on the limit based on the data requirements on link layer
173 * statistics.
174 */
175#define EXTTDLS_EVENT_BUF_SIZE 4096
176
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +0530177/*
178 * Values for Mac spoofing feature
179 *
180 */
181#define MAC_ADDR_SPOOFING_FW_HOST_DISABLE 0
182#define MAC_ADDR_SPOOFING_FW_HOST_ENABLE 1
183#define MAC_ADDR_SPOOFING_FW_ENABLE_HOST_DISABLE 2
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +0530184#define MAC_ADDR_SPOOFING_DEFER_INTERVAL 10 //in ms
185
Anurag Chouhan343af7e2016-12-16 13:11:19 +0530186/*
187 * max_sched_scan_plans defined to 10
188 */
189#define MAX_SCHED_SCAN_PLANS 10
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +0530190
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530191static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700192{
193 WLAN_CIPHER_SUITE_WEP40,
194 WLAN_CIPHER_SUITE_WEP104,
195 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800196#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700197#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
198 WLAN_CIPHER_SUITE_KRK,
199 WLAN_CIPHER_SUITE_CCMP,
200#else
201 WLAN_CIPHER_SUITE_CCMP,
202#endif
203#ifdef FEATURE_WLAN_WAPI
204 WLAN_CIPHER_SUITE_SMS4,
205#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700206#ifdef WLAN_FEATURE_11W
207 WLAN_CIPHER_SUITE_AES_CMAC,
208#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700209};
210
211static inline int is_broadcast_ether_addr(const u8 *addr)
212{
213 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
214 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
215}
216
Agrawal Ashish97dec502015-11-26 20:20:58 +0530217const static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530218{
Jeff Johnson295189b2012-06-20 16:38:30 -0700219 HDD2GHZCHAN(2412, 1, 0) ,
220 HDD2GHZCHAN(2417, 2, 0) ,
221 HDD2GHZCHAN(2422, 3, 0) ,
222 HDD2GHZCHAN(2427, 4, 0) ,
223 HDD2GHZCHAN(2432, 5, 0) ,
224 HDD2GHZCHAN(2437, 6, 0) ,
225 HDD2GHZCHAN(2442, 7, 0) ,
226 HDD2GHZCHAN(2447, 8, 0) ,
227 HDD2GHZCHAN(2452, 9, 0) ,
228 HDD2GHZCHAN(2457, 10, 0) ,
229 HDD2GHZCHAN(2462, 11, 0) ,
230 HDD2GHZCHAN(2467, 12, 0) ,
231 HDD2GHZCHAN(2472, 13, 0) ,
232 HDD2GHZCHAN(2484, 14, 0) ,
233};
234
Agrawal Ashish97dec502015-11-26 20:20:58 +0530235const static struct ieee80211_channel hdd_channels_5_GHZ[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700236{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700237 HDD5GHZCHAN(4920, 240, 0) ,
238 HDD5GHZCHAN(4940, 244, 0) ,
239 HDD5GHZCHAN(4960, 248, 0) ,
240 HDD5GHZCHAN(4980, 252, 0) ,
241 HDD5GHZCHAN(5040, 208, 0) ,
242 HDD5GHZCHAN(5060, 212, 0) ,
243 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700244 HDD5GHZCHAN(5180, 36, 0) ,
245 HDD5GHZCHAN(5200, 40, 0) ,
246 HDD5GHZCHAN(5220, 44, 0) ,
247 HDD5GHZCHAN(5240, 48, 0) ,
248 HDD5GHZCHAN(5260, 52, 0) ,
249 HDD5GHZCHAN(5280, 56, 0) ,
250 HDD5GHZCHAN(5300, 60, 0) ,
251 HDD5GHZCHAN(5320, 64, 0) ,
252 HDD5GHZCHAN(5500,100, 0) ,
253 HDD5GHZCHAN(5520,104, 0) ,
254 HDD5GHZCHAN(5540,108, 0) ,
255 HDD5GHZCHAN(5560,112, 0) ,
256 HDD5GHZCHAN(5580,116, 0) ,
257 HDD5GHZCHAN(5600,120, 0) ,
258 HDD5GHZCHAN(5620,124, 0) ,
259 HDD5GHZCHAN(5640,128, 0) ,
260 HDD5GHZCHAN(5660,132, 0) ,
261 HDD5GHZCHAN(5680,136, 0) ,
262 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800263#ifdef FEATURE_WLAN_CH144
264 HDD5GHZCHAN(5720,144, 0) ,
265#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700266 HDD5GHZCHAN(5745,149, 0) ,
267 HDD5GHZCHAN(5765,153, 0) ,
268 HDD5GHZCHAN(5785,157, 0) ,
269 HDD5GHZCHAN(5805,161, 0) ,
270 HDD5GHZCHAN(5825,165, 0) ,
271};
272
273static struct ieee80211_rate g_mode_rates[] =
274{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530275 HDD_G_MODE_RATETAB(10, 0x1, 0),
276 HDD_G_MODE_RATETAB(20, 0x2, 0),
277 HDD_G_MODE_RATETAB(55, 0x4, 0),
278 HDD_G_MODE_RATETAB(110, 0x8, 0),
279 HDD_G_MODE_RATETAB(60, 0x10, 0),
280 HDD_G_MODE_RATETAB(90, 0x20, 0),
281 HDD_G_MODE_RATETAB(120, 0x40, 0),
282 HDD_G_MODE_RATETAB(180, 0x80, 0),
283 HDD_G_MODE_RATETAB(240, 0x100, 0),
284 HDD_G_MODE_RATETAB(360, 0x200, 0),
285 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700286 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530287};
Jeff Johnson295189b2012-06-20 16:38:30 -0700288
289static struct ieee80211_rate a_mode_rates[] =
290{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530291 HDD_G_MODE_RATETAB(60, 0x10, 0),
292 HDD_G_MODE_RATETAB(90, 0x20, 0),
293 HDD_G_MODE_RATETAB(120, 0x40, 0),
294 HDD_G_MODE_RATETAB(180, 0x80, 0),
295 HDD_G_MODE_RATETAB(240, 0x100, 0),
296 HDD_G_MODE_RATETAB(360, 0x200, 0),
297 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700298 HDD_G_MODE_RATETAB(540, 0x800, 0),
299};
300
301static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
302{
Agrawal Ashish97dec502015-11-26 20:20:58 +0530303 .channels = NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700304 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
305 .band = IEEE80211_BAND_2GHZ,
306 .bitrates = g_mode_rates,
307 .n_bitrates = g_mode_rates_size,
308 .ht_cap.ht_supported = 1,
309 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
310 | IEEE80211_HT_CAP_GRN_FLD
311 | IEEE80211_HT_CAP_DSSSCCK40
312 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
313 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
314 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
315 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
316 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
317 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
318};
319
Jeff Johnson295189b2012-06-20 16:38:30 -0700320static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
321{
Agrawal Ashish97dec502015-11-26 20:20:58 +0530322 .channels = NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700323 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
324 .band = IEEE80211_BAND_5GHZ,
325 .bitrates = a_mode_rates,
326 .n_bitrates = a_mode_rates_size,
327 .ht_cap.ht_supported = 1,
328 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
329 | IEEE80211_HT_CAP_GRN_FLD
330 | IEEE80211_HT_CAP_DSSSCCK40
331 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
332 | IEEE80211_HT_CAP_SGI_40
333 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
334 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
335 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
336 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
337 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
338 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
339};
340
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530341/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700342 TX/RX direction for each kind of interface */
343static const struct ieee80211_txrx_stypes
344wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
345 [NL80211_IFTYPE_STATION] = {
346 .tx = 0xffff,
347 .rx = BIT(SIR_MAC_MGMT_ACTION) |
348 BIT(SIR_MAC_MGMT_PROBE_REQ),
349 },
350 [NL80211_IFTYPE_AP] = {
351 .tx = 0xffff,
352 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
353 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
354 BIT(SIR_MAC_MGMT_PROBE_REQ) |
355 BIT(SIR_MAC_MGMT_DISASSOC) |
356 BIT(SIR_MAC_MGMT_AUTH) |
357 BIT(SIR_MAC_MGMT_DEAUTH) |
358 BIT(SIR_MAC_MGMT_ACTION),
359 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700360 [NL80211_IFTYPE_ADHOC] = {
361 .tx = 0xffff,
362 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
363 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
364 BIT(SIR_MAC_MGMT_PROBE_REQ) |
365 BIT(SIR_MAC_MGMT_DISASSOC) |
366 BIT(SIR_MAC_MGMT_AUTH) |
367 BIT(SIR_MAC_MGMT_DEAUTH) |
368 BIT(SIR_MAC_MGMT_ACTION),
369 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700370 [NL80211_IFTYPE_P2P_CLIENT] = {
371 .tx = 0xffff,
372 .rx = BIT(SIR_MAC_MGMT_ACTION) |
373 BIT(SIR_MAC_MGMT_PROBE_REQ),
374 },
375 [NL80211_IFTYPE_P2P_GO] = {
376 /* This is also same as for SoftAP */
377 .tx = 0xffff,
378 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
379 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
380 BIT(SIR_MAC_MGMT_PROBE_REQ) |
381 BIT(SIR_MAC_MGMT_DISASSOC) |
382 BIT(SIR_MAC_MGMT_AUTH) |
383 BIT(SIR_MAC_MGMT_DEAUTH) |
384 BIT(SIR_MAC_MGMT_ACTION),
385 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700386};
387
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800388#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800389static const struct ieee80211_iface_limit
390wlan_hdd_iface_limit[] = {
391 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800392 /* max = 3 ; Our driver create two interfaces during driver init
393 * wlan0 and p2p0 interfaces. p2p0 is considered as station
394 * interface until a group is formed. In JB architecture, once the
395 * group is formed, interface type of p2p0 is changed to P2P GO or
396 * Client.
397 * When supplicant remove the group, it first issue a set interface
398 * cmd to change the mode back to Station. In JB this works fine as
399 * we advertize two station type interface during driver init.
400 * Some vendors create separate interface for P2P GO/Client,
401 * after group formation(Third one). But while group remove
402 * supplicant first tries to change the mode(3rd interface) to STATION
403 * But as we advertized only two sta type interfaces nl80211 was
404 * returning error for the third one which was leading to failure in
405 * delete interface. Ideally while removing the group, supplicant
406 * should not try to change the 3rd interface mode to Station type.
407 * Till we get a fix in wpa_supplicant, we advertize max STA
408 * interface type to 3
409 */
410 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800411 .types = BIT(NL80211_IFTYPE_STATION),
412 },
413 {
414 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700415 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800416 },
417 {
418 .max = 1,
419 .types = BIT(NL80211_IFTYPE_P2P_GO) |
420 BIT(NL80211_IFTYPE_P2P_CLIENT),
421 },
422};
423
424/* By default, only single channel concurrency is allowed */
425static struct ieee80211_iface_combination
426wlan_hdd_iface_combination = {
427 .limits = wlan_hdd_iface_limit,
428 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800429 /*
430 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
431 * and p2p0 interfaces during driver init
432 * Some vendors create separate interface for P2P operations.
433 * wlan0: STA interface
434 * p2p0: P2P Device interface, action frames goes
435 * through this interface.
436 * p2p-xx: P2P interface, After GO negotiation this interface is
437 * created for p2p operations(GO/CLIENT interface).
438 */
439 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800440 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
441 .beacon_int_infra_match = false,
442};
443#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800444
Jeff Johnson295189b2012-06-20 16:38:30 -0700445static struct cfg80211_ops wlan_hdd_cfg80211_ops;
446
447/* Data rate 100KBPS based on IE Index */
448struct index_data_rate_type
449{
450 v_U8_t beacon_rate_index;
451 v_U16_t supported_rate[4];
452};
453
454/* 11B, 11G Rate table include Basic rate and Extended rate
455 The IDX field is the rate index
456 The HI field is the rate when RSSI is strong or being ignored
457 (in this case we report actual rate)
458 The MID field is the rate when RSSI is moderate
459 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
460 The LO field is the rate when RSSI is low
461 (in this case we don't report rates, actual current rate used)
462 */
463static const struct
464{
465 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700466 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700467} supported_data_rate[] =
468{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700469/* IDX HI HM LM LO (RSSI-based index */
470 {2, { 10, 10, 10, 0}},
471 {4, { 20, 20, 10, 0}},
472 {11, { 55, 20, 10, 0}},
473 {12, { 60, 55, 20, 0}},
474 {18, { 90, 55, 20, 0}},
475 {22, {110, 55, 20, 0}},
476 {24, {120, 90, 60, 0}},
477 {36, {180, 120, 60, 0}},
478 {44, {220, 180, 60, 0}},
479 {48, {240, 180, 90, 0}},
480 {66, {330, 180, 90, 0}},
481 {72, {360, 240, 90, 0}},
482 {96, {480, 240, 120, 0}},
483 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700484};
485
486/* MCS Based rate table */
487static struct index_data_rate_type supported_mcs_rate[] =
488{
489/* MCS L20 L40 S20 S40 */
490 {0, {65, 135, 72, 150}},
491 {1, {130, 270, 144, 300}},
492 {2, {195, 405, 217, 450}},
493 {3, {260, 540, 289, 600}},
494 {4, {390, 810, 433, 900}},
495 {5, {520, 1080, 578, 1200}},
496 {6, {585, 1215, 650, 1350}},
497 {7, {650, 1350, 722, 1500}}
498};
499
Leo Chang6f8870f2013-03-26 18:11:36 -0700500#ifdef WLAN_FEATURE_11AC
501
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530502#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700503
504struct index_vht_data_rate_type
505{
506 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530507 v_U16_t supported_VHT80_rate[2];
508 v_U16_t supported_VHT40_rate[2];
509 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700510};
511
512typedef enum
513{
514 DATA_RATE_11AC_MAX_MCS_7,
515 DATA_RATE_11AC_MAX_MCS_8,
516 DATA_RATE_11AC_MAX_MCS_9,
517 DATA_RATE_11AC_MAX_MCS_NA
518} eDataRate11ACMaxMcs;
519
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530520/* SSID broadcast type */
521typedef enum eSSIDBcastType
522{
523 eBCAST_UNKNOWN = 0,
524 eBCAST_NORMAL = 1,
525 eBCAST_HIDDEN = 2,
526} tSSIDBcastType;
527
Leo Chang6f8870f2013-03-26 18:11:36 -0700528/* MCS Based VHT rate table */
529static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
530{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530531/* MCS L80 S80 L40 S40 L20 S40*/
532 {0, {293, 325}, {135, 150}, {65, 72}},
533 {1, {585, 650}, {270, 300}, {130, 144}},
534 {2, {878, 975}, {405, 450}, {195, 217}},
535 {3, {1170, 1300}, {540, 600}, {260, 289}},
536 {4, {1755, 1950}, {810, 900}, {390, 433}},
537 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
538 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
539 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
540 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
541 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700542};
543#endif /* WLAN_FEATURE_11AC */
544
c_hpothu79aab322014-07-14 21:11:01 +0530545/*array index points to MCS and array value points respective rssi*/
546static int rssiMcsTbl[][10] =
547{
548/*MCS 0 1 2 3 4 5 6 7 8 9*/
549 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
550 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
551 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
552};
553
Jeff Johnson295189b2012-06-20 16:38:30 -0700554extern struct net_device_ops net_ops_struct;
Dasari Srinivas7875a302014-09-26 17:50:57 +0530555#ifdef FEATURE_WLAN_SCAN_PNO
556static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
557#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700558
Leo Chang9056f462013-08-01 19:21:11 -0700559#ifdef WLAN_NL80211_TESTMODE
560enum wlan_hdd_tm_attr
561{
562 WLAN_HDD_TM_ATTR_INVALID = 0,
563 WLAN_HDD_TM_ATTR_CMD = 1,
564 WLAN_HDD_TM_ATTR_DATA = 2,
565 WLAN_HDD_TM_ATTR_TYPE = 3,
566 /* keep last */
567 WLAN_HDD_TM_ATTR_AFTER_LAST,
568 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
569};
570
571enum wlan_hdd_tm_cmd
572{
573 WLAN_HDD_TM_CMD_WLAN_HB = 1,
574};
575
576#define WLAN_HDD_TM_DATA_MAX_LEN 5000
577
578static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
579{
580 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
581 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
582 .len = WLAN_HDD_TM_DATA_MAX_LEN },
583};
584#endif /* WLAN_NL80211_TESTMODE */
585
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800586#ifdef FEATURE_WLAN_CH_AVOID
587/*
588 * FUNCTION: wlan_hdd_send_avoid_freq_event
589 * This is called when wlan driver needs to send vendor specific
590 * avoid frequency range event to userspace
591 */
592int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
593 tHddAvoidFreqList *pAvoidFreqList)
594{
595 struct sk_buff *vendor_event;
596
597 ENTER();
598
599 if (!pHddCtx)
600 {
601 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
602 "%s: HDD context is null", __func__);
603 return -1;
604 }
605
606 if (!pAvoidFreqList)
607 {
608 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
609 "%s: pAvoidFreqList is null", __func__);
610 return -1;
611 }
612
613 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530614#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
615 NULL,
616#endif
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800617 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530618 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800619 GFP_KERNEL);
620 if (!vendor_event)
621 {
622 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
623 "%s: cfg80211_vendor_event_alloc failed", __func__);
624 return -1;
625 }
626
627 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
628 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
629
630 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
631
632 EXIT();
633 return 0;
634}
635#endif /* FEATURE_WLAN_CH_AVOID */
636
Srinivas Dasari030bad32015-02-18 23:23:54 +0530637/*
638 * FUNCTION: __wlan_hdd_cfg80211_nan_request
639 * This is called when wlan driver needs to send vendor specific
640 * nan request event.
641 */
642static int __wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
643 struct wireless_dev *wdev,
644 const void *data, int data_len)
645{
646 tNanRequestReq nan_req;
647 VOS_STATUS status;
648 int ret_val = -1;
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530649 struct net_device *dev = wdev->netdev;
650 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
651 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530652 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
653
654 if (0 == data_len)
655 {
656 hddLog(VOS_TRACE_LEVEL_ERROR,
657 FL("NAN - Invalid Request, length = 0"));
658 return ret_val;
659 }
660
661 if (NULL == data)
662 {
663 hddLog(VOS_TRACE_LEVEL_ERROR,
664 FL("NAN - Invalid Request, data is NULL"));
665 return ret_val;
666 }
667
668 status = wlan_hdd_validate_context(pHddCtx);
669 if (0 != status)
670 {
671 hddLog(VOS_TRACE_LEVEL_ERROR,
672 FL("HDD context is not valid"));
673 return -EINVAL;
674 }
675
676 hddLog(LOG1, FL("Received NAN command"));
677 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
678 (tANI_U8 *)data, data_len);
679
680 /* check the NAN Capability */
681 if (TRUE != sme_IsFeatureSupportedByFW(NAN))
682 {
683 hddLog(VOS_TRACE_LEVEL_ERROR,
684 FL("NAN is not supported by Firmware"));
685 return -EINVAL;
686 }
687
688 nan_req.request_data_len = data_len;
689 nan_req.request_data = data;
690
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530691 status = sme_NanRequest(hHal, &nan_req, pAdapter->sessionId);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530692 if (VOS_STATUS_SUCCESS == status)
693 {
694 ret_val = 0;
695 }
696 return ret_val;
697}
698
699/*
700 * FUNCTION: wlan_hdd_cfg80211_nan_request
701 * Wrapper to protect the nan vendor command from ssr
702 */
703static int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
704 struct wireless_dev *wdev,
705 const void *data, int data_len)
706{
707 int ret;
708
709 vos_ssr_protect(__func__);
710 ret = __wlan_hdd_cfg80211_nan_request(wiphy, wdev, data, data_len);
711 vos_ssr_unprotect(__func__);
712
713 return ret;
714}
715
716/*
717 * FUNCTION: wlan_hdd_cfg80211_nan_callback
718 * This is a callback function and it gets called
719 * when we need to report nan response event to
720 * upper layers.
721 */
722static void wlan_hdd_cfg80211_nan_callback(void* ctx, tSirNanEvent* msg)
723{
724 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
725 struct sk_buff *vendor_event;
726 int status;
727 tSirNanEvent *data;
728
729 ENTER();
730 if (NULL == msg)
731 {
732 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
733 FL(" msg received here is null"));
734 return;
735 }
736 data = msg;
737
738 status = wlan_hdd_validate_context(pHddCtx);
739
740 if (0 != status)
741 {
742 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
743 FL("HDD context is not valid"));
744 return;
745 }
746
747 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530748#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
749 NULL,
750#endif
Srinivas Dasari030bad32015-02-18 23:23:54 +0530751 data->event_data_len +
752 NLMSG_HDRLEN,
753 QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX,
754 GFP_KERNEL);
755
756 if (!vendor_event)
757 {
758 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
759 FL("cfg80211_vendor_event_alloc failed"));
760 return;
761 }
762 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN,
763 data->event_data_len, data->event_data))
764 {
765 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
766 FL("QCA_WLAN_VENDOR_ATTR_NAN put fail"));
767 kfree_skb(vendor_event);
768 return;
769 }
770 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
771 EXIT();
772}
773
774/*
775 * FUNCTION: wlan_hdd_cfg80211_nan_init
776 * This function is called to register the callback to sme layer
777 */
778inline void wlan_hdd_cfg80211_nan_init(hdd_context_t *pHddCtx)
779{
780 sme_NanRegisterCallback(pHddCtx->hHal, wlan_hdd_cfg80211_nan_callback);
781}
782
783
Sunil Duttc69bccb2014-05-26 21:30:20 +0530784#ifdef WLAN_FEATURE_LINK_LAYER_STATS
785
786static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
787 struct sk_buff *vendor_event)
788{
789 if (nla_put_u8(vendor_event,
790 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
791 stats->rate.preamble) ||
792 nla_put_u8(vendor_event,
793 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
794 stats->rate.nss) ||
795 nla_put_u8(vendor_event,
796 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
797 stats->rate.bw) ||
798 nla_put_u8(vendor_event,
799 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
800 stats->rate.rateMcsIdx) ||
801 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
802 stats->rate.bitrate ) ||
803 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
804 stats->txMpdu ) ||
805 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
806 stats->rxMpdu ) ||
807 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
808 stats->mpduLost ) ||
809 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
810 stats->retries) ||
811 nla_put_u32(vendor_event,
812 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
813 stats->retriesShort ) ||
814 nla_put_u32(vendor_event,
815 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
816 stats->retriesLong))
817 {
818 hddLog(VOS_TRACE_LEVEL_ERROR,
819 FL("QCA_WLAN_VENDOR_ATTR put fail"));
820 return FALSE;
821 }
822 return TRUE;
823}
824
825static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
826 struct sk_buff *vendor_event)
827{
828 u32 i = 0;
829 struct nlattr *rateInfo;
830 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
831 stats->type) ||
832 nla_put(vendor_event,
833 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
834 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
835 nla_put_u32(vendor_event,
836 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
837 stats->capabilities) ||
838 nla_put_u32(vendor_event,
839 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
840 stats->numRate))
841 {
842 hddLog(VOS_TRACE_LEVEL_ERROR,
843 FL("QCA_WLAN_VENDOR_ATTR put fail"));
844 goto error;
845 }
846
847 rateInfo = nla_nest_start(vendor_event,
848 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530849 if(!rateInfo)
850 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530851 for (i = 0; i < stats->numRate; i++)
852 {
853 struct nlattr *rates;
854 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
855 stats->rateStats +
856 (i * sizeof(tSirWifiRateStat)));
857 rates = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530858 if(!rates)
859 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530860
861 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
862 {
863 hddLog(VOS_TRACE_LEVEL_ERROR,
864 FL("QCA_WLAN_VENDOR_ATTR put fail"));
865 return FALSE;
866 }
867 nla_nest_end(vendor_event, rates);
868 }
869 nla_nest_end(vendor_event, rateInfo);
870
871 return TRUE;
872error:
873 return FALSE;
874}
875
876static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
877 struct sk_buff *vendor_event)
878{
879 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
880 stats->ac ) ||
881 nla_put_u32(vendor_event,
882 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
883 stats->txMpdu ) ||
884 nla_put_u32(vendor_event,
885 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
886 stats->rxMpdu ) ||
887 nla_put_u32(vendor_event,
888 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
889 stats->txMcast ) ||
890 nla_put_u32(vendor_event,
891 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
892 stats->rxMcast ) ||
893 nla_put_u32(vendor_event,
894 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
895 stats->rxAmpdu ) ||
896 nla_put_u32(vendor_event,
897 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
898 stats->txAmpdu ) ||
899 nla_put_u32(vendor_event,
900 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
901 stats->mpduLost )||
902 nla_put_u32(vendor_event,
903 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
904 stats->retries ) ||
905 nla_put_u32(vendor_event,
906 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
907 stats->retriesShort ) ||
908 nla_put_u32(vendor_event,
909 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
910 stats->retriesLong ) ||
911 nla_put_u32(vendor_event,
912 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
913 stats->contentionTimeMin ) ||
914 nla_put_u32(vendor_event,
915 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
916 stats->contentionTimeMax ) ||
917 nla_put_u32(vendor_event,
918 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
919 stats->contentionTimeAvg ) ||
920 nla_put_u32(vendor_event,
921 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
922 stats->contentionNumSamples ))
923 {
924 hddLog(VOS_TRACE_LEVEL_ERROR,
925 FL("QCA_WLAN_VENDOR_ATTR put fail") );
926 return FALSE;
927 }
928 return TRUE;
929}
930
931static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
932 struct sk_buff *vendor_event)
933{
Dino Myclec8f3f332014-07-21 16:48:27 +0530934 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530935 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
936 nla_put(vendor_event,
937 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
938 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
939 nla_put_u32(vendor_event,
940 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
941 stats->state ) ||
942 nla_put_u32(vendor_event,
943 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
944 stats->roaming ) ||
945 nla_put_u32(vendor_event,
946 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
947 stats->capabilities ) ||
948 nla_put(vendor_event,
949 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
950 strlen(stats->ssid), stats->ssid) ||
951 nla_put(vendor_event,
952 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
953 WNI_CFG_BSSID_LEN, stats->bssid) ||
954 nla_put(vendor_event,
955 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
956 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
957 nla_put(vendor_event,
958 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
959 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
960 )
961 {
962 hddLog(VOS_TRACE_LEVEL_ERROR,
963 FL("QCA_WLAN_VENDOR_ATTR put fail") );
964 return FALSE;
965 }
966 return TRUE;
967}
968
Dino Mycle3b9536d2014-07-09 22:05:24 +0530969static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
970 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530971 struct sk_buff *vendor_event)
972{
973 int i = 0;
974 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530975 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
976 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +0530977 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530978
Sunil Duttc69bccb2014-05-26 21:30:20 +0530979 if (FALSE == put_wifi_interface_info(
980 &pWifiIfaceStat->info,
981 vendor_event))
982 {
983 hddLog(VOS_TRACE_LEVEL_ERROR,
984 FL("QCA_WLAN_VENDOR_ATTR put fail") );
985 return FALSE;
986
987 }
Dino Mycle3b9536d2014-07-09 22:05:24 +0530988 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
989 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
990 if (NULL == pWifiIfaceStatTL)
991 {
992 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
993 return FALSE;
994 }
995
Srinivas Dasaria8a304f2014-11-15 16:13:37 +0530996 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
997 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
998 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
999 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
1000
1001 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
1002 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
1003 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
1004 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301005
1006 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
1007 {
1008 if (VOS_STATUS_SUCCESS ==
1009 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1010 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
1011 {
1012 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
1013 * obtained from TL structure
1014 */
1015
1016 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
1017 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301018 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
1019
Srinivas Dasari98947432014-11-07 19:41:24 +05301020 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
1021 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
1022 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
1023 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
1024 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
1025 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
1026 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
1027 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301028
Srinivas Dasari98947432014-11-07 19:41:24 +05301029 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
1030 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
1031 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
1032 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
1033 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
1034 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
1035 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
1036 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301037
Srinivas Dasari98947432014-11-07 19:41:24 +05301038 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
1039 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
1040 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
1041 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
1042 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
1043 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
1044 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
1045 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301046 }
1047 else
1048 {
1049 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
1050 }
1051
Dino Mycle3b9536d2014-07-09 22:05:24 +05301052 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
1053 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
1054 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
1055 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
1056 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
1057 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
1058 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
1059 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
1060 }
1061 else
1062 {
1063 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
1064 }
1065
1066
Sunil Duttc69bccb2014-05-26 21:30:20 +05301067
1068 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301069 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1070 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_IFACE) ||
1071 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301072 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
1073 pWifiIfaceStat->beaconRx) ||
1074 nla_put_u32(vendor_event,
1075 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
1076 pWifiIfaceStat->mgmtRx) ||
1077 nla_put_u32(vendor_event,
1078 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
1079 pWifiIfaceStat->mgmtActionRx) ||
1080 nla_put_u32(vendor_event,
1081 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
1082 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301083 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301084 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
1085 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301086 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301087 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
1088 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301089 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301090 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
1091 pWifiIfaceStat->rssiAck))
1092 {
1093 hddLog(VOS_TRACE_LEVEL_ERROR,
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05301094 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1095 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301096 return FALSE;
1097 }
1098
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05301099#ifdef FEATURE_EXT_LL_STAT
1100 /*
1101 * Ensure when EXT_LL_STAT is supported by both host and fwr,
1102 * then host should send Leaky AP stats to upper layer,
1103 * otherwise no need to send these stats.
1104 */
1105 if(sme_IsFeatureSupportedByFW(EXT_LL_STAT) &&
1106 sme_IsFeatureSupportedByDriver(EXT_LL_STAT)
1107 )
1108 {
1109 hddLog(VOS_TRACE_LEVEL_INFO,
1110 FL("EXT_LL_STAT is supported by fwr and host %u %u %u %llu"),
1111 pWifiIfaceStat->leakyApStat.is_leaky_ap,
1112 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked,
1113 pWifiIfaceStat->leakyApStat.rx_leak_window,
1114 pWifiIfaceStat->leakyApStat.avg_bcn_spread);
1115 if (nla_put_u32(vendor_event,
1116 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_DETECTED,
1117 pWifiIfaceStat->leakyApStat.is_leaky_ap) ||
1118 nla_put_u32(vendor_event,
1119 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_AVG_NUM_FRAMES_LEAKED,
1120 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked) ||
1121 nla_put_u32(vendor_event,
1122 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_GUARD_TIME,
1123 pWifiIfaceStat->leakyApStat.rx_leak_window) ||
1124 nla_put_u64(vendor_event,
1125 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_AVERAGE_TSF_OFFSET,
1126 pWifiIfaceStat->leakyApStat.avg_bcn_spread))
1127 {
1128 hddLog(VOS_TRACE_LEVEL_ERROR,
1129 FL("EXT_LL_STAT put fail"));
1130 vos_mem_free(pWifiIfaceStatTL);
1131 return FALSE;
1132 }
1133 }
1134#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +05301135 wmmInfo = nla_nest_start(vendor_event,
1136 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301137 if(!wmmInfo)
1138 {
1139 vos_mem_free(pWifiIfaceStatTL);
1140 return FALSE;
1141 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301142 for (i = 0; i < WIFI_AC_MAX; i++)
1143 {
1144 struct nlattr *wmmStats;
1145 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301146 if(!wmmStats)
1147 {
1148 vos_mem_free(pWifiIfaceStatTL);
1149 return FALSE;
1150 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301151 if (FALSE == put_wifi_wmm_ac_stat(
1152 &pWifiIfaceStat->AccessclassStats[i],
1153 vendor_event))
1154 {
1155 hddLog(VOS_TRACE_LEVEL_ERROR,
1156 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05301157 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301158 return FALSE;
1159 }
1160
1161 nla_nest_end(vendor_event, wmmStats);
1162 }
1163 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +05301164 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301165 return TRUE;
1166}
1167
1168static tSirWifiInterfaceMode
1169 hdd_map_device_to_ll_iface_mode ( int deviceMode )
1170{
1171 switch (deviceMode)
1172 {
1173 case WLAN_HDD_INFRA_STATION:
1174 return WIFI_INTERFACE_STA;
1175 case WLAN_HDD_SOFTAP:
1176 return WIFI_INTERFACE_SOFTAP;
1177 case WLAN_HDD_P2P_CLIENT:
1178 return WIFI_INTERFACE_P2P_CLIENT;
1179 case WLAN_HDD_P2P_GO:
1180 return WIFI_INTERFACE_P2P_GO;
1181 case WLAN_HDD_IBSS:
1182 return WIFI_INTERFACE_IBSS;
1183 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05301184 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301185 }
1186}
1187
1188static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
1189 tpSirWifiInterfaceInfo pInfo)
1190{
1191 v_U8_t *staMac = NULL;
1192 hdd_station_ctx_t *pHddStaCtx;
1193 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1194 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
1195
1196 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
1197
1198 vos_mem_copy(pInfo->macAddr,
1199 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1200
1201 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1202 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
1203 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
1204 {
1205 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1206 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
1207 {
1208 pInfo->state = WIFI_DISCONNECTED;
1209 }
1210 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
1211 {
1212 hddLog(VOS_TRACE_LEVEL_ERROR,
1213 "%s: Session ID %d, Connection is in progress", __func__,
1214 pAdapter->sessionId);
1215 pInfo->state = WIFI_ASSOCIATING;
1216 }
1217 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1218 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
1219 {
1220 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
1221 hddLog(VOS_TRACE_LEVEL_ERROR,
1222 "%s: client " MAC_ADDRESS_STR
1223 " is in the middle of WPS/EAPOL exchange.", __func__,
1224 MAC_ADDR_ARRAY(staMac));
1225 pInfo->state = WIFI_AUTHENTICATING;
1226 }
1227 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
1228 {
1229 pInfo->state = WIFI_ASSOCIATED;
1230 vos_mem_copy(pInfo->bssid,
1231 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
1232 vos_mem_copy(pInfo->ssid,
1233 pHddStaCtx->conn_info.SSID.SSID.ssId,
1234 pHddStaCtx->conn_info.SSID.SSID.length);
1235 //NULL Terminate the string.
1236 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
1237 }
1238 }
1239 vos_mem_copy(pInfo->countryStr,
1240 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1241
1242 vos_mem_copy(pInfo->apCountryStr,
1243 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1244
1245 return TRUE;
1246}
1247
1248/*
1249 * hdd_link_layer_process_peer_stats () - This function is called after
1250 * receiving Link Layer Peer statistics from FW.This function converts
1251 * the firmware data to the NL data and sends the same to the kernel/upper
1252 * layers.
1253 */
1254static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
1255 v_VOID_t *pData)
1256{
1257 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301258 tpSirWifiPeerStat pWifiPeerStat;
1259 tpSirWifiPeerInfo pWifiPeerInfo;
1260 struct nlattr *peerInfo;
1261 struct sk_buff *vendor_event;
1262 int status, i;
1263
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301264 ENTER();
1265
Sunil Duttc69bccb2014-05-26 21:30:20 +05301266 status = wlan_hdd_validate_context(pHddCtx);
1267 if (0 != status)
1268 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301269 return;
1270 }
1271
1272 pWifiPeerStat = (tpSirWifiPeerStat) pData;
1273
1274 hddLog(VOS_TRACE_LEVEL_INFO,
1275 "LL_STATS_PEER_ALL : numPeers %u",
1276 pWifiPeerStat->numPeers);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301277 /*
1278 * Allocate a size of 4096 for the peer stats comprising
1279 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1280 * sizeof (tSirWifiRateStat).Each field is put with an
1281 * NL attribute.The size of 4096 is considered assuming
1282 * that number of rates shall not exceed beyond 50 with
1283 * the sizeof (tSirWifiRateStat) being 32.
1284 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301285 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1286 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301287 if (!vendor_event)
1288 {
1289 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301290 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
Sunil Duttc69bccb2014-05-26 21:30:20 +05301291 __func__);
1292 return;
1293 }
1294 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301295 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1296 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_PEER) ||
1297 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301298 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1299 pWifiPeerStat->numPeers))
1300 {
1301 hddLog(VOS_TRACE_LEVEL_ERROR,
1302 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1303 kfree_skb(vendor_event);
1304 return;
1305 }
1306
1307 peerInfo = nla_nest_start(vendor_event,
1308 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301309 if(!peerInfo)
1310 {
1311 hddLog(VOS_TRACE_LEVEL_ERROR,
1312 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
1313 __func__);
1314 kfree_skb(vendor_event);
1315 return;
1316 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301317
1318 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1319 pWifiPeerStat->peerInfo);
1320
1321 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1322 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301323 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301324 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301325
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301326 if(!peers)
1327 {
1328 hddLog(VOS_TRACE_LEVEL_ERROR,
1329 "%s: peer stats put fail",
1330 __func__);
1331 kfree_skb(vendor_event);
1332 return;
1333 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301334 if (FALSE == put_wifi_peer_info(
1335 pWifiPeerInfo, vendor_event))
1336 {
1337 hddLog(VOS_TRACE_LEVEL_ERROR,
1338 "%s: put_wifi_peer_info put fail", __func__);
1339 kfree_skb(vendor_event);
1340 return;
1341 }
1342
1343 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1344 pWifiPeerStat->peerInfo +
1345 (i * sizeof(tSirWifiPeerInfo)) +
1346 (numRate * sizeof (tSirWifiRateStat)));
1347 nla_nest_end(vendor_event, peers);
1348 }
1349 nla_nest_end(vendor_event, peerInfo);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301350 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301351 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301352}
1353
1354/*
1355 * hdd_link_layer_process_iface_stats () - This function is called after
1356 * receiving Link Layer Interface statistics from FW.This function converts
1357 * the firmware data to the NL data and sends the same to the kernel/upper
1358 * layers.
1359 */
1360static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1361 v_VOID_t *pData)
1362{
1363 tpSirWifiIfaceStat pWifiIfaceStat;
1364 struct sk_buff *vendor_event;
1365 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1366 int status;
1367
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301368 ENTER();
1369
Sunil Duttc69bccb2014-05-26 21:30:20 +05301370 status = wlan_hdd_validate_context(pHddCtx);
1371 if (0 != status)
1372 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301373 return;
1374 }
1375 /*
1376 * Allocate a size of 4096 for the interface stats comprising
1377 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1378 * assuming that all these fit with in the limit.Please take
1379 * a call on the limit based on the data requirements on
1380 * interface statistics.
1381 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301382 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1383 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301384 if (!vendor_event)
1385 {
1386 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301387 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301388 return;
1389 }
1390
1391 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1392
Dino Mycle3b9536d2014-07-09 22:05:24 +05301393
1394 if (FALSE == hdd_get_interface_info( pAdapter,
1395 &pWifiIfaceStat->info))
1396 {
1397 hddLog(VOS_TRACE_LEVEL_ERROR,
1398 FL("hdd_get_interface_info get fail") );
1399 kfree_skb(vendor_event);
1400 return;
1401 }
1402
1403 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
1404 vendor_event))
1405 {
1406 hddLog(VOS_TRACE_LEVEL_ERROR,
1407 FL("put_wifi_iface_stats fail") );
1408 kfree_skb(vendor_event);
1409 return;
1410 }
1411
Sunil Duttc69bccb2014-05-26 21:30:20 +05301412 hddLog(VOS_TRACE_LEVEL_INFO,
1413 "WMI_LINK_STATS_IFACE Data");
1414
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301415 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301416
1417 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301418}
1419
1420/*
1421 * hdd_link_layer_process_radio_stats () - This function is called after
1422 * receiving Link Layer Radio statistics from FW.This function converts
1423 * the firmware data to the NL data and sends the same to the kernel/upper
1424 * layers.
1425 */
1426static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1427 v_VOID_t *pData)
1428{
1429 int status, i;
1430 tpSirWifiRadioStat pWifiRadioStat;
1431 tpSirWifiChannelStats pWifiChannelStats;
1432 struct sk_buff *vendor_event;
1433 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1434 struct nlattr *chList;
1435
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301436 ENTER();
1437
Sunil Duttc69bccb2014-05-26 21:30:20 +05301438 status = wlan_hdd_validate_context(pHddCtx);
1439 if (0 != status)
1440 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301441 return;
1442 }
1443 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1444
1445 hddLog(VOS_TRACE_LEVEL_INFO,
1446 "LL_STATS_RADIO"
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05301447 " number of radios = %u"
Sunil Duttc69bccb2014-05-26 21:30:20 +05301448 " radio is %d onTime is %u "
1449 " txTime is %u rxTime is %u "
1450 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301451 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301452 " onTimePnoScan is %u onTimeHs20 is %u "
1453 " numChannels is %u",
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05301454 NUM_RADIOS,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301455 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1456 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1457 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301458 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301459 pWifiRadioStat->onTimeRoamScan,
1460 pWifiRadioStat->onTimePnoScan,
1461 pWifiRadioStat->onTimeHs20,
1462 pWifiRadioStat->numChannels);
1463 /*
1464 * Allocate a size of 4096 for the Radio stats comprising
1465 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1466 * (tSirWifiChannelStats).Each channel data is put with an
1467 * NL attribute.The size of 4096 is considered assuming that
1468 * number of channels shall not exceed beyond 60 with the
1469 * sizeof (tSirWifiChannelStats) being 24 bytes.
1470 */
1471
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301472 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1473 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301474 if (!vendor_event)
1475 {
1476 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301477 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301478 return;
1479 }
1480
1481 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301482 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1483 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO) ||
1484 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301485 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
1486 pWifiRadioStat->radio) ||
1487 nla_put_u32(vendor_event,
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05301488 QCA_WLAN_VENDOR_ATTR_LL_STATS_NUM_RADIOS,
1489 NUM_RADIOS) ||
1490 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301491 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
1492 pWifiRadioStat->onTime) ||
1493 nla_put_u32(vendor_event,
1494 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
1495 pWifiRadioStat->txTime) ||
1496 nla_put_u32(vendor_event,
1497 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
1498 pWifiRadioStat->rxTime) ||
1499 nla_put_u32(vendor_event,
1500 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
1501 pWifiRadioStat->onTimeScan) ||
1502 nla_put_u32(vendor_event,
1503 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
1504 pWifiRadioStat->onTimeNbd) ||
1505 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301506 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
1507 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05301508 nla_put_u32(vendor_event,
1509 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
1510 pWifiRadioStat->onTimeRoamScan) ||
1511 nla_put_u32(vendor_event,
1512 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
1513 pWifiRadioStat->onTimePnoScan) ||
1514 nla_put_u32(vendor_event,
1515 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
1516 pWifiRadioStat->onTimeHs20) ||
1517 nla_put_u32(vendor_event,
1518 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
1519 pWifiRadioStat->numChannels))
1520 {
1521 hddLog(VOS_TRACE_LEVEL_ERROR,
1522 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1523 kfree_skb(vendor_event);
1524 return ;
1525 }
1526
1527 chList = nla_nest_start(vendor_event,
1528 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301529 if(!chList)
1530 {
1531 hddLog(VOS_TRACE_LEVEL_ERROR,
1532 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
1533 __func__);
1534 kfree_skb(vendor_event);
1535 return;
1536 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301537 for (i = 0; i < pWifiRadioStat->numChannels; i++)
1538 {
1539 struct nlattr *chInfo;
1540
1541 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
1542 pWifiRadioStat->channels +
1543 (i * sizeof(tSirWifiChannelStats)));
1544
Sunil Duttc69bccb2014-05-26 21:30:20 +05301545 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301546 if(!chInfo)
1547 {
1548 hddLog(VOS_TRACE_LEVEL_ERROR,
1549 "%s: failed to put chInfo",
1550 __func__);
1551 kfree_skb(vendor_event);
1552 return;
1553 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301554
1555 if (nla_put_u32(vendor_event,
1556 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
1557 pWifiChannelStats->channel.width) ||
1558 nla_put_u32(vendor_event,
1559 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
1560 pWifiChannelStats->channel.centerFreq) ||
1561 nla_put_u32(vendor_event,
1562 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
1563 pWifiChannelStats->channel.centerFreq0) ||
1564 nla_put_u32(vendor_event,
1565 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
1566 pWifiChannelStats->channel.centerFreq1) ||
1567 nla_put_u32(vendor_event,
1568 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
1569 pWifiChannelStats->onTime) ||
1570 nla_put_u32(vendor_event,
1571 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
1572 pWifiChannelStats->ccaBusyTime))
1573 {
1574 hddLog(VOS_TRACE_LEVEL_ERROR,
1575 FL("cfg80211_vendor_event_alloc failed") );
1576 kfree_skb(vendor_event);
1577 return ;
1578 }
1579 nla_nest_end(vendor_event, chInfo);
1580 }
1581 nla_nest_end(vendor_event, chList);
1582
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301583 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301584
1585 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301586 return;
1587}
1588
1589/*
1590 * hdd_link_layer_stats_ind_callback () - This function is called after
1591 * receiving Link Layer indications from FW.This callback converts the firmware
1592 * data to the NL data and send the same to the kernel/upper layers.
1593 */
1594static void hdd_link_layer_stats_ind_callback ( void *pCtx,
1595 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05301596 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301597{
Dino Mycled3d50022014-07-07 12:58:25 +05301598 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
1599 hdd_adapter_t *pAdapter = NULL;
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301600 struct hdd_ll_stats_context *context;
Dino Mycled3d50022014-07-07 12:58:25 +05301601 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301602 int status;
1603
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301604 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301605
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301606 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301607 if (0 != status)
1608 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301609 return;
1610 }
1611
Dino Mycled3d50022014-07-07 12:58:25 +05301612 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
1613 if (NULL == pAdapter)
1614 {
1615 hddLog(VOS_TRACE_LEVEL_ERROR,
1616 FL(" MAC address %pM does not exist with host"),
1617 macAddr);
1618 return;
1619 }
1620
Sunil Duttc69bccb2014-05-26 21:30:20 +05301621 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301622 "%s: Interface: %s LLStats indType: %d", __func__,
1623 pAdapter->dev->name, indType);
1624
Sunil Duttc69bccb2014-05-26 21:30:20 +05301625 switch (indType)
1626 {
1627 case SIR_HAL_LL_STATS_RESULTS_RSP:
1628 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301629 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301630 "LL_STATS RESP paramID = 0x%x, ifaceId = %u MAC: %pM "
1631 "respId = %u, moreResultToFollow = %u",
1632 linkLayerStatsResults->paramId, linkLayerStatsResults->ifaceId,
1633 macAddr, linkLayerStatsResults->respId,
1634 linkLayerStatsResults->moreResultToFollow);
1635
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301636 spin_lock(&hdd_context_lock);
1637 context = &pHddCtx->ll_stats_context;
1638 /* validate response received from target */
1639 if ((context->request_id != linkLayerStatsResults->respId) ||
1640 !(context->request_bitmap & linkLayerStatsResults->paramId))
1641 {
1642 spin_unlock(&hdd_context_lock);
1643 hddLog(LOGE,
1644 FL("Error : Request id %d response id %d request bitmap 0x%x"
1645 "response bitmap 0x%x"),
1646 context->request_id, linkLayerStatsResults->respId,
1647 context->request_bitmap, linkLayerStatsResults->paramId);
1648 return;
1649 }
1650 spin_unlock(&hdd_context_lock);
1651
Sunil Duttc69bccb2014-05-26 21:30:20 +05301652 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
1653 {
1654 hdd_link_layer_process_radio_stats(pAdapter,
1655 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301656 spin_lock(&hdd_context_lock);
1657 context->request_bitmap &= ~(WMI_LINK_STATS_RADIO);
1658 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301659 }
1660 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
1661 {
1662 hdd_link_layer_process_iface_stats(pAdapter,
1663 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301664 spin_lock(&hdd_context_lock);
1665 context->request_bitmap &= ~(WMI_LINK_STATS_IFACE);
1666 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301667 }
1668 else if ( linkLayerStatsResults->paramId &
1669 WMI_LINK_STATS_ALL_PEER )
1670 {
1671 hdd_link_layer_process_peer_stats(pAdapter,
1672 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301673 spin_lock(&hdd_context_lock);
1674 context->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER);
1675 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301676 } /* WMI_LINK_STATS_ALL_PEER */
1677 else
1678 {
1679 hddLog(VOS_TRACE_LEVEL_ERROR,
1680 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
1681 }
1682
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301683 spin_lock(&hdd_context_lock);
1684 /* complete response event if all requests are completed */
1685 if (0 == context->request_bitmap)
1686 complete(&context->response_event);
1687 spin_unlock(&hdd_context_lock);
1688
Sunil Duttc69bccb2014-05-26 21:30:20 +05301689 break;
1690 }
1691 default:
1692 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
1693 break;
1694 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301695
1696 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301697 return;
1698}
1699
1700const struct
1701nla_policy
1702qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
1703{
1704 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
1705 { .type = NLA_U32 },
1706 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
1707 { .type = NLA_U32 },
1708};
1709
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301710static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1711 struct wireless_dev *wdev,
1712 const void *data,
1713 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301714{
1715 int status;
1716 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301717 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301718 struct net_device *dev = wdev->netdev;
1719 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1720 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1721
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301722 ENTER();
1723
Sunil Duttc69bccb2014-05-26 21:30:20 +05301724 status = wlan_hdd_validate_context(pHddCtx);
1725 if (0 != status)
1726 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301727 return -EINVAL;
1728 }
1729
1730 if (NULL == pAdapter)
1731 {
1732 hddLog(VOS_TRACE_LEVEL_ERROR,
1733 FL("HDD adapter is Null"));
1734 return -ENODEV;
1735 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301736 /* check the LLStats Capability */
1737 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1738 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1739 {
Anurag Chouhan65ea6dc2016-10-25 19:59:14 +05301740 hddLog(VOS_TRACE_LEVEL_WARN,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301741 FL("Link Layer Statistics not supported by Firmware"));
1742 return -EINVAL;
1743 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301744
1745 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1746 (struct nlattr *)data,
1747 data_len, qca_wlan_vendor_ll_set_policy))
1748 {
1749 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1750 return -EINVAL;
1751 }
1752 if (!tb_vendor
1753 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1754 {
1755 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1756 return -EINVAL;
1757 }
1758 if (!tb_vendor[
1759 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1760 {
1761 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1762 return -EINVAL;
1763 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301764 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301765 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301766
Dino Mycledf0a5d92014-07-04 09:41:55 +05301767 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301768 nla_get_u32(
1769 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1770
Dino Mycledf0a5d92014-07-04 09:41:55 +05301771 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301772 nla_get_u32(
1773 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1774
Dino Mycled3d50022014-07-07 12:58:25 +05301775 vos_mem_copy(linkLayerStatsSetReq.macAddr,
1776 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301777
1778
1779 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301780 "LL_STATS_SET reqId = %d, MAC = %pM, mpduSizeThreshold = %d "
1781 "Statistics Gathering = %d ",
1782 linkLayerStatsSetReq.reqId, linkLayerStatsSetReq.macAddr,
1783 linkLayerStatsSetReq.mpduSizeThreshold,
1784 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301785
1786 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1787 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05301788 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301789 {
1790 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1791 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301792 return -EINVAL;
1793
1794 }
Srinivas Dasari98947432014-11-07 19:41:24 +05301795
Sunil Duttc69bccb2014-05-26 21:30:20 +05301796 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301797 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301798 {
1799 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1800 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301801 return -EINVAL;
1802 }
1803
1804 pAdapter->isLinkLayerStatsSet = 1;
1805
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301806 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301807 return 0;
1808}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301809static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1810 struct wireless_dev *wdev,
1811 const void *data,
1812 int data_len)
1813{
1814 int ret = 0;
1815
1816 vos_ssr_protect(__func__);
1817 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
1818 vos_ssr_unprotect(__func__);
1819
1820 return ret;
1821}
Sunil Duttc69bccb2014-05-26 21:30:20 +05301822
1823const struct
1824nla_policy
1825qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1826{
1827 /* Unsigned 32bit value provided by the caller issuing the GET stats
1828 * command. When reporting
1829 * the stats results, the driver uses the same value to indicate
1830 * which GET request the results
1831 * correspond to.
1832 */
1833 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1834
1835 /* Unsigned 32bit value . bit mask to identify what statistics are
1836 requested for retrieval */
1837 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1838};
1839
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301840static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1841 struct wireless_dev *wdev,
1842 const void *data,
1843 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301844{
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301845 unsigned long rc;
1846 struct hdd_ll_stats_context *context;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301847 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1848 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301849 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301850 struct net_device *dev = wdev->netdev;
1851 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma10313ba2015-07-29 19:14:39 +05301852 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301853 int status;
1854
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301855 ENTER();
1856
Sunil Duttc69bccb2014-05-26 21:30:20 +05301857 status = wlan_hdd_validate_context(pHddCtx);
1858 if (0 != status)
1859 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301860 return -EINVAL ;
1861 }
1862
1863 if (NULL == pAdapter)
1864 {
1865 hddLog(VOS_TRACE_LEVEL_FATAL,
1866 "%s: HDD adapter is Null", __func__);
1867 return -ENODEV;
1868 }
Mukul Sharma10313ba2015-07-29 19:14:39 +05301869
1870 if (pHddStaCtx == NULL)
1871 {
1872 hddLog(VOS_TRACE_LEVEL_FATAL,
1873 "%s: HddStaCtx is Null", __func__);
1874 return -ENODEV;
1875 }
1876
Dino Mycledf0a5d92014-07-04 09:41:55 +05301877 /* check the LLStats Capability */
1878 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1879 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1880 {
1881 hddLog(VOS_TRACE_LEVEL_ERROR,
1882 FL("Link Layer Statistics not supported by Firmware"));
1883 return -EINVAL;
1884 }
1885
Sunil Duttc69bccb2014-05-26 21:30:20 +05301886
1887 if (!pAdapter->isLinkLayerStatsSet)
1888 {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05301889 hddLog(VOS_TRACE_LEVEL_ERROR,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301890 "%s: isLinkLayerStatsSet : %d",
1891 __func__, pAdapter->isLinkLayerStatsSet);
1892 return -EINVAL;
1893 }
1894
Mukul Sharma10313ba2015-07-29 19:14:39 +05301895 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
1896 {
1897 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1898 "%s: Roaming in progress, so unable to proceed this request", __func__);
1899 return -EBUSY;
1900 }
1901
Sunil Duttc69bccb2014-05-26 21:30:20 +05301902 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
1903 (struct nlattr *)data,
1904 data_len, qca_wlan_vendor_ll_get_policy))
1905 {
1906 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1907 return -EINVAL;
1908 }
1909
1910 if (!tb_vendor
1911 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
1912 {
1913 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
1914 return -EINVAL;
1915 }
1916
1917 if (!tb_vendor
1918 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
1919 {
1920 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
1921 return -EINVAL;
1922 }
1923
Sunil Duttc69bccb2014-05-26 21:30:20 +05301924
Dino Mycledf0a5d92014-07-04 09:41:55 +05301925 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301926 nla_get_u32( tb_vendor[
1927 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05301928 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301929 nla_get_u32( tb_vendor[
1930 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
1931
Dino Mycled3d50022014-07-07 12:58:25 +05301932 vos_mem_copy(linkLayerStatsGetReq.macAddr,
1933 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301934
1935 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301936 "LL_STATS_GET reqId = %d, MAC = %pM, paramIdMask = %d",
1937 linkLayerStatsGetReq.reqId, linkLayerStatsGetReq.macAddr,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301938 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301939
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301940 spin_lock(&hdd_context_lock);
1941 context = &pHddCtx->ll_stats_context;
1942 context->request_id = linkLayerStatsGetReq.reqId;
1943 context->request_bitmap = linkLayerStatsGetReq.paramIdMask;
1944 INIT_COMPLETION(context->response_event);
1945 spin_unlock(&hdd_context_lock);
1946
Sunil Duttc69bccb2014-05-26 21:30:20 +05301947 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301948 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301949 {
1950 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1951 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301952 return -EINVAL;
1953 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301954
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301955 rc = wait_for_completion_timeout(&context->response_event,
1956 msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS));
1957 if (!rc)
1958 {
1959 hddLog(LOGE,
1960 FL("Target response timed out request id %d request bitmap 0x%x"),
1961 context->request_id, context->request_bitmap);
1962 return -ETIMEDOUT;
1963 }
1964
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301965 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301966 return 0;
1967}
1968
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301969static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1970 struct wireless_dev *wdev,
1971 const void *data,
1972 int data_len)
1973{
1974 int ret = 0;
1975
1976 vos_ssr_protect(__func__);
1977 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
1978 vos_ssr_unprotect(__func__);
1979
1980 return ret;
1981}
1982
Sunil Duttc69bccb2014-05-26 21:30:20 +05301983const struct
1984nla_policy
1985qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
1986{
1987 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
1988 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
1989 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
1990 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
1991};
1992
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301993static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
1994 struct wireless_dev *wdev,
1995 const void *data,
1996 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301997{
1998 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1999 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302000 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302001 struct net_device *dev = wdev->netdev;
2002 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2003 u32 statsClearReqMask;
2004 u8 stopReq;
2005 int status;
2006
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302007 ENTER();
2008
Sunil Duttc69bccb2014-05-26 21:30:20 +05302009 status = wlan_hdd_validate_context(pHddCtx);
2010 if (0 != status)
2011 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302012 return -EINVAL;
2013 }
2014
2015 if (NULL == pAdapter)
2016 {
2017 hddLog(VOS_TRACE_LEVEL_FATAL,
2018 "%s: HDD adapter is Null", __func__);
2019 return -ENODEV;
2020 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302021 /* check the LLStats Capability */
2022 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2023 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2024 {
2025 hddLog(VOS_TRACE_LEVEL_ERROR,
2026 FL("Enable LLStats Capability"));
2027 return -EINVAL;
2028 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302029
2030 if (!pAdapter->isLinkLayerStatsSet)
2031 {
2032 hddLog(VOS_TRACE_LEVEL_FATAL,
2033 "%s: isLinkLayerStatsSet : %d",
2034 __func__, pAdapter->isLinkLayerStatsSet);
2035 return -EINVAL;
2036 }
2037
2038 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
2039 (struct nlattr *)data,
2040 data_len, qca_wlan_vendor_ll_clr_policy))
2041 {
2042 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2043 return -EINVAL;
2044 }
2045
2046 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
2047
2048 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
2049 {
2050 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
2051 return -EINVAL;
2052
2053 }
2054
Sunil Duttc69bccb2014-05-26 21:30:20 +05302055
Dino Mycledf0a5d92014-07-04 09:41:55 +05302056 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302057 nla_get_u32(
2058 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
2059
Dino Mycledf0a5d92014-07-04 09:41:55 +05302060 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302061 nla_get_u8(
2062 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
2063
2064 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302065 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302066
Dino Mycled3d50022014-07-07 12:58:25 +05302067 vos_mem_copy(linkLayerStatsClearReq.macAddr,
2068 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302069
2070 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302071 "LL_STATS_CLEAR reqId = %d, MAC = %pM,"
2072 "statsClearReqMask = 0x%X, stopReq = %d",
2073 linkLayerStatsClearReq.reqId,
2074 linkLayerStatsClearReq.macAddr,
2075 linkLayerStatsClearReq.statsClearReqMask,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302076 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302077
2078 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302079 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302080 {
2081 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05302082 hdd_station_ctx_t *pHddStaCtx;
2083
2084 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2085 if (VOS_STATUS_SUCCESS !=
2086 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2087 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
2088 {
2089 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2090 "WLANTL_ClearInterfaceStats Failed", __func__);
2091 return -EINVAL;
2092 }
2093 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
2094 (statsClearReqMask & WIFI_STATS_IFACE)) {
2095 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
2096 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
2097 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
2098 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
2099 }
2100
Sunil Duttc69bccb2014-05-26 21:30:20 +05302101 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
2102 2 * sizeof(u32) +
2103 NLMSG_HDRLEN);
2104
2105 if (temp_skbuff != NULL)
2106 {
2107
2108 if (nla_put_u32(temp_skbuff,
2109 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
2110 statsClearReqMask) ||
2111 nla_put_u32(temp_skbuff,
2112 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
2113 stopReq))
2114 {
2115 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
2116 kfree_skb(temp_skbuff);
2117 return -EINVAL;
2118 }
2119 /* If the ask is to stop the stats collection as part of clear
2120 * (stopReq = 1) , ensure that no further requests of get
2121 * go to the firmware by having isLinkLayerStatsSet set to 0.
2122 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302123 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05302124 * case the firmware is just asked to clear the statistics.
2125 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05302126 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302127 pAdapter->isLinkLayerStatsSet = 0;
2128 return cfg80211_vendor_cmd_reply(temp_skbuff);
2129 }
2130 return -ENOMEM;
2131 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302132
2133 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302134 return -EINVAL;
2135}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302136static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2137 struct wireless_dev *wdev,
2138 const void *data,
2139 int data_len)
2140{
2141 int ret = 0;
2142
2143 vos_ssr_protect(__func__);
2144 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
2145 vos_ssr_unprotect(__func__);
2146
2147 return ret;
2148
2149
2150}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302151#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
2152
Dino Mycle6fb96c12014-06-10 11:52:40 +05302153#ifdef WLAN_FEATURE_EXTSCAN
2154static const struct nla_policy
2155wlan_hdd_extscan_config_policy
2156 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
2157{
2158 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
2159 { .type = NLA_U32 },
2160 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
2161 { .type = NLA_U32 },
2162 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
2163 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
2164 { .type = NLA_U32 },
2165 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
2166 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
2167
2168 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
2169 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
2170 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
2171 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
2172 { .type = NLA_U8 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302173 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] =
2174 { .type = NLA_U32 },
2175 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT] =
2176 { .type = NLA_U32 },
2177 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] =
2178 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302179 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
2180 { .type = NLA_U32 },
2181 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
2182 { .type = NLA_U32 },
2183 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
2184 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302185 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] =
2186 { .type = NLA_U8 },
2187 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302188 { .type = NLA_U8 },
2189 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
2190 { .type = NLA_U8 },
2191 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
2192 { .type = NLA_U8 },
2193
2194 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
2195 { .type = NLA_U32 },
2196 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] =
2197 { .type = NLA_UNSPEC },
2198 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
2199 { .type = NLA_S32 },
2200 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
2201 { .type = NLA_S32 },
2202 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
2203 { .type = NLA_U32 },
2204 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
2205 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302206 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] =
2207 { .type = NLA_U32 },
2208 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] =
2209 { .type = NLA_BINARY,
2210 .len = IEEE80211_MAX_SSID_LEN + 1 },
2211 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302212 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302213 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] =
2214 { .type = NLA_U32 },
2215 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] =
2216 { .type = NLA_U8 },
2217 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] =
2218 { .type = NLA_S32 },
2219 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] =
2220 { .type = NLA_S32 },
2221 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] =
2222 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302223};
2224
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302225/**
2226 * wlan_hdd_cfg80211_extscan_get_capabilities_rsp() - response from target
2227 * @ctx: hdd global context
2228 * @data: capabilities data
2229 *
2230 * Return: none
2231 */
2232static void
2233wlan_hdd_cfg80211_extscan_get_capabilities_rsp(void *ctx, void *pMsg)
Dino Mycle6fb96c12014-06-10 11:52:40 +05302234{
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302235 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302236 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302237 tSirEXTScanCapabilitiesEvent *data =
2238 (tSirEXTScanCapabilitiesEvent *) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302239
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302240 ENTER();
2241
2242 if (wlan_hdd_validate_context(pHddCtx))
2243 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302244 return;
2245 }
2246
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302247 if (!pMsg)
2248 {
2249 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2250 return;
2251 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302252
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302253 vos_spin_lock_acquire(&hdd_context_lock);
2254
2255 context = &pHddCtx->ext_scan_context;
2256 /* validate response received from target*/
2257 if (context->request_id != data->requestId)
2258 {
2259 vos_spin_lock_release(&hdd_context_lock);
2260 hddLog(LOGE,
2261 FL("Target response id did not match: request_id %d resposne_id %d"),
2262 context->request_id, data->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302263 return;
2264 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302265 else
2266 {
2267 context->capability_response = *data;
2268 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302269 }
2270
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302271 vos_spin_lock_release(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302272
Dino Mycle6fb96c12014-06-10 11:52:40 +05302273 return;
2274}
2275
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302276/*
2277 * define short names for the global vendor params
2278 * used by wlan_hdd_send_ext_scan_capability()
2279 */
2280#define PARAM_REQUEST_ID \
2281 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
2282#define PARAM_STATUS \
2283 QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS
2284#define MAX_SCAN_CACHE_SIZE \
2285 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE
2286#define MAX_SCAN_BUCKETS \
2287 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS
2288#define MAX_AP_CACHE_PER_SCAN \
2289 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN
2290#define MAX_RSSI_SAMPLE_SIZE \
2291 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE
2292#define MAX_SCAN_RPT_THRHOLD \
2293 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
2294#define MAX_HOTLIST_BSSIDS \
2295 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS
2296#define MAX_BSSID_HISTORY_ENTRIES \
2297 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
2298#define MAX_HOTLIST_SSIDS \
2299 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302300#define MAX_SIGNIFICANT_WIFI_CHANGE_APS \
2301 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302302
2303static int wlan_hdd_send_ext_scan_capability(void *ctx)
2304{
2305 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2306 struct sk_buff *skb = NULL;
2307 int ret;
2308 tSirEXTScanCapabilitiesEvent *data;
2309 tANI_U32 nl_buf_len;
2310
2311 ret = wlan_hdd_validate_context(pHddCtx);
2312 if (0 != ret)
2313 {
2314 return ret;
2315 }
2316
2317 data = &(pHddCtx->ext_scan_context.capability_response);
2318
2319 nl_buf_len = NLMSG_HDRLEN;
2320 nl_buf_len += (sizeof(data->requestId) + NLA_HDRLEN) +
2321 (sizeof(data->status) + NLA_HDRLEN) +
2322 (sizeof(data->scanCacheSize) + NLA_HDRLEN) +
2323 (sizeof(data->scanBuckets) + NLA_HDRLEN) +
2324 (sizeof(data->maxApPerScan) + NLA_HDRLEN) +
2325 (sizeof(data->maxRssiSampleSize) + NLA_HDRLEN) +
2326 (sizeof(data->maxScanReportingThreshold) + NLA_HDRLEN) +
2327 (sizeof(data->maxHotlistAPs) + NLA_HDRLEN) +
2328 (sizeof(data->maxBsidHistoryEntries) + NLA_HDRLEN) +
2329 (sizeof(data->maxHotlistSSIDs) + NLA_HDRLEN);
2330
2331 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, nl_buf_len);
2332
2333 if (!skb)
2334 {
2335 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
2336 return -ENOMEM;
2337 }
2338
2339 hddLog(LOG1, "Req Id (%u) Status (%u)", data->requestId, data->status);
2340 hddLog(LOG1, "Scan cache size (%u) Scan buckets (%u) Max AP per scan (%u)",
2341 data->scanCacheSize, data->scanBuckets, data->maxApPerScan);
2342 hddLog(LOG1, "max_rssi_sample_size (%u) max_scan_reporting_threshold (%u)",
2343 data->maxRssiSampleSize, data->maxScanReportingThreshold);
2344 hddLog(LOG1, "max_hotlist_bssids (%u) max_bssid_history_entries (%u)"
2345 "max_hotlist_ssids (%u)", data->maxHotlistAPs,
2346 data->maxBsidHistoryEntries, data->maxHotlistSSIDs);
2347
2348 if (nla_put_u32(skb, PARAM_REQUEST_ID, data->requestId) ||
2349 nla_put_u32(skb, PARAM_STATUS, data->status) ||
2350 nla_put_u32(skb, MAX_SCAN_CACHE_SIZE, data->scanCacheSize) ||
2351 nla_put_u32(skb, MAX_SCAN_BUCKETS, data->scanBuckets) ||
2352 nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN,
2353 data->maxApPerScan) ||
2354 nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE,
2355 data->maxRssiSampleSize) ||
2356 nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD,
2357 data->maxScanReportingThreshold) ||
2358 nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->maxHotlistAPs) ||
2359 nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES,
2360 data->maxBsidHistoryEntries) ||
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302361 nla_put_u32(skb, MAX_HOTLIST_SSIDS, data->maxHotlistSSIDs) ||
2362 nla_put_u32(skb, MAX_SIGNIFICANT_WIFI_CHANGE_APS, 0))
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302363 {
2364 hddLog(LOGE, FL("nla put fail"));
2365 goto nla_put_failure;
2366 }
2367
2368 cfg80211_vendor_cmd_reply(skb);
2369 return 0;
2370
2371nla_put_failure:
2372 kfree_skb(skb);
2373 return -EINVAL;;
2374}
2375
2376/*
2377 * done with short names for the global vendor params
2378 * used by wlan_hdd_send_ext_scan_capability()
2379 */
2380#undef PARAM_REQUEST_ID
2381#undef PARAM_STATUS
2382#undef MAX_SCAN_CACHE_SIZE
2383#undef MAX_SCAN_BUCKETS
2384#undef MAX_AP_CACHE_PER_SCAN
2385#undef MAX_RSSI_SAMPLE_SIZE
2386#undef MAX_SCAN_RPT_THRHOLD
2387#undef MAX_HOTLIST_BSSIDS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302388#undef MAX_BSSID_HISTORY_ENTRIES
2389#undef MAX_HOTLIST_SSIDS
Dino Mycle6fb96c12014-06-10 11:52:40 +05302390
2391static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
2392{
2393 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
2394 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302395 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302396 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302397
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302398 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302399
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302400 if (wlan_hdd_validate_context(pHddCtx))
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302401 return;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302402
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302403 if (!pMsg)
2404 {
2405 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302406 return;
2407 }
2408
Dino Mycle6fb96c12014-06-10 11:52:40 +05302409 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2410 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2411
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302412 context = &pHddCtx->ext_scan_context;
2413 spin_lock(&hdd_context_lock);
2414 if (context->request_id == pData->requestId) {
2415 context->response_status = pData->status ? -EINVAL : 0;
2416 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302417 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302418 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302419
2420 /*
2421 * Store the Request ID for comparing with the requestID obtained
2422 * in other requests.HDD shall return a failure is the extscan_stop
2423 * request is issued with a different requestId as that of the
2424 * extscan_start request. Also, This requestId shall be used while
2425 * indicating the full scan results to the upper layers.
2426 * The requestId is stored with the assumption that the firmware
2427 * shall return the ext scan start request's requestId in ext scan
2428 * start response.
2429 */
2430 if (pData->status == 0)
2431 pMac->sme.extScanStartReqId = pData->requestId;
2432
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302433 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302434 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302435}
2436
2437
2438static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2439{
2440 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2441 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302442 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302443
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302444 ENTER();
2445
2446 if (wlan_hdd_validate_context(pHddCtx)){
2447 return;
2448 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302449
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302450 if (!pMsg)
2451 {
2452 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302453 return;
2454 }
2455
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302456 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2457 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302458
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302459 context = &pHddCtx->ext_scan_context;
2460 spin_lock(&hdd_context_lock);
2461 if (context->request_id == pData->requestId) {
2462 context->response_status = pData->status ? -EINVAL : 0;
2463 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302464 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302465 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302466
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302467 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302468 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302469}
2470
Dino Mycle6fb96c12014-06-10 11:52:40 +05302471static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2472 void *pMsg)
2473{
2474 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302475 tpSirEXTScanSetBssidHotListRspParams pData =
2476 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302477 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302478
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302479 ENTER();
2480
2481 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05302482 return;
2483 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302484
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302485 if (!pMsg)
2486 {
2487 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2488 return;
2489 }
2490
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302491 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2492 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302493
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302494 context = &pHddCtx->ext_scan_context;
2495 spin_lock(&hdd_context_lock);
2496 if (context->request_id == pData->requestId) {
2497 context->response_status = pData->status ? -EINVAL : 0;
2498 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302499 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302500 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302501
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302502 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302503 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302504}
2505
2506static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2507 void *pMsg)
2508{
2509 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302510 tpSirEXTScanResetBssidHotlistRspParams pData =
2511 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302512 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302513
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302514 ENTER();
2515
2516 if (wlan_hdd_validate_context(pHddCtx)) {
2517 return;
2518 }
2519 if (!pMsg)
2520 {
2521 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302522 return;
2523 }
2524
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302525 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2526 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302527
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302528 context = &pHddCtx->ext_scan_context;
2529 spin_lock(&hdd_context_lock);
2530 if (context->request_id == pData->requestId) {
2531 context->response_status = pData->status ? -EINVAL : 0;
2532 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302533 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302534 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302535
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302536 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302537 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302538}
2539
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05302540static void wlan_hdd_cfg80211_extscan_set_ssid_hotlist_rsp(void *ctx,
2541 void *pMsg)
2542{
2543 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2544 tpSirEXTScanSetSsidHotListRspParams pData =
2545 (tpSirEXTScanSetSsidHotListRspParams) pMsg;
2546 struct hdd_ext_scan_context *context;
2547
2548 if (wlan_hdd_validate_context(pHddCtx)){
2549 return;
2550 }
2551
2552 if (!pMsg)
2553 {
2554 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2555 return;
2556 }
2557
2558 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2559 pData->status);
2560
2561 context = &pHddCtx->ext_scan_context;
2562 spin_lock(&hdd_context_lock);
2563 if (context->request_id == pData->requestId) {
2564 context->response_status = pData->status ? -EINVAL : 0;
2565 complete(&context->response_event);
2566 }
2567 spin_unlock(&hdd_context_lock);
2568
2569 return;
2570}
2571
2572static void wlan_hdd_cfg80211_extscan_reset_ssid_hotlist_rsp(void *ctx,
2573 void *pMsg)
2574{
2575 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2576 tpSirEXTScanResetSsidHotlistRspParams pData =
2577 (tpSirEXTScanResetSsidHotlistRspParams) pMsg;
2578 struct hdd_ext_scan_context *context;
2579
2580 if (wlan_hdd_validate_context(pHddCtx)) {
2581 return;
2582 }
2583 if (!pMsg)
2584 {
2585 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2586 return;
2587 }
2588
2589 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2590 pData->status);
2591
2592 context = &pHddCtx->ext_scan_context;
2593 spin_lock(&hdd_context_lock);
2594 if (context->request_id == pData->requestId) {
2595 context->response_status = pData->status ? -EINVAL : 0;
2596 complete(&context->response_event);
2597 }
2598 spin_unlock(&hdd_context_lock);
2599
2600 return;
2601}
2602
2603
Dino Mycle6fb96c12014-06-10 11:52:40 +05302604static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2605 void *pMsg)
2606{
2607 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2608 struct sk_buff *skb = NULL;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302609 tANI_U32 i = 0, j, resultsPerEvent, scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302610 tANI_S32 totalResults;
2611 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302612 tpSirWifiScanResult pSirWifiScanResult, head_ptr;
2613 struct hdd_ext_scan_context *context;
2614 bool ignore_cached_results = false;
2615 tExtscanCachedScanResult *result;
2616 struct nlattr *nla_results;
2617 tANI_U16 ieLength= 0;
2618 tANI_U8 *ie = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302619
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302620 ENTER();
2621
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302622 if (wlan_hdd_validate_context(pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302623 return;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302624
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302625 if (!pMsg)
2626 {
2627 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2628 return;
2629 }
2630
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302631 spin_lock(&hdd_context_lock);
2632 context = &pHddCtx->ext_scan_context;
2633 ignore_cached_results = context->ignore_cached_results;
2634 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302635
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302636 if (ignore_cached_results) {
2637 hddLog(LOGE,
2638 FL("Ignore the cached results received after timeout"));
2639 return;
2640 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302641
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302642 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u More Data %u No of scan ids %u",
2643 pData->requestId, pData->moreData, pData->scanResultSize);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302644
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302645 result = (tExtscanCachedScanResult *)&(pData->result);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302646
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302647 for (scan_id_index = 0; scan_id_index < pData->scanResultSize;
2648 scan_id_index++) {
2649 result+= scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302650
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302651 totalResults = result->num_results;
2652 hddLog(VOS_TRACE_LEVEL_INFO, "scan_id %u flags %u Num results %u",
2653 result->scan_id, result->flags, totalResults);
2654 i = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302655
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302656 do{
2657 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2658 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2659 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302660
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302661 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2662 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN);
2663
2664 if (!skb) {
2665 hddLog(VOS_TRACE_LEVEL_ERROR,
2666 FL("cfg80211_vendor_event_alloc failed"));
2667 return;
2668 }
2669
2670 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2671
2672 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2673 pData->requestId) ||
2674 nla_put_u32(skb,
2675 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2676 resultsPerEvent)) {
2677 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2678 goto fail;
2679 }
2680 if (nla_put_u8(skb,
2681 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2682 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302683 {
2684 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2685 goto fail;
2686 }
2687
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302688 if (nla_put_u32(skb,
2689 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
2690 result->scan_id)) {
2691 hddLog(LOGE, FL("put fail"));
2692 goto fail;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302693 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302694
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302695 nla_results = nla_nest_start(skb,
2696 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_LIST);
2697 if (!nla_results)
2698 goto fail;
2699
2700 if (resultsPerEvent) {
2701 struct nlattr *aps;
2702 struct nlattr *nla_result;
2703
2704 nla_result = nla_nest_start(skb, scan_id_index);
2705 if(!nla_result)
2706 goto fail;
2707
2708 if (nla_put_u32(skb,
2709 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
2710 result->scan_id) ||
2711 nla_put_u32(skb,
2712 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_FLAGS,
2713 result->flags) ||
2714 nla_put_u32(skb,
2715 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2716 totalResults)) {
2717 hddLog(LOGE, FL("put fail"));
2718 goto fail;
2719 }
2720
2721 aps = nla_nest_start(skb,
2722 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2723 if (!aps)
2724 {
2725 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2726 goto fail;
2727 }
2728
2729 head_ptr = (tpSirWifiScanResult) &(result->ap);
2730
2731 for (j = 0; j < resultsPerEvent; j++, i++) {
2732 struct nlattr *ap;
2733 pSirWifiScanResult = head_ptr + i;
2734
2735 /*
Srinivas Dasari91727c12016-03-23 17:59:06 +05302736 * Firmware returns timestamp from extscan_start till
2737 * BSSID was cached (in micro seconds). Add this with
2738 * time gap between system boot up to extscan_start
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302739 * to derive the time since boot when the
2740 * BSSID was cached.
2741 */
Srinivas Dasari91727c12016-03-23 17:59:06 +05302742 pSirWifiScanResult->ts +=
2743 pHddCtx->extscan_start_time_since_boot;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302744 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2745 "Ssid (%s)"
2746 "Bssid: %pM "
2747 "Channel (%u)"
2748 "Rssi (%d)"
2749 "RTT (%u)"
2750 "RTT_SD (%u)"
2751 "Beacon Period %u"
2752 "Capability 0x%x "
2753 "Ie length %d",
2754 i,
2755 pSirWifiScanResult->ts,
2756 pSirWifiScanResult->ssid,
2757 pSirWifiScanResult->bssid,
2758 pSirWifiScanResult->channel,
2759 pSirWifiScanResult->rssi,
2760 pSirWifiScanResult->rtt,
2761 pSirWifiScanResult->rtt_sd,
2762 pSirWifiScanResult->beaconPeriod,
2763 pSirWifiScanResult->capability,
2764 ieLength);
2765
2766 ap = nla_nest_start(skb, j + 1);
2767 if (!ap)
2768 {
2769 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2770 goto fail;
2771 }
2772
2773 if (nla_put_u64(skb,
2774 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2775 pSirWifiScanResult->ts) )
2776 {
2777 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2778 goto fail;
2779 }
2780 if (nla_put(skb,
2781 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2782 sizeof(pSirWifiScanResult->ssid),
2783 pSirWifiScanResult->ssid) )
2784 {
2785 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2786 goto fail;
2787 }
2788 if (nla_put(skb,
2789 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2790 sizeof(pSirWifiScanResult->bssid),
2791 pSirWifiScanResult->bssid) )
2792 {
2793 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2794 goto fail;
2795 }
2796 if (nla_put_u32(skb,
2797 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2798 pSirWifiScanResult->channel) )
2799 {
2800 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2801 goto fail;
2802 }
2803 if (nla_put_s32(skb,
2804 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2805 pSirWifiScanResult->rssi) )
2806 {
2807 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2808 goto fail;
2809 }
2810 if (nla_put_u32(skb,
2811 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2812 pSirWifiScanResult->rtt) )
2813 {
2814 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2815 goto fail;
2816 }
2817 if (nla_put_u32(skb,
2818 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2819 pSirWifiScanResult->rtt_sd))
2820 {
2821 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2822 goto fail;
2823 }
2824 if (nla_put_u32(skb,
2825 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
2826 pSirWifiScanResult->beaconPeriod))
2827 {
2828 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2829 goto fail;
2830 }
2831 if (nla_put_u32(skb,
2832 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
2833 pSirWifiScanResult->capability))
2834 {
2835 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2836 goto fail;
2837 }
2838 if (nla_put_u32(skb,
2839 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
2840 ieLength))
2841 {
2842 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2843 goto fail;
2844 }
2845
2846 if (ieLength)
2847 if (nla_put(skb,
2848 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
2849 ieLength, ie)) {
2850 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2851 goto fail;
2852 }
2853
2854 nla_nest_end(skb, ap);
2855 }
2856 nla_nest_end(skb, aps);
2857 nla_nest_end(skb, nla_result);
2858 }
2859
2860 nla_nest_end(skb, nla_results);
2861
2862 cfg80211_vendor_cmd_reply(skb);
2863
2864 } while (totalResults > 0);
2865 }
2866
2867 if (!pData->moreData) {
2868 spin_lock(&hdd_context_lock);
2869 context->response_status = 0;
2870 complete(&context->response_event);
2871 spin_unlock(&hdd_context_lock);
2872 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302873
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302874 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302875 return;
2876fail:
2877 kfree_skb(skb);
2878 return;
2879}
2880
2881static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
2882 void *pMsg)
2883{
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302884 tpSirEXTScanHotlistMatch pData = (tpSirEXTScanHotlistMatch) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302885 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2886 struct sk_buff *skb = NULL;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302887 tANI_U32 i, index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302888
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302889 ENTER();
2890
2891 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302892 hddLog(LOGE,
2893 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302894 return;
2895 }
2896 if (!pMsg)
2897 {
2898 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302899 return;
2900 }
2901
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302902 if (pData->bss_found)
2903 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX;
2904 else
2905 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX;
2906
Dino Mycle6fb96c12014-06-10 11:52:40 +05302907 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302908#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2909 NULL,
2910#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302911 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302912 index, GFP_KERNEL);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302913
2914 if (!skb) {
2915 hddLog(VOS_TRACE_LEVEL_ERROR,
2916 FL("cfg80211_vendor_event_alloc failed"));
2917 return;
2918 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302919
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302920 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2921 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numHotlistBss);
2922 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2923 hddLog(VOS_TRACE_LEVEL_INFO, "ap_found %u", pData->bss_found);
2924
2925 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302926 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
2927 "Ssid (%s) "
2928 "Bssid (" MAC_ADDRESS_STR ") "
2929 "Channel (%u) "
2930 "Rssi (%d) "
2931 "RTT (%u) "
2932 "RTT_SD (%u) ",
2933 i,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302934 pData->bssHotlist[i].ts,
2935 pData->bssHotlist[i].ssid,
2936 MAC_ADDR_ARRAY(pData->bssHotlist[i].bssid),
2937 pData->bssHotlist[i].channel,
2938 pData->bssHotlist[i].rssi,
2939 pData->bssHotlist[i].rtt,
2940 pData->bssHotlist[i].rtt_sd);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302941 }
2942
2943 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2944 pData->requestId) ||
2945 nla_put_u32(skb,
2946 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302947 pData->numHotlistBss)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302948 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2949 goto fail;
2950 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302951 if (pData->numHotlistBss) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302952 struct nlattr *aps;
2953
2954 aps = nla_nest_start(skb,
2955 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2956 if (!aps)
2957 goto fail;
2958
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302959 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302960 struct nlattr *ap;
2961
2962 ap = nla_nest_start(skb, i + 1);
2963 if (!ap)
2964 goto fail;
2965
2966 if (nla_put_u64(skb,
2967 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302968 pData->bssHotlist[i].ts) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302969 nla_put(skb,
2970 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302971 sizeof(pData->bssHotlist[i].ssid),
2972 pData->bssHotlist[i].ssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302973 nla_put(skb,
2974 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302975 sizeof(pData->bssHotlist[i].bssid),
2976 pData->bssHotlist[i].bssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302977 nla_put_u32(skb,
2978 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302979 pData->bssHotlist[i].channel) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302980 nla_put_s32(skb,
2981 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302982 pData->bssHotlist[i].rssi) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302983 nla_put_u32(skb,
2984 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302985 pData->bssHotlist[i].rtt) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302986 nla_put_u32(skb,
2987 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302988 pData->bssHotlist[i].rtt_sd))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302989 goto fail;
2990
2991 nla_nest_end(skb, ap);
2992 }
2993 nla_nest_end(skb, aps);
2994
2995 if (nla_put_u8(skb,
2996 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2997 pData->moreData))
2998 goto fail;
2999 }
3000
3001 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303002 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303003 return;
3004
3005fail:
3006 kfree_skb(skb);
3007 return;
3008
3009}
Dino Mycle6fb96c12014-06-10 11:52:40 +05303010
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303011/**
3012 * wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind() -
3013 * Handle an SSID hotlist match event
3014 * @ctx: HDD context registered with SME
3015 * @event: The SSID hotlist match event
3016 *
3017 * This function will take an SSID match event that was generated by
3018 * firmware and will convert it into a cfg80211 vendor event which is
3019 * sent to userspace.
3020 *
3021 * Return: none
3022 */
3023static void
3024wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind(void *ctx,
3025 void *pMsg)
3026{
3027 hdd_context_t *hdd_ctx = ctx;
3028 struct sk_buff *skb;
3029 tANI_U32 i, index;
3030 tpSirEXTScanSsidHotlistMatch pData = (tpSirEXTScanSsidHotlistMatch) pMsg;
3031
3032 ENTER();
3033
3034 if (wlan_hdd_validate_context(hdd_ctx)) {
3035 hddLog(LOGE,
3036 FL("HDD context is not valid or response"));
3037 return;
3038 }
3039 if (!pMsg)
3040 {
3041 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3042 return;
3043 }
3044
3045 if (pData->ssid_found) {
3046 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND_INDEX;
3047 hddLog(LOG1, "SSID hotlist found");
3048 } else {
3049 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST_INDEX;
3050 hddLog(LOG1, "SSID hotlist lost");
3051 }
3052
3053 skb = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
3054#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3055 NULL,
3056#endif
3057 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3058 index, GFP_KERNEL);
3059
3060 if (!skb) {
3061 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
3062 return;
3063 }
3064 hddLog(LOG1, "Req Id %u, Num of SSIDs %u, More Data (%u)",
3065 pData->requestId, pData->numHotlistSsid, pData->moreData);
3066
3067 for (i = 0; i < pData->numHotlistSsid; i++) {
3068 hddLog(LOG1, "[i=%d] Timestamp %llu "
3069 "Ssid: %s "
3070 "Bssid (" MAC_ADDRESS_STR ") "
3071 "Channel %u "
3072 "Rssi %d "
3073 "RTT %u "
3074 "RTT_SD %u",
3075 i,
3076 pData->ssidHotlist[i].ts,
3077 pData->ssidHotlist[i].ssid,
3078 MAC_ADDR_ARRAY(pData->ssidHotlist[i].bssid),
3079 pData->ssidHotlist[i].channel,
3080 pData->ssidHotlist[i].rssi,
3081 pData->ssidHotlist[i].rtt,
3082 pData->ssidHotlist[i].rtt_sd);
3083 }
3084
3085 if (nla_put_u32(skb,
3086 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3087 pData->requestId) ||
3088 nla_put_u32(skb,
3089 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3090 pData->numHotlistSsid)) {
3091 hddLog(LOGE, FL("put fail"));
3092 goto fail;
3093 }
3094
3095 if (pData->numHotlistSsid) {
3096 struct nlattr *aps;
3097 aps = nla_nest_start(skb,
3098 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3099 if (!aps) {
3100 hddLog(LOGE, FL("nest fail"));
3101 goto fail;
3102 }
3103
3104 for (i = 0; i < pData->numHotlistSsid; i++) {
3105 struct nlattr *ap;
3106
3107 ap = nla_nest_start(skb, i);
3108 if (!ap) {
3109 hddLog(LOGE, FL("nest fail"));
3110 goto fail;
3111 }
3112
3113 if (nla_put_u64(skb,
3114 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3115 pData->ssidHotlist[i].ts) ||
3116 nla_put(skb,
3117 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3118 sizeof(pData->ssidHotlist[i].ssid),
3119 pData->ssidHotlist[i].ssid) ||
3120 nla_put(skb,
3121 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3122 sizeof(pData->ssidHotlist[i].bssid),
3123 pData->ssidHotlist[i].bssid) ||
3124 nla_put_u32(skb,
3125 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3126 pData->ssidHotlist[i].channel) ||
3127 nla_put_s32(skb,
3128 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
3129 pData->ssidHotlist[i].rssi) ||
3130 nla_put_u32(skb,
3131 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3132 pData->ssidHotlist[i].rtt) ||
3133 nla_put_u32(skb,
3134 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3135 pData->ssidHotlist[i].rtt_sd)) {
3136 hddLog(LOGE, FL("put fail"));
3137 goto fail;
3138 }
3139 nla_nest_end(skb, ap);
3140 }
3141 nla_nest_end(skb, aps);
3142
3143 if (nla_put_u8(skb,
3144 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3145 pData->moreData)) {
3146 hddLog(LOGE, FL("put fail"));
3147 goto fail;
3148 }
3149 }
3150
3151 cfg80211_vendor_event(skb, GFP_KERNEL);
3152 return;
3153
3154fail:
3155 kfree_skb(skb);
3156 return;
3157
3158}
3159
3160
Dino Mycle6fb96c12014-06-10 11:52:40 +05303161static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
3162 void *pMsg)
3163{
3164 struct sk_buff *skb;
3165 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3166 tpSirWifiFullScanResultEvent pData =
3167 (tpSirWifiFullScanResultEvent) (pMsg);
3168
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303169 ENTER();
3170
3171 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303172 hddLog(LOGE,
3173 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303174 return;
3175 }
3176 if (!pMsg)
3177 {
3178 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303179 return;
3180 }
3181
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303182 /*
3183 * If the full scan result including IE data exceeds NL 4K size
3184 * limitation, drop that beacon/probe rsp frame.
3185 */
3186 if ((sizeof(*pData) + pData->ieLength) >= EXTSCAN_EVENT_BUF_SIZE) {
3187 hddLog(LOGE, FL("Frame exceeded NL size limilation, drop it!"));
3188 return;
3189 }
3190
Dino Mycle6fb96c12014-06-10 11:52:40 +05303191 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303192#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3193 NULL,
3194#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303195 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3196 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
3197 GFP_KERNEL);
3198
3199 if (!skb) {
3200 hddLog(VOS_TRACE_LEVEL_ERROR,
3201 FL("cfg80211_vendor_event_alloc failed"));
3202 return;
3203 }
3204
Dino Mycle6fb96c12014-06-10 11:52:40 +05303205 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
3206 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
3207 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
3208 "Ssid (%s)"
3209 "Bssid (" MAC_ADDRESS_STR ")"
3210 "Channel (%u)"
3211 "Rssi (%d)"
3212 "RTT (%u)"
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303213 "RTT_SD (%u)"
3214 "Bcn Period %d"
3215 "Capability 0x%X "),
Dino Mycle6fb96c12014-06-10 11:52:40 +05303216 pData->ap.ts,
3217 pData->ap.ssid,
3218 MAC_ADDR_ARRAY(pData->ap.bssid),
3219 pData->ap.channel,
3220 pData->ap.rssi,
3221 pData->ap.rtt,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303222 pData->ap.rtt_sd,
3223 pData->ap.beaconPeriod,
3224 pData->ap.capability);
3225
Dino Mycle6fb96c12014-06-10 11:52:40 +05303226 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
3227 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3228 pData->requestId) ||
3229 nla_put_u64(skb,
3230 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3231 pData->ap.ts) ||
3232 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3233 sizeof(pData->ap.ssid),
3234 pData->ap.ssid) ||
3235 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3236 WNI_CFG_BSSID_LEN,
3237 pData->ap.bssid) ||
3238 nla_put_u32(skb,
3239 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3240 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05303241 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303242 pData->ap.rssi) ||
3243 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3244 pData->ap.rtt) ||
3245 nla_put_u32(skb,
3246 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3247 pData->ap.rtt_sd) ||
3248 nla_put_u16(skb,
3249 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3250 pData->ap.beaconPeriod) ||
3251 nla_put_u16(skb,
3252 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3253 pData->ap.capability) ||
3254 nla_put_u32(skb,
3255 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303256 pData->ieLength) ||
3257 nla_put_u8(skb,
3258 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3259 pData->moreData))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303260 {
3261 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3262 goto nla_put_failure;
3263 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303264
3265 if (pData->ieLength) {
3266 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3267 pData->ieLength,
3268 pData->ie))
3269 {
3270 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3271 goto nla_put_failure;
3272 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303273 }
3274
3275 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303276 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303277 return;
3278
3279nla_put_failure:
3280 kfree_skb(skb);
3281 return;
3282}
3283
3284static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
3285 void *pMsg)
3286{
3287 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3288 struct sk_buff *skb = NULL;
3289 tpSirEXTScanResultsAvailableIndParams pData =
3290 (tpSirEXTScanResultsAvailableIndParams) pMsg;
3291
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303292 ENTER();
3293
3294 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303295 hddLog(LOGE,
3296 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303297 return;
3298 }
3299 if (!pMsg)
3300 {
3301 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303302 return;
3303 }
3304
3305 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303306#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3307 NULL,
3308#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303309 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3310 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
3311 GFP_KERNEL);
3312
3313 if (!skb) {
3314 hddLog(VOS_TRACE_LEVEL_ERROR,
3315 FL("cfg80211_vendor_event_alloc failed"));
3316 return;
3317 }
3318
Dino Mycle6fb96c12014-06-10 11:52:40 +05303319 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3320 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
3321 pData->numResultsAvailable);
3322 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3323 pData->requestId) ||
3324 nla_put_u32(skb,
3325 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3326 pData->numResultsAvailable)) {
3327 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3328 goto nla_put_failure;
3329 }
3330
3331 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303332 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303333 return;
3334
3335nla_put_failure:
3336 kfree_skb(skb);
3337 return;
3338}
3339
3340static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
3341{
3342 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3343 struct sk_buff *skb = NULL;
3344 tpSirEXTScanProgressIndParams pData =
3345 (tpSirEXTScanProgressIndParams) pMsg;
3346
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303347 ENTER();
3348
3349 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303350 hddLog(LOGE,
3351 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303352 return;
3353 }
3354 if (!pMsg)
3355 {
3356 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303357 return;
3358 }
3359
3360 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303361#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3362 NULL,
3363#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303364 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3365 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
3366 GFP_KERNEL);
3367
3368 if (!skb) {
3369 hddLog(VOS_TRACE_LEVEL_ERROR,
3370 FL("cfg80211_vendor_event_alloc failed"));
3371 return;
3372 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303373 hddLog(VOS_TRACE_LEVEL_INFO, FL("Request Id (%u) "), pData->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303374 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
3375 pData->extScanEventType);
3376 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
3377 pData->status);
3378
3379 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
3380 pData->extScanEventType) ||
3381 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05303382 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3383 pData->requestId) ||
3384 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303385 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
3386 pData->status)) {
3387 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3388 goto nla_put_failure;
3389 }
3390
3391 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303392 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303393 return;
3394
3395nla_put_failure:
3396 kfree_skb(skb);
3397 return;
3398}
3399
3400void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
3401 void *pMsg)
3402{
3403 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3404
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303405 ENTER();
3406
Dino Mycle6fb96c12014-06-10 11:52:40 +05303407 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303408 return;
3409 }
3410
3411 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
3412
3413
3414 switch(evType) {
3415 case SIR_HAL_EXTSCAN_START_RSP:
3416 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
3417 break;
3418
3419 case SIR_HAL_EXTSCAN_STOP_RSP:
3420 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
3421 break;
3422 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
3423 /* There is no need to send this response to upper layer
3424 Just log the message */
3425 hddLog(VOS_TRACE_LEVEL_INFO,
3426 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
3427 break;
3428 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
3429 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
3430 break;
3431
3432 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
3433 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
3434 break;
3435
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303436 case SIR_HAL_EXTSCAN_SET_SSID_HOTLIST_RSP:
3437 wlan_hdd_cfg80211_extscan_set_ssid_hotlist_rsp(ctx, pMsg);
3438 break;
3439
3440 case SIR_HAL_EXTSCAN_RESET_SSID_HOTLIST_RSP:
3441 wlan_hdd_cfg80211_extscan_reset_ssid_hotlist_rsp(ctx, pMsg);
3442 break;
3443
Dino Mycle6fb96c12014-06-10 11:52:40 +05303444 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303445 wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx, pMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303446 break;
3447 case SIR_HAL_EXTSCAN_PROGRESS_IND:
3448 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
3449 break;
3450 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
3451 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
3452 break;
3453 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
3454 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
3455 break;
3456 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
3457 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
3458 break;
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303459 case SIR_HAL_EXTSCAN_SSID_HOTLIST_MATCH_IND:
3460 wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind(ctx, pMsg);
3461 break;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303462 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
3463 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
3464 break;
3465 default:
3466 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
3467 break;
3468 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303469 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303470}
3471
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303472static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3473 struct wireless_dev *wdev,
3474 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303475{
Dino Myclee8843b32014-07-04 14:21:45 +05303476 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303477 struct net_device *dev = wdev->netdev;
3478 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3479 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3480 struct nlattr
3481 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3482 eHalStatus status;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303483 struct hdd_ext_scan_context *context;
3484 unsigned long rc;
3485 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303486
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303487 ENTER();
3488
Dino Mycle6fb96c12014-06-10 11:52:40 +05303489 status = wlan_hdd_validate_context(pHddCtx);
3490 if (0 != status)
3491 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303492 return -EINVAL;
3493 }
Dino Myclee8843b32014-07-04 14:21:45 +05303494 /* check the EXTScan Capability */
3495 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303496 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3497 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303498 {
3499 hddLog(VOS_TRACE_LEVEL_ERROR,
3500 FL("EXTScan not enabled/supported by Firmware"));
3501 return -EINVAL;
3502 }
3503
Dino Mycle6fb96c12014-06-10 11:52:40 +05303504 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3505 data, dataLen,
3506 wlan_hdd_extscan_config_policy)) {
3507 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3508 return -EINVAL;
3509 }
3510
3511 /* Parse and fetch request Id */
3512 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3513 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3514 return -EINVAL;
3515 }
3516
Dino Myclee8843b32014-07-04 14:21:45 +05303517 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303518 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303519 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303520
Dino Myclee8843b32014-07-04 14:21:45 +05303521 reqMsg.sessionId = pAdapter->sessionId;
3522 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303523
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303524 vos_spin_lock_acquire(&hdd_context_lock);
3525 context = &pHddCtx->ext_scan_context;
3526 context->request_id = reqMsg.requestId;
3527 INIT_COMPLETION(context->response_event);
3528 vos_spin_lock_release(&hdd_context_lock);
3529
Dino Myclee8843b32014-07-04 14:21:45 +05303530 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303531 if (!HAL_STATUS_SUCCESS(status)) {
3532 hddLog(VOS_TRACE_LEVEL_ERROR,
3533 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303534 return -EINVAL;
3535 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303536
3537 rc = wait_for_completion_timeout(&context->response_event,
3538 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3539 if (!rc) {
3540 hddLog(LOGE, FL("Target response timed out"));
3541 return -ETIMEDOUT;
3542 }
3543
3544 ret = wlan_hdd_send_ext_scan_capability(pHddCtx);
3545 if (ret)
3546 hddLog(LOGE, FL("Failed to send ext scan capability to user space"));
3547
3548 return ret;
3549
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303550 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303551 return 0;
3552}
3553
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303554static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3555 struct wireless_dev *wdev,
3556 const void *data, int dataLen)
3557{
3558 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303559
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303560 vos_ssr_protect(__func__);
3561 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
3562 vos_ssr_unprotect(__func__);
3563
3564 return ret;
3565}
3566
3567static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3568 struct wireless_dev *wdev,
3569 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303570{
Dino Myclee8843b32014-07-04 14:21:45 +05303571 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303572 struct net_device *dev = wdev->netdev;
3573 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3574 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3575 struct nlattr
3576 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3577 eHalStatus status;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303578 struct hdd_ext_scan_context *context;
3579 unsigned long rc;
3580 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303581
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303582 ENTER();
3583
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303584 if (VOS_FTM_MODE == hdd_get_conparam()) {
3585 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3586 return -EINVAL;
3587 }
3588
Dino Mycle6fb96c12014-06-10 11:52:40 +05303589 status = wlan_hdd_validate_context(pHddCtx);
3590 if (0 != status)
3591 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303592 return -EINVAL;
3593 }
Dino Myclee8843b32014-07-04 14:21:45 +05303594 /* check the EXTScan Capability */
3595 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303596 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3597 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303598 {
3599 hddLog(VOS_TRACE_LEVEL_ERROR,
3600 FL("EXTScan not enabled/supported by Firmware"));
3601 return -EINVAL;
3602 }
3603
Dino Mycle6fb96c12014-06-10 11:52:40 +05303604 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3605 data, dataLen,
3606 wlan_hdd_extscan_config_policy)) {
3607 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3608 return -EINVAL;
3609 }
3610 /* Parse and fetch request Id */
3611 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3612 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3613 return -EINVAL;
3614 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303615
Dino Myclee8843b32014-07-04 14:21:45 +05303616 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303617 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3618
Dino Myclee8843b32014-07-04 14:21:45 +05303619 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303620
Dino Myclee8843b32014-07-04 14:21:45 +05303621 reqMsg.sessionId = pAdapter->sessionId;
3622 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303623
3624 /* Parse and fetch flush parameter */
3625 if (!tb
3626 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3627 {
3628 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3629 goto failed;
3630 }
Dino Myclee8843b32014-07-04 14:21:45 +05303631 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303632 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3633
Dino Myclee8843b32014-07-04 14:21:45 +05303634 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303635
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303636 spin_lock(&hdd_context_lock);
3637 context = &pHddCtx->ext_scan_context;
3638 context->request_id = reqMsg.requestId;
3639 context->ignore_cached_results = false;
3640 INIT_COMPLETION(context->response_event);
3641 spin_unlock(&hdd_context_lock);
3642
Dino Myclee8843b32014-07-04 14:21:45 +05303643 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303644 if (!HAL_STATUS_SUCCESS(status)) {
3645 hddLog(VOS_TRACE_LEVEL_ERROR,
3646 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303647 return -EINVAL;
3648 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303649
3650 rc = wait_for_completion_timeout(&context->response_event,
3651 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3652 if (!rc) {
3653 hddLog(LOGE, FL("Target response timed out"));
3654 retval = -ETIMEDOUT;
3655 spin_lock(&hdd_context_lock);
3656 context->ignore_cached_results = true;
3657 spin_unlock(&hdd_context_lock);
3658 } else {
3659 spin_lock(&hdd_context_lock);
3660 retval = context->response_status;
3661 spin_unlock(&hdd_context_lock);
3662 }
3663
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303664 EXIT();
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303665 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303666
3667failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303668 return -EINVAL;
3669}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303670static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3671 struct wireless_dev *wdev,
3672 const void *data, int dataLen)
3673{
3674 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303675
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303676 vos_ssr_protect(__func__);
3677 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
3678 vos_ssr_unprotect(__func__);
3679
3680 return ret;
3681}
3682
3683static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303684 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05303685 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303686{
3687 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3688 struct net_device *dev = wdev->netdev;
3689 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3690 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3691 struct nlattr
3692 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3693 struct nlattr
3694 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3695 struct nlattr *apTh;
3696 eHalStatus status;
3697 tANI_U8 i = 0;
3698 int rem;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303699 struct hdd_ext_scan_context *context;
3700 tANI_U32 request_id;
3701 unsigned long rc;
3702 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303703
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303704 ENTER();
3705
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303706 if (VOS_FTM_MODE == hdd_get_conparam()) {
3707 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3708 return -EINVAL;
3709 }
3710
Dino Mycle6fb96c12014-06-10 11:52:40 +05303711 status = wlan_hdd_validate_context(pHddCtx);
3712 if (0 != status)
3713 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303714 return -EINVAL;
3715 }
Dino Myclee8843b32014-07-04 14:21:45 +05303716 /* check the EXTScan Capability */
3717 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303718 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3719 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303720 {
3721 hddLog(VOS_TRACE_LEVEL_ERROR,
3722 FL("EXTScan not enabled/supported by Firmware"));
3723 return -EINVAL;
3724 }
3725
Dino Mycle6fb96c12014-06-10 11:52:40 +05303726 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3727 data, dataLen,
3728 wlan_hdd_extscan_config_policy)) {
3729 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3730 return -EINVAL;
3731 }
3732
3733 /* Parse and fetch request Id */
3734 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3735 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3736 return -EINVAL;
3737 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303738 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3739 vos_mem_malloc(sizeof(*pReqMsg));
3740 if (!pReqMsg) {
3741 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3742 return -ENOMEM;
3743 }
3744
Dino Myclee8843b32014-07-04 14:21:45 +05303745
Dino Mycle6fb96c12014-06-10 11:52:40 +05303746 pReqMsg->requestId = nla_get_u32(
3747 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3748 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3749
3750 /* Parse and fetch number of APs */
3751 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3752 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3753 goto fail;
3754 }
3755
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303756 /* Parse and fetch lost ap sample size */
3757 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]) {
3758 hddLog(LOGE, FL("attr lost ap sample size failed"));
3759 goto fail;
3760 }
3761
3762 pReqMsg->lostBssidSampleSize = nla_get_u32(
3763 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]);
3764 hddLog(LOG1, FL("Lost ap sample size %d"), pReqMsg->lostBssidSampleSize);
3765
Dino Mycle6fb96c12014-06-10 11:52:40 +05303766 pReqMsg->sessionId = pAdapter->sessionId;
3767 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3768
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303769 pReqMsg->numBssid = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303770 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303771 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numBssid);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303772
3773 nla_for_each_nested(apTh,
3774 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3775 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3776 nla_data(apTh), nla_len(apTh),
3777 NULL)) {
3778 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3779 goto fail;
3780 }
3781
3782 /* Parse and fetch MAC address */
3783 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3784 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3785 goto fail;
3786 }
3787 memcpy(pReqMsg->ap[i].bssid, nla_data(
3788 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3789 sizeof(tSirMacAddr));
3790 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3791
3792 /* Parse and fetch low RSSI */
3793 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3794 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3795 goto fail;
3796 }
3797 pReqMsg->ap[i].low = nla_get_s32(
3798 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3799 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3800
3801 /* Parse and fetch high RSSI */
3802 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3803 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3804 goto fail;
3805 }
3806 pReqMsg->ap[i].high = nla_get_s32(
3807 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3808 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3809 pReqMsg->ap[i].high);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303810 i++;
3811 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303812
3813 context = &pHddCtx->ext_scan_context;
3814 spin_lock(&hdd_context_lock);
3815 INIT_COMPLETION(context->response_event);
3816 context->request_id = request_id = pReqMsg->requestId;
3817 spin_unlock(&hdd_context_lock);
3818
Dino Mycle6fb96c12014-06-10 11:52:40 +05303819 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3820 if (!HAL_STATUS_SUCCESS(status)) {
3821 hddLog(VOS_TRACE_LEVEL_ERROR,
3822 FL("sme_SetBssHotlist failed(err=%d)"), status);
3823 vos_mem_free(pReqMsg);
3824 return -EINVAL;
3825 }
3826
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303827 /* request was sent -- wait for the response */
3828 rc = wait_for_completion_timeout(&context->response_event,
3829 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3830
3831 if (!rc) {
3832 hddLog(LOGE, FL("sme_SetBssHotlist timed out"));
3833 retval = -ETIMEDOUT;
3834 } else {
3835 spin_lock(&hdd_context_lock);
3836 if (context->request_id == request_id)
3837 retval = context->response_status;
3838 else
3839 retval = -EINVAL;
3840 spin_unlock(&hdd_context_lock);
3841 }
3842
Dino Myclee8843b32014-07-04 14:21:45 +05303843 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303844 EXIT();
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303845 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303846
3847fail:
3848 vos_mem_free(pReqMsg);
3849 return -EINVAL;
3850}
3851
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303852static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3853 struct wireless_dev *wdev,
3854 const void *data, int dataLen)
3855{
3856 int ret = 0;
3857
3858 vos_ssr_protect(__func__);
3859 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
3860 dataLen);
3861 vos_ssr_unprotect(__func__);
3862
3863 return ret;
3864}
3865
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303866/*
3867 * define short names for the global vendor params
3868 * used by wlan_hdd_cfg80211_extscan_set_ssid_hotlist()
3869 */
3870#define PARAM_MAX \
3871QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
3872#define PARAM_REQUEST_ID \
3873QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
3874#define PARAMS_LOST_SSID_SAMPLE_SIZE \
3875QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE
3876#define PARAMS_NUM_SSID \
3877QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID
3878#define THRESHOLD_PARAM \
3879QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM
3880#define PARAM_SSID \
3881QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID
3882#define PARAM_BAND \
3883QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND
3884#define PARAM_RSSI_LOW \
3885QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW
3886#define PARAM_RSSI_HIGH \
3887QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH
3888
3889/**
3890 * __wlan_hdd_cfg80211_extscan_set_ssid_hotlist() - set ssid hot list
3891 * @wiphy: Pointer to wireless phy
3892 * @wdev: Pointer to wireless device
3893 * @data: Pointer to data
3894 * @data_len: Data length
3895 *
3896 * Return: 0 on success, negative errno on failure
3897 */
3898static int
3899__wlan_hdd_cfg80211_extscan_set_ssid_hotlist(struct wiphy *wiphy,
3900 struct wireless_dev *wdev,
3901 const void *data,
3902 int data_len)
3903{
3904 tSirEXTScanSetSsidHotListReqParams *request;
3905 struct net_device *dev = wdev->netdev;
3906 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
3907 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
3908 struct nlattr *tb[PARAM_MAX + 1];
3909 struct nlattr *tb2[PARAM_MAX + 1];
3910 struct nlattr *ssids;
3911 struct hdd_ext_scan_context *context;
3912 uint32_t request_id;
3913 char ssid_string[SIR_MAC_MAX_SSID_LENGTH + 1] = {'\0'};
3914 int ssid_len;
Anurag Chouhand64d5232016-08-29 17:01:38 +05303915 int ssid_length;
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303916 eHalStatus status;
3917 int i, rem, retval;
3918 unsigned long rc;
3919
3920 ENTER();
3921
3922 if (VOS_FTM_MODE == hdd_get_conparam()) {
3923 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3924 return -EINVAL;
3925 }
3926
3927 retval = wlan_hdd_validate_context(hdd_ctx);
3928 if (0 != retval) {
3929 hddLog(LOGE, FL("HDD context is not valid"));
3930 return -EINVAL;
3931 }
3932
3933 /* check the EXTScan Capability */
3934 if ( (TRUE != hdd_ctx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303935 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3936 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303937 {
3938 hddLog(VOS_TRACE_LEVEL_ERROR,
3939 FL("EXTScan not enabled/supported by Firmware"));
3940 return -EINVAL;
3941 }
3942
3943 if (nla_parse(tb, PARAM_MAX,
3944 data, data_len,
3945 wlan_hdd_extscan_config_policy)) {
3946 hddLog(LOGE, FL("Invalid ATTR"));
3947 return -EINVAL;
3948 }
3949
3950 request = vos_mem_malloc(sizeof(*request));
3951 if (!request) {
3952 hddLog(LOGE, FL("vos_mem_malloc failed"));
3953 return -ENOMEM;
3954 }
3955
3956 /* Parse and fetch request Id */
3957 if (!tb[PARAM_REQUEST_ID]) {
3958 hddLog(LOGE, FL("attr request id failed"));
3959 goto fail;
3960 }
3961
3962 request->request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
3963 hddLog(LOG1, FL("Request Id %d"), request->request_id);
3964
3965 /* Parse and fetch lost SSID sample size */
3966 if (!tb[PARAMS_LOST_SSID_SAMPLE_SIZE]) {
3967 hddLog(LOGE, FL("attr number of Ssid failed"));
3968 goto fail;
3969 }
3970 request->lost_ssid_sample_size =
3971 nla_get_u32(tb[PARAMS_LOST_SSID_SAMPLE_SIZE]);
3972 hddLog(LOG1, FL("Lost SSID Sample Size %d"),
3973 request->lost_ssid_sample_size);
3974
3975 /* Parse and fetch number of hotlist SSID */
3976 if (!tb[PARAMS_NUM_SSID]) {
3977 hddLog(LOGE, FL("attr number of Ssid failed"));
3978 goto fail;
3979 }
3980 request->ssid_count = nla_get_u32(tb[PARAMS_NUM_SSID]);
3981 hddLog(LOG1, FL("Number of SSID %d"), request->ssid_count);
3982
3983 request->session_id = adapter->sessionId;
3984 hddLog(LOG1, FL("Session Id (%d)"), request->session_id);
3985
3986 i = 0;
3987 nla_for_each_nested(ssids, tb[THRESHOLD_PARAM], rem) {
3988 if (i >= WLAN_EXTSCAN_MAX_HOTLIST_SSIDS) {
3989 hddLog(LOGE,
3990 FL("Too Many SSIDs, %d exceeds %d"),
3991 i, WLAN_EXTSCAN_MAX_HOTLIST_SSIDS);
3992 break;
3993 }
3994 if (nla_parse(tb2, PARAM_MAX,
3995 nla_data(ssids), nla_len(ssids),
3996 wlan_hdd_extscan_config_policy)) {
3997 hddLog(LOGE, FL("nla_parse failed"));
3998 goto fail;
3999 }
4000
4001 /* Parse and fetch SSID */
4002 if (!tb2[PARAM_SSID]) {
4003 hddLog(LOGE, FL("attr ssid failed"));
4004 goto fail;
4005 }
Anurag Chouhand64d5232016-08-29 17:01:38 +05304006 ssid_length = nla_strlcpy(ssid_string, tb2[PARAM_SSID],
4007 sizeof(ssid_string));
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05304008 hddLog(LOG1, FL("SSID %s"),
4009 ssid_string);
4010 ssid_len = strlen(ssid_string);
SaidiReddy Yenugae4f6f372016-12-06 16:11:39 +05304011 if (ssid_length >= SIR_MAC_MAX_SSID_LENGTH) {
Anurag Chouhand64d5232016-08-29 17:01:38 +05304012 hddLog(LOGE, FL("Invalid ssid length"));
4013 goto fail;
4014 }
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05304015 memcpy(request->ssid[i].ssid.ssId, ssid_string, ssid_len);
4016 request->ssid[i].ssid.length = ssid_len;
4017 request->ssid[i].ssid.ssId[ssid_len] = '\0';
4018 hddLog(LOG1, FL("After copying SSID %s"),
4019 request->ssid[i].ssid.ssId);
4020 hddLog(LOG1, FL("After copying length: %d"),
4021 ssid_len);
4022
4023 /* Parse and fetch low RSSI */
4024 if (!tb2[PARAM_BAND]) {
4025 hddLog(LOGE, FL("attr band failed"));
4026 goto fail;
4027 }
4028 request->ssid[i].band = nla_get_u8(tb2[PARAM_BAND]);
4029 hddLog(LOG1, FL("band %d"), request->ssid[i].band);
4030
4031 /* Parse and fetch low RSSI */
4032 if (!tb2[PARAM_RSSI_LOW]) {
4033 hddLog(LOGE, FL("attr low RSSI failed"));
4034 goto fail;
4035 }
4036 request->ssid[i].rssi_low = nla_get_s32(tb2[PARAM_RSSI_LOW]);
4037 hddLog(LOG1, FL("RSSI low %d"), request->ssid[i].rssi_low);
4038
4039 /* Parse and fetch high RSSI */
4040 if (!tb2[PARAM_RSSI_HIGH]) {
4041 hddLog(LOGE, FL("attr high RSSI failed"));
4042 goto fail;
4043 }
4044 request->ssid[i].rssi_high = nla_get_u32(tb2[PARAM_RSSI_HIGH]);
4045 hddLog(LOG1, FL("RSSI high %d"), request->ssid[i].rssi_high);
4046 i++;
4047 }
4048
4049 context = &hdd_ctx->ext_scan_context;
4050 spin_lock(&hdd_context_lock);
4051 INIT_COMPLETION(context->response_event);
4052 context->request_id = request_id = request->request_id;
4053 spin_unlock(&hdd_context_lock);
4054
4055 status = sme_set_ssid_hotlist(hdd_ctx->hHal, request);
4056 if (!HAL_STATUS_SUCCESS(status)) {
4057 hddLog(LOGE,
4058 FL("sme_set_ssid_hotlist failed(err=%d)"), status);
4059 goto fail;
4060 }
4061
4062 vos_mem_free(request);
4063
4064 /* request was sent -- wait for the response */
4065 rc = wait_for_completion_timeout(&context->response_event,
4066 msecs_to_jiffies
4067 (WLAN_WAIT_TIME_EXTSCAN));
4068 if (!rc) {
4069 hddLog(LOGE, FL("sme_set_ssid_hotlist timed out"));
4070 retval = -ETIMEDOUT;
4071 } else {
4072 spin_lock(&hdd_context_lock);
4073 if (context->request_id == request_id)
4074 retval = context->response_status;
4075 else
4076 retval = -EINVAL;
4077 spin_unlock(&hdd_context_lock);
4078 }
4079
4080 return retval;
4081
4082fail:
4083 vos_mem_free(request);
4084 return -EINVAL;
4085}
4086
4087/*
4088 * done with short names for the global vendor params
4089 * used by wlan_hdd_cfg80211_extscan_set_ssid_hotlist()
4090 */
4091#undef PARAM_MAX
4092#undef PARAM_REQUEST_ID
4093#undef PARAMS_NUM_SSID
4094#undef THRESHOLD_PARAM
4095#undef PARAM_SSID
4096#undef PARAM_BAND
4097#undef PARAM_RSSI_LOW
4098#undef PARAM_RSSI_HIGH
4099
4100static int wlan_hdd_cfg80211_extscan_set_ssid_hotlist(struct wiphy *wiphy,
4101 struct wireless_dev *wdev,
4102 const void *data, int dataLen)
4103{
4104 int ret = 0;
4105
4106 vos_ssr_protect(__func__);
4107 ret = __wlan_hdd_cfg80211_extscan_set_ssid_hotlist(wiphy, wdev, data,
4108 dataLen);
4109 vos_ssr_unprotect(__func__);
4110
4111 return ret;
4112}
4113
4114static int
4115__wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(struct wiphy *wiphy,
4116 struct wireless_dev *wdev,
4117 const void *data,
4118 int data_len)
4119{
4120 tSirEXTScanResetSsidHotlistReqParams request;
4121 struct net_device *dev = wdev->netdev;
4122 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
4123 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
4124 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4125 struct hdd_ext_scan_context *context;
4126 uint32_t request_id;
4127 eHalStatus status;
4128 int retval;
4129 unsigned long rc;
4130
4131 ENTER();
4132
4133 if (VOS_FTM_MODE == hdd_get_conparam()) {
4134 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4135 return -EINVAL;
4136 }
4137
4138 retval = wlan_hdd_validate_context(hdd_ctx);
4139 if (0 != retval) {
4140 hddLog(LOGE, FL("HDD context is not valid"));
4141 return -EINVAL;
4142 }
4143
4144 /* check the EXTScan Capability */
4145 if ( (TRUE != hdd_ctx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304146 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4147 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05304148 {
4149 hddLog(LOGE,
4150 FL("EXTScan not enabled/supported by Firmware"));
4151 return -EINVAL;
4152 }
4153
4154 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4155 data, data_len,
4156 wlan_hdd_extscan_config_policy)) {
4157 hddLog(LOGE, FL("Invalid ATTR"));
4158 return -EINVAL;
4159 }
4160
4161 /* Parse and fetch request Id */
4162 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4163 hddLog(LOGE, FL("attr request id failed"));
4164 return -EINVAL;
4165 }
4166
4167 request.requestId = nla_get_u32(
4168 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4169 request.sessionId = adapter->sessionId;
4170 hddLog(LOG1, FL("Request Id %d Session Id %d"), request.requestId,
4171 request.sessionId);
4172
4173 context = &hdd_ctx->ext_scan_context;
4174 spin_lock(&hdd_context_lock);
4175 INIT_COMPLETION(context->response_event);
4176 context->request_id = request_id = request.requestId;
4177 spin_unlock(&hdd_context_lock);
4178
4179 status = sme_reset_ssid_hotlist(hdd_ctx->hHal, &request);
4180 if (!HAL_STATUS_SUCCESS(status)) {
4181 hddLog(LOGE,
4182 FL("sme_reset_ssid_hotlist failed(err=%d)"), status);
4183 return -EINVAL;
4184 }
4185
4186 /* request was sent -- wait for the response */
4187 rc = wait_for_completion_timeout(&context->response_event,
4188 msecs_to_jiffies
4189 (WLAN_WAIT_TIME_EXTSCAN));
4190 if (!rc) {
4191 hddLog(LOGE, FL("sme_reset_ssid_hotlist timed out"));
4192 retval = -ETIMEDOUT;
4193 } else {
4194 spin_lock(&hdd_context_lock);
4195 if (context->request_id == request_id)
4196 retval = context->response_status;
4197 else
4198 retval = -EINVAL;
4199 spin_unlock(&hdd_context_lock);
4200 }
4201
4202 return retval;
4203}
4204
4205static int
4206wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(struct wiphy *wiphy,
4207 struct wireless_dev *wdev,
4208 const void *data,
4209 int data_len)
4210{
4211 int ret;
4212
4213 vos_ssr_protect(__func__);
4214 ret = __wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(wiphy, wdev,
4215 data, data_len);
4216 vos_ssr_unprotect(__func__);
4217
4218 return ret;
4219}
4220
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304221static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304222 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304223 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304224{
Agrawal Ashish16abf782016-08-18 22:42:59 +05304225 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4226 struct net_device *dev = wdev->netdev;
4227 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4228 uint32_t chan_list[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4229 uint8_t num_channels = 0;
4230 uint8_t num_chan_new = 0;
4231 uint8_t buf[256] = {0};
Dino Mycle6fb96c12014-06-10 11:52:40 +05304232 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304233 tANI_U32 requestId, maxChannels;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304234 tWifiBand wifiBand;
4235 eHalStatus status;
4236 struct sk_buff *replySkb;
Agrawal Ashish16abf782016-08-18 22:42:59 +05304237 tANI_U8 i,j,k;
4238 int ret,len = 0;;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304239
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304240 ENTER();
4241
Dino Mycle6fb96c12014-06-10 11:52:40 +05304242 status = wlan_hdd_validate_context(pHddCtx);
4243 if (0 != status)
4244 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304245 return -EINVAL;
4246 }
Dino Myclee8843b32014-07-04 14:21:45 +05304247
Dino Mycle6fb96c12014-06-10 11:52:40 +05304248 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4249 data, dataLen,
4250 wlan_hdd_extscan_config_policy)) {
4251 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4252 return -EINVAL;
4253 }
4254
4255 /* Parse and fetch request Id */
4256 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4257 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4258 return -EINVAL;
4259 }
4260 requestId = nla_get_u32(
4261 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4262 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
4263
4264 /* Parse and fetch wifi band */
4265 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
4266 {
4267 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4268 return -EINVAL;
4269 }
4270 wifiBand = nla_get_u32(
4271 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
4272 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
4273
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304274 /* Parse and fetch max channels */
4275 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
4276 {
4277 hddLog(LOGE, FL("attr max channels failed"));
4278 return -EINVAL;
4279 }
4280 maxChannels = nla_get_u32(
4281 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
4282 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);
4283
Dino Mycle6fb96c12014-06-10 11:52:40 +05304284 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
Agrawal Ashish16abf782016-08-18 22:42:59 +05304285 wifiBand, chan_list,
4286 &num_channels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304287 if (eHAL_STATUS_SUCCESS != status) {
4288 hddLog(VOS_TRACE_LEVEL_ERROR,
4289 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
4290 return -EINVAL;
4291 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304292
Agrawal Ashish16abf782016-08-18 22:42:59 +05304293 num_channels = VOS_MIN(num_channels, maxChannels);
4294 num_chan_new = num_channels;
4295 /* remove the indoor only channels if iface is SAP */
4296 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
4297 {
4298 num_chan_new = 0;
4299 for (i = 0; i < num_channels; i++)
4300 for (j = 0; j < IEEE80211_NUM_BANDS; j++) {
4301 if (wiphy->bands[j] == NULL)
4302 continue;
4303 for (k = 0; k < wiphy->bands[j]->n_channels; k++) {
4304 if ((chan_list[i] ==
4305 wiphy->bands[j]->channels[k].center_freq) &&
4306 (!(wiphy->bands[j]->channels[k].flags &
4307 IEEE80211_CHAN_INDOOR_ONLY))) {
4308 chan_list[num_chan_new] = chan_list[i];
4309 num_chan_new++;
4310 }
4311 }
4312 }
4313 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304314
Agrawal Ashish16abf782016-08-18 22:42:59 +05304315 hddLog(LOG1, FL("Number of channels: %d"), num_chan_new);
4316 for (i = 0; i < num_chan_new; i++)
4317 len += scnprintf(buf + len, sizeof(buf) - len, "%u ", chan_list[i]);
4318 hddLog(LOG1, "Channels: %s", buf);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304319
4320 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
Agrawal Ashish16abf782016-08-18 22:42:59 +05304321 sizeof(u32) * num_chan_new +
Dino Mycle6fb96c12014-06-10 11:52:40 +05304322 NLMSG_HDRLEN);
4323
4324 if (!replySkb) {
4325 hddLog(VOS_TRACE_LEVEL_ERROR,
4326 FL("valid channels: buffer alloc fail"));
4327 return -EINVAL;
4328 }
4329 if (nla_put_u32(replySkb,
4330 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304331 num_chan_new) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05304332 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304333 sizeof(u32) * num_chan_new, chan_list)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304334
4335 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4336 kfree_skb(replySkb);
4337 return -EINVAL;
4338 }
4339
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304340 ret = cfg80211_vendor_cmd_reply(replySkb);
4341
4342 EXIT();
4343 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304344}
4345
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304346static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
4347 struct wireless_dev *wdev,
4348 const void *data, int dataLen)
4349{
4350 int ret = 0;
4351
4352 vos_ssr_protect(__func__);
4353 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
4354 dataLen);
4355 vos_ssr_unprotect(__func__);
4356
4357 return ret;
4358}
4359
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304360static int hdd_extscan_start_fill_bucket_channel_spec(
4361 hdd_context_t *pHddCtx,
4362 tpSirEXTScanStartReqParams pReqMsg,
4363 struct nlattr **tb)
4364{
4365 struct nlattr *bucket[
4366 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4367 struct nlattr *channel[
4368 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4369 struct nlattr *buckets;
4370 struct nlattr *channels;
4371 int rem1, rem2;
4372 eHalStatus status;
4373 tANI_U8 bktIndex, j, numChannels;
4374 tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4375 tANI_U32 passive_max_chn_time, active_max_chn_time;
4376
4377 bktIndex = 0;
4378
4379 nla_for_each_nested(buckets,
4380 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
4381 if (nla_parse(bucket,
4382 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4383 nla_data(buckets), nla_len(buckets), NULL)) {
4384 hddLog(LOGE, FL("nla_parse failed"));
4385 return -EINVAL;
4386 }
4387
4388 /* Parse and fetch bucket spec */
4389 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4390 hddLog(LOGE, FL("attr bucket index failed"));
4391 return -EINVAL;
4392 }
4393 pReqMsg->buckets[bktIndex].bucket = nla_get_u8(
4394 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4395 hddLog(LOG1, FL("Bucket spec Index %d"),
4396 pReqMsg->buckets[bktIndex].bucket);
4397
4398 /* Parse and fetch wifi band */
4399 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4400 hddLog(LOGE, FL("attr wifi band failed"));
4401 return -EINVAL;
4402 }
4403 pReqMsg->buckets[bktIndex].band = nla_get_u8(
4404 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4405 hddLog(LOG1, FL("Wifi band %d"),
4406 pReqMsg->buckets[bktIndex].band);
4407
4408 /* Parse and fetch period */
4409 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4410 hddLog(LOGE, FL("attr period failed"));
4411 return -EINVAL;
4412 }
4413 pReqMsg->buckets[bktIndex].period = nla_get_u32(
4414 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4415 hddLog(LOG1, FL("period %d"),
4416 pReqMsg->buckets[bktIndex].period);
4417
4418 /* Parse and fetch report events */
4419 if (!bucket[
4420 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4421 hddLog(LOGE, FL("attr report events failed"));
4422 return -EINVAL;
4423 }
4424 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
4425 bucket[
4426 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4427 hddLog(LOG1, FL("report events %d"),
4428 pReqMsg->buckets[bktIndex].reportEvents);
4429
4430 /* Parse and fetch max period */
4431 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
4432 hddLog(LOGE, FL("attr max period failed"));
4433 return -EINVAL;
4434 }
4435 pReqMsg->buckets[bktIndex].max_period = nla_get_u32(
4436 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);
4437 hddLog(LOG1, FL("max period %u"),
4438 pReqMsg->buckets[bktIndex].max_period);
4439
4440 /* Parse and fetch exponent */
4441 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
4442 hddLog(LOGE, FL("attr exponent failed"));
4443 return -EINVAL;
4444 }
4445 pReqMsg->buckets[bktIndex].exponent = nla_get_u32(
4446 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
4447 hddLog(LOG1, FL("exponent %u"),
4448 pReqMsg->buckets[bktIndex].exponent);
4449
4450 /* Parse and fetch step count */
4451 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
4452 hddLog(LOGE, FL("attr step count failed"));
4453 return -EINVAL;
4454 }
4455 pReqMsg->buckets[bktIndex].step_count = nla_get_u32(
4456 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
4457 hddLog(LOG1, FL("Step count %u"),
4458 pReqMsg->buckets[bktIndex].step_count);
4459
4460 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time);
4461 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time);
4462
4463 /* Framework shall pass the channel list if the input WiFi band is
4464 * WIFI_BAND_UNSPECIFIED.
4465 * If the input WiFi band is specified (any value other than
4466 * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
4467 */
4468 if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) {
4469 numChannels = 0;
4470 hddLog(LOG1, "WiFi band is specified, driver to fill channel list");
4471 status = sme_GetValidChannelsByBand(pHddCtx->hHal,
4472 pReqMsg->buckets[bktIndex].band,
4473 chanList, &numChannels);
4474 if (!HAL_STATUS_SUCCESS(status)) {
4475 hddLog(LOGE,
4476 FL("sme_GetValidChannelsByBand failed (err=%d)"),
4477 status);
4478 return -EINVAL;
4479 }
4480
4481 pReqMsg->buckets[bktIndex].numChannels =
4482 VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS);
4483 hddLog(LOG1, FL("Num channels %d"),
4484 pReqMsg->buckets[bktIndex].numChannels);
4485
4486 for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels;
4487 j++) {
4488 pReqMsg->buckets[bktIndex].channels[j].channel =
4489 chanList[j];
4490 pReqMsg->buckets[bktIndex].channels[j].
4491 chnlClass = 0;
4492 if (CSR_IS_CHANNEL_DFS(
4493 vos_freq_to_chan(chanList[j]))) {
4494 pReqMsg->buckets[bktIndex].channels[j].
4495 passive = 1;
4496 pReqMsg->buckets[bktIndex].channels[j].
4497 dwellTimeMs = passive_max_chn_time;
4498 } else {
4499 pReqMsg->buckets[bktIndex].channels[j].
4500 passive = 0;
4501 pReqMsg->buckets[bktIndex].channels[j].
4502 dwellTimeMs = active_max_chn_time;
4503 }
4504
4505 hddLog(LOG1,
4506 "Channel %u Passive %u Dwell time %u ms",
4507 pReqMsg->buckets[bktIndex].channels[j].channel,
4508 pReqMsg->buckets[bktIndex].channels[j].passive,
4509 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4510 }
4511
4512 bktIndex++;
4513 continue;
4514 }
4515
4516 /* Parse and fetch number of channels */
4517 if (!bucket[
4518 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
4519 hddLog(LOGE, FL("attr num channels failed"));
4520 return -EINVAL;
4521 }
4522
4523 pReqMsg->buckets[bktIndex].numChannels =
4524 nla_get_u32(bucket[
4525 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
4526 hddLog(LOG1, FL("num channels %d"),
4527 pReqMsg->buckets[bktIndex].numChannels);
4528
4529 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
4530 hddLog(LOGE, FL("attr channel spec failed"));
4531 return -EINVAL;
4532 }
4533
4534 j = 0;
4535 nla_for_each_nested(channels,
4536 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
4537 if (nla_parse(channel,
4538 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4539 nla_data(channels), nla_len(channels),
4540 wlan_hdd_extscan_config_policy)) {
4541 hddLog(LOGE, FL("nla_parse failed"));
4542 return -EINVAL;
4543 }
4544
4545 /* Parse and fetch channel */
4546 if (!channel[
4547 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
4548 hddLog(LOGE, FL("attr channel failed"));
4549 return -EINVAL;
4550 }
4551 pReqMsg->buckets[bktIndex].channels[j].channel =
4552 nla_get_u32(channel[
4553 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
4554 hddLog(LOG1, FL("channel %u"),
4555 pReqMsg->buckets[bktIndex].channels[j].channel);
4556
4557 /* Parse and fetch dwell time */
4558 if (!channel[
4559 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
4560 hddLog(LOGE, FL("attr dwelltime failed"));
4561 return -EINVAL;
4562 }
4563 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
4564 nla_get_u32(channel[
4565 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
4566
4567 hddLog(LOG1, FL("Dwell time (%u ms)"),
4568 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4569
4570
4571 /* Parse and fetch channel spec passive */
4572 if (!channel[
4573 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
4574 hddLog(LOGE,
4575 FL("attr channel spec passive failed"));
4576 return -EINVAL;
4577 }
4578 pReqMsg->buckets[bktIndex].channels[j].passive =
4579 nla_get_u8(channel[
4580 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
4581 hddLog(LOG1, FL("Chnl spec passive %u"),
4582 pReqMsg->buckets[bktIndex].channels[j].passive);
4583
4584 j++;
4585 }
4586
4587 bktIndex++;
4588 }
4589
4590 return 0;
4591}
4592
4593
4594/*
4595 * define short names for the global vendor params
4596 * used by wlan_hdd_cfg80211_extscan_start()
4597 */
4598#define PARAM_MAX \
4599QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
4600#define PARAM_REQUEST_ID \
4601QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
4602#define PARAM_BASE_PERIOD \
4603QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
4604#define PARAM_MAX_AP_PER_SCAN \
4605QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
4606#define PARAM_RPT_THRHLD_PERCENT \
4607QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
4608#define PARAM_RPT_THRHLD_NUM_SCANS \
4609QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
4610#define PARAM_NUM_BUCKETS \
4611QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
4612
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304613static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304614 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304615 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304616{
Dino Myclee8843b32014-07-04 14:21:45 +05304617 tpSirEXTScanStartReqParams pReqMsg = NULL;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304618 struct net_device *dev = wdev->netdev;
4619 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4620 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4621 struct nlattr *tb[PARAM_MAX + 1];
4622 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304623 eHalStatus status;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304624 tANI_U32 request_id;
4625 struct hdd_ext_scan_context *context;
4626 unsigned long rc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304627
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304628 ENTER();
4629
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304630 if (VOS_FTM_MODE == hdd_get_conparam()) {
4631 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4632 return -EINVAL;
4633 }
4634
Dino Mycle6fb96c12014-06-10 11:52:40 +05304635 status = wlan_hdd_validate_context(pHddCtx);
4636 if (0 != status)
4637 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304638 return -EINVAL;
4639 }
Dino Myclee8843b32014-07-04 14:21:45 +05304640 /* check the EXTScan Capability */
4641 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304642 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4643 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304644 {
4645 hddLog(VOS_TRACE_LEVEL_ERROR,
4646 FL("EXTScan not enabled/supported by Firmware"));
4647 return -EINVAL;
4648 }
4649
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304650 if (nla_parse(tb, PARAM_MAX,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304651 data, dataLen,
4652 wlan_hdd_extscan_config_policy)) {
4653 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4654 return -EINVAL;
4655 }
4656
4657 /* Parse and fetch request Id */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304658 if (!tb[PARAM_REQUEST_ID]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304659 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4660 return -EINVAL;
4661 }
4662
Dino Myclee8843b32014-07-04 14:21:45 +05304663 pReqMsg = (tpSirEXTScanStartReqParams)
4664 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304665 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05304666 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4667 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304668 }
4669
4670 pReqMsg->requestId = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304671 tb[PARAM_REQUEST_ID]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304672 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4673
4674 pReqMsg->sessionId = pAdapter->sessionId;
4675 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4676
4677 /* Parse and fetch base period */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304678 if (!tb[PARAM_BASE_PERIOD]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304679 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
4680 goto fail;
4681 }
4682 pReqMsg->basePeriod = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304683 tb[PARAM_BASE_PERIOD]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304684 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
4685 pReqMsg->basePeriod);
4686
4687 /* Parse and fetch max AP per scan */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304688 if (!tb[PARAM_MAX_AP_PER_SCAN]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304689 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
4690 goto fail;
4691 }
4692 pReqMsg->maxAPperScan = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304693 tb[PARAM_MAX_AP_PER_SCAN]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304694 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
4695 pReqMsg->maxAPperScan);
4696
4697 /* Parse and fetch report threshold */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304698 if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304699 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
4700 goto fail;
4701 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304702 pReqMsg->reportThresholdPercent = nla_get_u8(
4703 tb[PARAM_RPT_THRHLD_PERCENT]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304704 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304705 pReqMsg->reportThresholdPercent);
4706
4707 /* Parse and fetch report threshold num scans */
4708 if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
4709 hddLog(LOGE, FL("attr report_threshold num scans failed"));
4710 goto fail;
4711 }
4712 pReqMsg->reportThresholdNumScans = nla_get_u8(
4713 tb[PARAM_RPT_THRHLD_NUM_SCANS]);
4714 hddLog(LOG1, FL("Report Threshold num scans %d"),
4715 pReqMsg->reportThresholdNumScans);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304716
4717 /* Parse and fetch number of buckets */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304718 if (!tb[PARAM_NUM_BUCKETS]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304719 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
4720 goto fail;
4721 }
4722 pReqMsg->numBuckets = nla_get_u8(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304723 tb[PARAM_NUM_BUCKETS]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304724 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
4725 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
4726 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
4727 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
4728 }
4729 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
4730 pReqMsg->numBuckets);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304731
Dino Mycle6fb96c12014-06-10 11:52:40 +05304732 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
4733 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
4734 goto fail;
4735 }
4736
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304737 pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304738
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304739 if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
4740 goto fail;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304741
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304742 context = &pHddCtx->ext_scan_context;
4743 spin_lock(&hdd_context_lock);
4744 INIT_COMPLETION(context->response_event);
4745 context->request_id = request_id = pReqMsg->requestId;
4746 spin_unlock(&hdd_context_lock);
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304747
Dino Mycle6fb96c12014-06-10 11:52:40 +05304748 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
4749 if (!HAL_STATUS_SUCCESS(status)) {
4750 hddLog(VOS_TRACE_LEVEL_ERROR,
4751 FL("sme_EXTScanStart failed(err=%d)"), status);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304752 goto fail;
4753 }
4754
Srinivas Dasari91727c12016-03-23 17:59:06 +05304755 pHddCtx->extscan_start_time_since_boot = vos_get_monotonic_boottime();
4756
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304757 /* request was sent -- wait for the response */
4758 rc = wait_for_completion_timeout(&context->response_event,
4759 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4760
4761 if (!rc) {
4762 hddLog(LOGE, FL("sme_ExtScanStart timed out"));
4763 retval = -ETIMEDOUT;
4764 } else {
4765 spin_lock(&hdd_context_lock);
4766 if (context->request_id == request_id)
4767 retval = context->response_status;
4768 else
4769 retval = -EINVAL;
4770 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304771 }
4772
Dino Myclee8843b32014-07-04 14:21:45 +05304773 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304774 EXIT();
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304775 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304776
4777fail:
4778 vos_mem_free(pReqMsg);
4779 return -EINVAL;
4780}
4781
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304782/*
4783 * done with short names for the global vendor params
4784 * used by wlan_hdd_cfg80211_extscan_start()
4785 */
4786#undef PARAM_MAX
4787#undef PARAM_REQUEST_ID
4788#undef PARAM_BASE_PERIOD
4789#undef PARAMS_MAX_AP_PER_SCAN
4790#undef PARAMS_RPT_THRHLD_PERCENT
4791#undef PARAMS_RPT_THRHLD_NUM_SCANS
4792#undef PARAMS_NUM_BUCKETS
4793
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304794static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
4795 struct wireless_dev *wdev,
4796 const void *data, int dataLen)
4797{
4798 int ret = 0;
4799
4800 vos_ssr_protect(__func__);
4801 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
4802 vos_ssr_unprotect(__func__);
4803
4804 return ret;
4805}
4806
4807static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304808 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304809 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304810{
Dino Myclee8843b32014-07-04 14:21:45 +05304811 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304812 struct net_device *dev = wdev->netdev;
4813 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4814 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4815 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4816 eHalStatus status;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304817 int retval;
4818 unsigned long rc;
4819 struct hdd_ext_scan_context *context;
4820 tANI_U32 request_id;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304821
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304822 ENTER();
4823
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304824 if (VOS_FTM_MODE == hdd_get_conparam()) {
4825 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4826 return -EINVAL;
4827 }
4828
Dino Mycle6fb96c12014-06-10 11:52:40 +05304829 status = wlan_hdd_validate_context(pHddCtx);
4830 if (0 != status)
4831 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304832 return -EINVAL;
4833 }
Dino Myclee8843b32014-07-04 14:21:45 +05304834 /* check the EXTScan Capability */
4835 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304836 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4837 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304838 {
4839 hddLog(VOS_TRACE_LEVEL_ERROR,
4840 FL("EXTScan not enabled/supported by Firmware"));
4841 return -EINVAL;
4842 }
4843
Dino Mycle6fb96c12014-06-10 11:52:40 +05304844 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4845 data, dataLen,
4846 wlan_hdd_extscan_config_policy)) {
4847 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4848 return -EINVAL;
4849 }
4850
4851 /* Parse and fetch request Id */
4852 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4853 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4854 return -EINVAL;
4855 }
4856
Dino Myclee8843b32014-07-04 14:21:45 +05304857 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304858 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304859 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304860
Dino Myclee8843b32014-07-04 14:21:45 +05304861 reqMsg.sessionId = pAdapter->sessionId;
4862 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304863
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304864 context = &pHddCtx->ext_scan_context;
4865 spin_lock(&hdd_context_lock);
4866 INIT_COMPLETION(context->response_event);
Sravanti Palakonda7539fb92016-02-26 17:49:21 +05304867 context->request_id = request_id = reqMsg.requestId;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304868 spin_unlock(&hdd_context_lock);
4869
Dino Myclee8843b32014-07-04 14:21:45 +05304870 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304871 if (!HAL_STATUS_SUCCESS(status)) {
4872 hddLog(VOS_TRACE_LEVEL_ERROR,
4873 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304874 return -EINVAL;
4875 }
4876
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304877 /* request was sent -- wait for the response */
4878 rc = wait_for_completion_timeout(&context->response_event,
4879 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4880
4881 if (!rc) {
4882 hddLog(LOGE, FL("sme_ExtScanStop timed out"));
4883 retval = -ETIMEDOUT;
4884 } else {
4885 spin_lock(&hdd_context_lock);
4886 if (context->request_id == request_id)
4887 retval = context->response_status;
4888 else
4889 retval = -EINVAL;
4890 spin_unlock(&hdd_context_lock);
4891 }
4892
4893 return retval;
4894
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304895 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304896 return 0;
4897}
4898
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304899static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
4900 struct wireless_dev *wdev,
4901 const void *data, int dataLen)
4902{
4903 int ret = 0;
4904
4905 vos_ssr_protect(__func__);
4906 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
4907 vos_ssr_unprotect(__func__);
4908
4909 return ret;
4910}
4911
4912static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304913 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304914 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304915{
Dino Myclee8843b32014-07-04 14:21:45 +05304916 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304917 struct net_device *dev = wdev->netdev;
4918 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4919 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4920 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4921 eHalStatus status;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304922 struct hdd_ext_scan_context *context;
4923 tANI_U32 request_id;
4924 unsigned long rc;
4925 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304926
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304927 ENTER();
4928
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304929 if (VOS_FTM_MODE == hdd_get_conparam()) {
4930 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4931 return -EINVAL;
4932 }
4933
Dino Mycle6fb96c12014-06-10 11:52:40 +05304934 status = wlan_hdd_validate_context(pHddCtx);
4935 if (0 != status)
4936 {
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304937 hddLog(LOGE, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304938 return -EINVAL;
4939 }
Dino Myclee8843b32014-07-04 14:21:45 +05304940 /* check the EXTScan Capability */
4941 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304942 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4943 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304944 {
4945 hddLog(VOS_TRACE_LEVEL_ERROR,
4946 FL("EXTScan not enabled/supported by Firmware"));
4947 return -EINVAL;
4948 }
4949
Dino Mycle6fb96c12014-06-10 11:52:40 +05304950 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4951 data, dataLen,
4952 wlan_hdd_extscan_config_policy)) {
4953 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4954 return -EINVAL;
4955 }
4956
4957 /* Parse and fetch request Id */
4958 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4959 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4960 return -EINVAL;
4961 }
4962
Dino Myclee8843b32014-07-04 14:21:45 +05304963 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304964 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304965 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304966
Dino Myclee8843b32014-07-04 14:21:45 +05304967 reqMsg.sessionId = pAdapter->sessionId;
4968 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304969
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304970 context = &pHddCtx->ext_scan_context;
4971 spin_lock(&hdd_context_lock);
4972 INIT_COMPLETION(context->response_event);
4973 context->request_id = request_id = reqMsg.requestId;
4974 spin_unlock(&hdd_context_lock);
4975
Dino Myclee8843b32014-07-04 14:21:45 +05304976 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304977 if (!HAL_STATUS_SUCCESS(status)) {
4978 hddLog(VOS_TRACE_LEVEL_ERROR,
4979 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304980 return -EINVAL;
4981 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304982
4983 /* request was sent -- wait for the response */
4984 rc = wait_for_completion_timeout(&context->response_event,
4985 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4986 if (!rc) {
4987 hddLog(LOGE, FL("sme_ResetBssHotlist timed out"));
4988 retval = -ETIMEDOUT;
4989 } else {
4990 spin_lock(&hdd_context_lock);
4991 if (context->request_id == request_id)
4992 retval = context->response_status;
4993 else
4994 retval = -EINVAL;
4995 spin_unlock(&hdd_context_lock);
4996 }
4997
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304998 EXIT();
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304999 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305000}
5001
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305002static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
5003 struct wireless_dev *wdev,
5004 const void *data, int dataLen)
5005{
5006 int ret = 0;
5007
5008 vos_ssr_protect(__func__);
5009 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
5010 vos_ssr_unprotect(__func__);
5011
5012 return ret;
5013}
Dino Mycle6fb96c12014-06-10 11:52:40 +05305014#endif /* WLAN_FEATURE_EXTSCAN */
5015
Atul Mittal115287b2014-07-08 13:26:33 +05305016/*EXT TDLS*/
5017static const struct nla_policy
5018wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
5019{
5020 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
5021 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
5022 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
5023 {.type = NLA_S32 },
5024 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
5025 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
5026
5027};
5028
5029static const struct nla_policy
5030wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
5031{
5032 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
5033
5034};
5035
5036static const struct nla_policy
5037wlan_hdd_tdls_config_state_change_policy[
5038 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
5039{
5040 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {.type = NLA_UNSPEC },
5041 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
5042 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305043 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
5044 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
5045 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305046
5047};
5048
5049static const struct nla_policy
5050wlan_hdd_tdls_config_get_status_policy[
5051 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
5052{
5053 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {.type = NLA_UNSPEC },
5054 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
5055 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305056 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
5057 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
5058 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305059
5060};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305061
5062static const struct nla_policy
5063wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
5064{
5065 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {.type = NLA_UNSPEC },
5066};
5067
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305068static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305069 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305070 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305071 int data_len)
5072{
5073
5074 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5075 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
5076
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305077 ENTER();
5078
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305079 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305080 return -EINVAL;
5081 }
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +05305082 if (0 == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05305083 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305084 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05305085 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305086 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05305087 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305088 return -ENOTSUPP;
5089 }
5090
5091 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
5092 data, data_len, wlan_hdd_mac_config)) {
5093 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5094 return -EINVAL;
5095 }
5096
5097 /* Parse and fetch mac address */
5098 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
5099 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5100 return -EINVAL;
5101 }
5102
5103 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
5104 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5105 VOS_MAC_ADDR_LAST_3_BYTES);
5106
Siddharth Bhal76972212014-10-15 16:22:51 +05305107 pHddCtx->spoofMacAddr.isEnabled = TRUE;
5108
5109 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305110 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5111 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05305112 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
5113 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
5114 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
5115 {
5116 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
5117 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
5118 VOS_MAC_ADDRESS_LEN);
5119 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305120 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305121
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +05305122 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
5123 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305124
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305125 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305126 return 0;
5127}
5128
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305129static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
5130 struct wireless_dev *wdev,
5131 const void *data,
5132 int data_len)
5133{
5134 int ret = 0;
5135
5136 vos_ssr_protect(__func__);
5137 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
5138 vos_ssr_unprotect(__func__);
5139
5140 return ret;
5141}
5142
5143static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305144 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305145 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305146 int data_len)
5147{
5148 u8 peer[6] = {0};
5149 struct net_device *dev = wdev->netdev;
5150 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5151 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5152 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
5153 eHalStatus ret;
5154 tANI_S32 state;
5155 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305156 tANI_S32 global_operating_class = 0;
5157 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05305158 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305159 int retVal;
5160
5161 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305162
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305163 if (!pAdapter) {
5164 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5165 return -EINVAL;
5166 }
5167
Atul Mittal115287b2014-07-08 13:26:33 +05305168 ret = wlan_hdd_validate_context(pHddCtx);
5169 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305170 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305171 return -EINVAL;
5172 }
5173 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305174 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305175 return -ENOTSUPP;
5176 }
5177 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
5178 data, data_len,
5179 wlan_hdd_tdls_config_get_status_policy)) {
5180 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5181 return -EINVAL;
5182 }
5183
5184 /* Parse and fetch mac address */
5185 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
5186 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5187 return -EINVAL;
5188 }
5189
5190 memcpy(peer, nla_data(
5191 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
5192 sizeof(peer));
5193 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5194
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05305195 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05305196
Atul Mittal115287b2014-07-08 13:26:33 +05305197 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305198 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05305199 NLMSG_HDRLEN);
5200
5201 if (!skb) {
5202 hddLog(VOS_TRACE_LEVEL_ERROR,
5203 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5204 return -EINVAL;
5205 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305206 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 +05305207 reason,
5208 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305209 global_operating_class,
5210 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05305211 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305212 if (nla_put_s32(skb,
5213 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
5214 state) ||
5215 nla_put_s32(skb,
5216 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
5217 reason) ||
5218 nla_put_s32(skb,
5219 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
5220 global_operating_class) ||
5221 nla_put_s32(skb,
5222 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
5223 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05305224
5225 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5226 goto nla_put_failure;
5227 }
5228
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305229 retVal = cfg80211_vendor_cmd_reply(skb);
5230 EXIT();
5231 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05305232
5233nla_put_failure:
5234 kfree_skb(skb);
5235 return -EINVAL;
5236}
5237
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305238static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
5239 struct wireless_dev *wdev,
5240 const void *data,
5241 int data_len)
5242{
5243 int ret = 0;
5244
5245 vos_ssr_protect(__func__);
5246 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
5247 vos_ssr_unprotect(__func__);
5248
5249 return ret;
5250}
5251
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05305252static int wlan_hdd_cfg80211_exttdls_callback(
5253#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
5254 const tANI_U8* mac,
5255#else
5256 tANI_U8* mac,
5257#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305258 tANI_S32 state,
5259 tANI_S32 reason,
5260 void *ctx)
5261{
5262 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05305263 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305264 tANI_S32 global_operating_class = 0;
5265 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305266 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05305267
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305268 ENTER();
5269
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305270 if (!pAdapter) {
5271 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5272 return -EINVAL;
5273 }
5274
5275 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05305276 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305277 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305278 return -EINVAL;
5279 }
5280
5281 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305282 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305283 return -ENOTSUPP;
5284 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05305285 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
5286#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
5287 NULL,
5288#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305289 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
5290 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
5291 GFP_KERNEL);
5292
5293 if (!skb) {
5294 hddLog(VOS_TRACE_LEVEL_ERROR,
5295 FL("cfg80211_vendor_event_alloc failed"));
5296 return -EINVAL;
5297 }
5298 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305299 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
5300 reason,
5301 state,
5302 global_operating_class,
5303 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05305304 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
5305 MAC_ADDR_ARRAY(mac));
5306
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305307 if (nla_put(skb,
5308 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
5309 VOS_MAC_ADDR_SIZE, mac) ||
5310 nla_put_s32(skb,
5311 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
5312 state) ||
5313 nla_put_s32(skb,
5314 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
5315 reason) ||
5316 nla_put_s32(skb,
5317 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
5318 channel) ||
5319 nla_put_s32(skb,
5320 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
5321 global_operating_class)
5322 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05305323 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5324 goto nla_put_failure;
5325 }
5326
5327 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305328 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05305329 return (0);
5330
5331nla_put_failure:
5332 kfree_skb(skb);
5333 return -EINVAL;
5334}
5335
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305336static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305337 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305338 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305339 int data_len)
5340{
5341 u8 peer[6] = {0};
5342 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305343 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5344 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
5345 eHalStatus status;
5346 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305347 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305348 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305349
5350 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305351
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305352 if (!dev) {
5353 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5354 return -EINVAL;
5355 }
5356
5357 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5358 if (!pAdapter) {
5359 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5360 return -EINVAL;
5361 }
5362
Atul Mittal115287b2014-07-08 13:26:33 +05305363 status = wlan_hdd_validate_context(pHddCtx);
5364 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305365 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305366 return -EINVAL;
5367 }
5368 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305369 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305370 return -ENOTSUPP;
5371 }
5372 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
5373 data, data_len,
5374 wlan_hdd_tdls_config_enable_policy)) {
5375 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5376 return -EINVAL;
5377 }
5378
5379 /* Parse and fetch mac address */
5380 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
5381 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5382 return -EINVAL;
5383 }
5384
5385 memcpy(peer, nla_data(
5386 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
5387 sizeof(peer));
5388 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5389
5390 /* Parse and fetch channel */
5391 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
5392 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
5393 return -EINVAL;
5394 }
5395 pReqMsg.channel = nla_get_s32(
5396 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
5397 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
5398
5399 /* Parse and fetch global operating class */
5400 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
5401 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
5402 return -EINVAL;
5403 }
5404 pReqMsg.global_operating_class = nla_get_s32(
5405 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
5406 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
5407 pReqMsg.global_operating_class);
5408
5409 /* Parse and fetch latency ms */
5410 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
5411 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
5412 return -EINVAL;
5413 }
5414 pReqMsg.max_latency_ms = nla_get_s32(
5415 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
5416 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
5417 pReqMsg.max_latency_ms);
5418
5419 /* Parse and fetch required bandwidth kbps */
5420 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
5421 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
5422 return -EINVAL;
5423 }
5424
5425 pReqMsg.min_bandwidth_kbps = nla_get_s32(
5426 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
5427 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
5428 pReqMsg.min_bandwidth_kbps);
5429
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305430 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05305431 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05305432 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305433 wlan_hdd_cfg80211_exttdls_callback);
5434
5435 EXIT();
5436 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305437}
5438
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305439static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
5440 struct wireless_dev *wdev,
5441 const void *data,
5442 int data_len)
5443{
5444 int ret = 0;
5445
5446 vos_ssr_protect(__func__);
5447 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
5448 vos_ssr_unprotect(__func__);
5449
5450 return ret;
5451}
5452
5453static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305454 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305455 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305456 int data_len)
5457{
5458 u8 peer[6] = {0};
5459 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305460 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5461 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
5462 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305463 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305464 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305465
5466 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305467
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305468 if (!dev) {
5469 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5470 return -EINVAL;
5471 }
5472
5473 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5474 if (!pAdapter) {
5475 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
5476 return -EINVAL;
5477 }
5478
Atul Mittal115287b2014-07-08 13:26:33 +05305479 status = wlan_hdd_validate_context(pHddCtx);
5480 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305481 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305482 return -EINVAL;
5483 }
5484 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305485 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305486 return -ENOTSUPP;
5487 }
5488 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
5489 data, data_len,
5490 wlan_hdd_tdls_config_disable_policy)) {
5491 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5492 return -EINVAL;
5493 }
5494 /* Parse and fetch mac address */
5495 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
5496 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5497 return -EINVAL;
5498 }
5499
5500 memcpy(peer, nla_data(
5501 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
5502 sizeof(peer));
5503 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5504
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305505 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
5506
5507 EXIT();
5508 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305509}
5510
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305511static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
5512 struct wireless_dev *wdev,
5513 const void *data,
5514 int data_len)
5515{
5516 int ret = 0;
5517
5518 vos_ssr_protect(__func__);
5519 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
5520 vos_ssr_unprotect(__func__);
5521
5522 return ret;
5523}
5524
Dasari Srinivas7875a302014-09-26 17:50:57 +05305525static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305526__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05305527 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305528 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05305529{
5530 struct net_device *dev = wdev->netdev;
5531 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5532 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5533 struct sk_buff *skb = NULL;
5534 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305535 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305536
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305537 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305538
5539 ret = wlan_hdd_validate_context(pHddCtx);
5540 if (0 != ret)
5541 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305542 return ret;
5543 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305544 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
5545 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
5546 fset |= WIFI_FEATURE_INFRA;
5547 }
5548
5549 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
5550 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
5551 fset |= WIFI_FEATURE_INFRA_5G;
5552 }
5553
5554#ifdef WLAN_FEATURE_P2P
5555 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
5556 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
5557 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
5558 fset |= WIFI_FEATURE_P2P;
5559 }
5560#endif
5561
5562 /* Soft-AP is supported currently by default */
5563 fset |= WIFI_FEATURE_SOFT_AP;
5564
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05305565 /* HOTSPOT is a supplicant feature, enable it by default */
5566 fset |= WIFI_FEATURE_HOTSPOT;
5567
Dasari Srinivas7875a302014-09-26 17:50:57 +05305568#ifdef WLAN_FEATURE_EXTSCAN
5569 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305570 sme_IsFeatureSupportedByFW(EXTENDED_SCAN) &&
5571 sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)) {
5572 hddLog(LOG1, FL("Enhanced EXTScan is supported by firmware"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05305573 fset |= WIFI_FEATURE_EXTSCAN;
5574 }
5575#endif
5576
Dasari Srinivas7875a302014-09-26 17:50:57 +05305577 if (sme_IsFeatureSupportedByFW(NAN)) {
5578 hddLog(LOG1, FL("NAN is supported by firmware"));
5579 fset |= WIFI_FEATURE_NAN;
5580 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305581
5582 /* D2D RTT is not supported currently by default */
5583 if (sme_IsFeatureSupportedByFW(RTT)) {
5584 hddLog(LOG1, FL("RTT is supported by firmware"));
5585 fset |= WIFI_FEATURE_D2AP_RTT;
5586 }
5587
Padma, Santhosh Kumaraac4c4d2015-12-08 16:07:47 +05305588 if (sme_IsFeatureSupportedByFW(RTT3)) {
5589 hddLog(LOG1, FL("RTT3 is supported by firmware"));
5590 fset |= WIFI_FEATURE_RTT3;
5591 }
5592
Dasari Srinivas7875a302014-09-26 17:50:57 +05305593#ifdef FEATURE_WLAN_BATCH_SCAN
5594 if (fset & WIFI_FEATURE_EXTSCAN) {
5595 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
5596 fset &= ~WIFI_FEATURE_BATCH_SCAN;
5597 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
5598 hddLog(LOG1, FL("Batch scan is supported by firmware"));
5599 fset |= WIFI_FEATURE_BATCH_SCAN;
5600 }
5601#endif
5602
5603#ifdef FEATURE_WLAN_SCAN_PNO
5604 if (pHddCtx->cfg_ini->configPNOScanSupport &&
5605 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
5606 hddLog(LOG1, FL("PNO is supported by firmware"));
5607 fset |= WIFI_FEATURE_PNO;
5608 }
5609#endif
5610
5611 /* STA+STA is supported currently by default */
5612 fset |= WIFI_FEATURE_ADDITIONAL_STA;
5613
5614#ifdef FEATURE_WLAN_TDLS
5615 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
5616 sme_IsFeatureSupportedByFW(TDLS)) {
5617 hddLog(LOG1, FL("TDLS is supported by firmware"));
5618 fset |= WIFI_FEATURE_TDLS;
5619 }
5620
5621 /* TDLS_OFFCHANNEL is not supported currently by default */
5622#endif
5623
5624#ifdef WLAN_AP_STA_CONCURRENCY
5625 /* AP+STA concurrency is supported currently by default */
5626 fset |= WIFI_FEATURE_AP_STA;
5627#endif
5628
Mukul Sharma5add0532015-08-17 15:57:47 +05305629#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5630 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
5631 hddLog(LOG1, FL("Link layer stats is supported by driver"));
5632#endif
5633
Dasari Srinivas7875a302014-09-26 17:50:57 +05305634 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
5635 NLMSG_HDRLEN);
5636
5637 if (!skb) {
5638 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5639 return -EINVAL;
5640 }
5641 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
5642
5643 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
5644 hddLog(LOGE, FL("nla put fail"));
5645 goto nla_put_failure;
5646 }
5647
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305648 ret = cfg80211_vendor_cmd_reply(skb);
5649 EXIT();
5650 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305651
5652nla_put_failure:
5653 kfree_skb(skb);
5654 return -EINVAL;
5655}
5656
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305657static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305658wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
5659 struct wireless_dev *wdev,
5660 const void *data, int data_len)
5661{
5662 int ret = 0;
5663
5664 vos_ssr_protect(__func__);
5665 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
5666 vos_ssr_unprotect(__func__);
5667
5668 return ret;
5669}
5670
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305671
5672static const struct
5673nla_policy
5674qca_wlan_vendor_wifi_logger_get_ring_data_policy
5675[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1] = {
5676 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]
5677 = {.type = NLA_U32 },
5678};
5679
5680static int
5681 __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
5682 struct wireless_dev *wdev,
5683 const void *data,
5684 int data_len)
5685{
5686 int ret;
5687 VOS_STATUS status;
5688 uint32_t ring_id;
5689 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5690 struct nlattr *tb
5691 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1];
5692
5693 ENTER();
5694
5695 ret = wlan_hdd_validate_context(hdd_ctx);
5696 if (0 != ret) {
5697 return ret;
5698 }
5699
5700 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX,
5701 data, data_len,
5702 qca_wlan_vendor_wifi_logger_get_ring_data_policy)) {
5703 hddLog(LOGE, FL("Invalid attribute"));
5704 return -EINVAL;
5705 }
5706
5707 /* Parse and fetch ring id */
5708 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]) {
5709 hddLog(LOGE, FL("attr ATTR failed"));
5710 return -EINVAL;
5711 }
5712
5713 ring_id = nla_get_u32(
5714 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]);
5715
5716 hddLog(LOG1, FL("Bug report triggered by framework"));
5717
5718 status = vos_fatal_event_logs_req(WLAN_LOG_TYPE_NON_FATAL,
5719 WLAN_LOG_INDICATOR_FRAMEWORK,
5720 WLAN_LOG_REASON_CODE_FRAMEWORK,
Abhishek Singh837adf22015-10-01 17:37:37 +05305721 TRUE, TRUE
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305722 );
5723 if (VOS_STATUS_SUCCESS != status) {
5724 hddLog(LOGE, FL("Failed to trigger bug report"));
5725
5726 return -EINVAL;
5727 }
5728
5729 return 0;
5730
5731
5732}
5733
5734
5735static int
5736 wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
5737 struct wireless_dev *wdev,
5738 const void *data,
5739 int data_len)
5740{
5741 int ret = 0;
5742
5743 vos_ssr_protect(__func__);
5744 ret = __wlan_hdd_cfg80211_wifi_logger_get_ring_data(wiphy,
5745 wdev, data, data_len);
5746 vos_ssr_unprotect(__func__);
5747
5748 return ret;
5749
5750}
5751
5752
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305753static int
5754__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305755 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305756 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305757{
5758 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
5759 uint8_t i, feature_sets, max_feature_sets;
5760 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX + 1];
5761 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305762 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5763 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305764
5765 ENTER();
5766
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305767 ret = wlan_hdd_validate_context(pHddCtx);
5768 if (0 != ret)
5769 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305770 return ret;
5771 }
5772
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305773 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX,
5774 data, data_len, NULL)) {
5775 hddLog(LOGE, FL("Invalid ATTR"));
5776 return -EINVAL;
5777 }
5778
5779 /* Parse and fetch max feature set */
5780 if (!tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
5781 hddLog(LOGE, FL("Attr max feature set size failed"));
5782 return -EINVAL;
5783 }
5784 max_feature_sets = nla_get_u32(
5785 tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
5786 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
5787
5788 /* Fill feature combination matrix */
5789 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305790 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5791 WIFI_FEATURE_P2P;
5792
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305793 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5794 WIFI_FEATURE_SOFT_AP;
5795
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305796 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
5797 WIFI_FEATURE_SOFT_AP;
5798
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305799 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5800 WIFI_FEATURE_SOFT_AP |
5801 WIFI_FEATURE_P2P;
5802
5803 /* Add more feature combinations here */
5804
5805 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
5806 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
5807 hddLog(LOG1, "Feature set matrix");
5808 for (i = 0; i < feature_sets; i++)
5809 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
5810
5811 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
5812 sizeof(u32) * feature_sets +
5813 NLMSG_HDRLEN);
5814
5815 if (reply_skb) {
5816 if (nla_put_u32(reply_skb,
5817 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
5818 feature_sets) ||
5819 nla_put(reply_skb,
5820 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
5821 sizeof(u32) * feature_sets, feature_set_matrix)) {
5822 hddLog(LOGE, FL("nla put fail"));
5823 kfree_skb(reply_skb);
5824 return -EINVAL;
5825 }
5826
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305827 ret = cfg80211_vendor_cmd_reply(reply_skb);
5828 EXIT();
5829 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305830 }
5831 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
5832 return -ENOMEM;
5833
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305834}
5835
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305836static int
5837wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
5838 struct wireless_dev *wdev,
5839 const void *data, int data_len)
5840{
5841 int ret = 0;
5842
5843 vos_ssr_protect(__func__);
5844 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
5845 data_len);
5846 vos_ssr_unprotect(__func__);
5847
5848 return ret;
5849}
5850
c_manjeecfd1efb2015-09-25 19:32:34 +05305851
5852static int
5853__wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5854 struct wireless_dev *wdev,
5855 const void *data, int data_len)
5856{
5857 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5858 int ret;
5859 ENTER();
5860
5861 ret = wlan_hdd_validate_context(pHddCtx);
5862 if (0 != ret)
5863 {
5864 return ret;
5865 }
5866
5867 if( !pHddCtx->cfg_ini->enableFwrMemDump ||
5868 (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
5869 {
5870 hddLog(VOS_TRACE_LEVEL_INFO, FL("FW dump Logging not supported"));
5871 return -EINVAL;
5872 }
5873 /*call common API for FW mem dump req*/
5874 ret = wlan_hdd_fw_mem_dump_req(pHddCtx);
5875
Abhishek Singhc783fa72015-12-09 18:07:34 +05305876 if (!ret)
c_manjee04b4c5c2015-10-13 18:35:01 +05305877 {
5878 /*indicate to userspace the status of fw mem dump */
5879 wlan_indicate_mem_dump_complete(true);
5880 }
5881 else
5882 {
5883 /*else send failure to userspace */
5884 wlan_indicate_mem_dump_complete(false);
5885 }
c_manjeecfd1efb2015-09-25 19:32:34 +05305886 EXIT();
5887 return ret;
5888}
5889
5890/**
5891 * wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump
5892 * @wiphy: pointer to wireless wiphy structure.
5893 * @wdev: pointer to wireless_dev structure.
5894 * @data: Pointer to the NL data.
5895 * @data_len:Length of @data
5896 *
5897 * This is called when wlan driver needs to get the firmware memory dump
5898 * via vendor specific command.
5899 *
5900 * Return: 0 on success, error number otherwise.
5901 */
5902
5903static int
5904wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5905 struct wireless_dev *wdev,
5906 const void *data, int data_len)
Sushant Kaushik8e644982015-09-23 12:18:54 +05305907{
5908 int ret = 0;
5909 vos_ssr_protect(__func__);
5910 ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data,
5911 data_len);
5912 vos_ssr_unprotect(__func__);
5913 return ret;
5914}
c_manjeecfd1efb2015-09-25 19:32:34 +05305915
Sushant Kaushik8e644982015-09-23 12:18:54 +05305916static const struct
5917nla_policy
5918qca_wlan_vendor_wifi_logger_start_policy
5919[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
5920 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
5921 = {.type = NLA_U32 },
5922 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
5923 = {.type = NLA_U32 },
5924 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
5925 = {.type = NLA_U32 },
5926};
5927
5928/**
5929 * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
5930 * or disable the collection of packet statistics from the firmware
5931 * @wiphy: WIPHY structure pointer
5932 * @wdev: Wireless device structure pointer
5933 * @data: Pointer to the data received
5934 * @data_len: Length of the data received
5935 *
5936 * This function is used to enable or disable the collection of packet
5937 * statistics from the firmware
5938 *
5939 * Return: 0 on success and errno on failure
5940 */
5941static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
5942 struct wireless_dev *wdev,
5943 const void *data,
5944 int data_len)
5945{
5946 eHalStatus status;
5947 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5948 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
5949 tAniWifiStartLog start_log;
5950
5951 status = wlan_hdd_validate_context(hdd_ctx);
5952 if (0 != status) {
5953 return -EINVAL;
5954 }
5955
5956 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
5957 data, data_len,
5958 qca_wlan_vendor_wifi_logger_start_policy)) {
5959 hddLog(LOGE, FL("Invalid attribute"));
5960 return -EINVAL;
5961 }
5962
5963 /* Parse and fetch ring id */
5964 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
5965 hddLog(LOGE, FL("attr ATTR failed"));
5966 return -EINVAL;
5967 }
5968 start_log.ringId = nla_get_u32(
5969 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
5970 hddLog(LOG1, FL("Ring ID=%d"), start_log.ringId);
5971
5972 /* Parse and fetch verbose level */
5973 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
5974 hddLog(LOGE, FL("attr verbose_level failed"));
5975 return -EINVAL;
5976 }
5977 start_log.verboseLevel = nla_get_u32(
5978 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
5979 hddLog(LOG1, FL("verbose_level=%d"), start_log.verboseLevel);
5980
5981 /* Parse and fetch flag */
5982 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
5983 hddLog(LOGE, FL("attr flag failed"));
5984 return -EINVAL;
5985 }
5986 start_log.flag = nla_get_u32(
5987 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
5988 hddLog(LOG1, FL("flag=%d"), start_log.flag);
5989
5990 if ((RING_ID_PER_PACKET_STATS == start_log.ringId) &&
Sushant Kaushik33200572015-08-05 16:46:20 +05305991 (!hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable ||
5992 !vos_isPktStatsEnabled()))
5993
Sushant Kaushik8e644982015-09-23 12:18:54 +05305994 {
5995 hddLog(LOGE, FL("per pkt stats not enabled"));
5996 return -EINVAL;
5997 }
Sushant Kaushik8e644982015-09-23 12:18:54 +05305998
Sushant Kaushik33200572015-08-05 16:46:20 +05305999 vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306000 return 0;
6001}
6002
6003/**
6004 * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
6005 * or disable the collection of packet statistics from the firmware
6006 * @wiphy: WIPHY structure pointer
6007 * @wdev: Wireless device structure pointer
6008 * @data: Pointer to the data received
6009 * @data_len: Length of the data received
6010 *
6011 * This function is used to enable or disable the collection of packet
6012 * statistics from the firmware
6013 *
6014 * Return: 0 on success and errno on failure
6015 */
6016static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6017 struct wireless_dev *wdev,
6018 const void *data,
6019 int data_len)
c_manjeecfd1efb2015-09-25 19:32:34 +05306020{
6021 int ret = 0;
6022
6023 vos_ssr_protect(__func__);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306024
6025 ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
6026 wdev, data, data_len);
c_manjeecfd1efb2015-09-25 19:32:34 +05306027 vos_ssr_unprotect(__func__);
6028
6029 return ret;
c_manjeecfd1efb2015-09-25 19:32:34 +05306030}
6031
6032
Agarwal Ashish738843c2014-09-25 12:27:56 +05306033static const struct nla_policy
6034wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
6035 +1] =
6036{
6037 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
6038};
6039
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306040static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306041 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306042 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306043 int data_len)
6044{
6045 struct net_device *dev = wdev->netdev;
6046 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6047 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6048 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6049 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
6050 eHalStatus status;
6051 u32 dfsFlag = 0;
6052
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306053 ENTER();
6054
Agarwal Ashish738843c2014-09-25 12:27:56 +05306055 status = wlan_hdd_validate_context(pHddCtx);
6056 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05306057 return -EINVAL;
6058 }
6059 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
6060 data, data_len,
6061 wlan_hdd_set_no_dfs_flag_config_policy)) {
6062 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6063 return -EINVAL;
6064 }
6065
6066 /* Parse and fetch required bandwidth kbps */
6067 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
6068 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
6069 return -EINVAL;
6070 }
6071
6072 dfsFlag = nla_get_u32(
6073 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
6074 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
6075 dfsFlag);
6076
6077 pHddCtx->disable_dfs_flag = dfsFlag;
6078
6079 sme_disable_dfs_channel(hHal, dfsFlag);
6080 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306081
6082 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05306083 return 0;
6084}
Atul Mittal115287b2014-07-08 13:26:33 +05306085
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306086static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
6087 struct wireless_dev *wdev,
6088 const void *data,
6089 int data_len)
6090{
6091 int ret = 0;
6092
6093 vos_ssr_protect(__func__);
6094 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
6095 vos_ssr_unprotect(__func__);
6096
6097 return ret;
6098
6099}
6100
Mukul Sharma2a271632014-10-13 14:59:01 +05306101const struct
6102nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
6103{
6104 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
6105 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
6106};
6107
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306108static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05306109 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05306110{
6111
6112 u8 bssid[6] = {0};
6113 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6114 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6115 eHalStatus status = eHAL_STATUS_SUCCESS;
6116 v_U32_t isFwrRoamEnabled = FALSE;
6117 int ret;
6118
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306119 ENTER();
6120
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306121 ret = wlan_hdd_validate_context(pHddCtx);
6122 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306123 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05306124 }
6125
6126 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
6127 data, data_len,
6128 qca_wlan_vendor_attr);
6129 if (ret){
6130 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6131 return -EINVAL;
6132 }
6133
6134 /* Parse and fetch Enable flag */
6135 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
6136 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
6137 return -EINVAL;
6138 }
6139
6140 isFwrRoamEnabled = nla_get_u32(
6141 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
6142
6143 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
6144
6145 /* Parse and fetch bssid */
6146 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
6147 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
6148 return -EINVAL;
6149 }
6150
6151 memcpy(bssid, nla_data(
6152 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
6153 sizeof(bssid));
6154 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
6155
6156 //Update roaming
6157 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306158 if (!HAL_STATUS_SUCCESS(status)) {
6159 hddLog(LOGE,
6160 FL("sme_ConfigFwrRoaming failed (err=%d)"), status);
6161 return -EINVAL;
6162 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306163 EXIT();
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306164 return 0;
Mukul Sharma2a271632014-10-13 14:59:01 +05306165}
6166
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306167static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
6168 struct wireless_dev *wdev, const void *data, int data_len)
6169{
6170 int ret = 0;
6171
6172 vos_ssr_protect(__func__);
6173 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
6174 vos_ssr_unprotect(__func__);
6175
6176 return ret;
6177}
6178
Sushant Kaushik847890c2015-09-28 16:05:17 +05306179static const struct
6180nla_policy
6181qca_wlan_vendor_get_wifi_info_policy[
6182 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
6183 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
6184 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
6185};
6186
6187
6188/**
6189 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6190 * @wiphy: pointer to wireless wiphy structure.
6191 * @wdev: pointer to wireless_dev structure.
6192 * @data: Pointer to the data to be passed via vendor interface
6193 * @data_len:Length of the data to be passed
6194 *
6195 * This is called when wlan driver needs to send wifi driver related info
6196 * (driver/fw version) to the user space application upon request.
6197 *
6198 * Return: Return the Success or Failure code.
6199 */
6200static int __wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6201 struct wireless_dev *wdev,
6202 const void *data, int data_len)
6203{
6204 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6205 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
6206 tSirVersionString version;
6207 uint32 version_len;
6208 uint8 attr;
6209 int status;
6210 struct sk_buff *reply_skb = NULL;
6211
6212 if (VOS_FTM_MODE == hdd_get_conparam()) {
6213 hddLog(LOGE, FL("Command not allowed in FTM mode"));
6214 return -EINVAL;
6215 }
6216
6217 status = wlan_hdd_validate_context(hdd_ctx);
6218 if (0 != status) {
6219 hddLog(LOGE, FL("HDD context is not valid"));
6220 return -EINVAL;
6221 }
6222
6223 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
6224 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
6225 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
6226 return -EINVAL;
6227 }
6228
6229 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
6230 hddLog(LOG1, FL("Rcvd req for Driver version Driver version is %s"),
6231 QWLAN_VERSIONSTR);
6232 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
6233 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
6234 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
6235 hddLog(LOG1, FL("Rcvd req for FW version FW version is %s"),
6236 hdd_ctx->fw_Version);
6237 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
6238 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
6239 } else {
6240 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
6241 return -EINVAL;
6242 }
6243
6244 version_len = strlen(version);
6245 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
6246 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
6247 if (!reply_skb) {
6248 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6249 return -ENOMEM;
6250 }
6251
6252 if (nla_put(reply_skb, attr, version_len, version)) {
6253 hddLog(LOGE, FL("nla put fail"));
6254 kfree_skb(reply_skb);
6255 return -EINVAL;
6256 }
6257
6258 return cfg80211_vendor_cmd_reply(reply_skb);
6259}
6260
6261/**
6262 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6263 * @wiphy: pointer to wireless wiphy structure.
6264 * @wdev: pointer to wireless_dev structure.
6265 * @data: Pointer to the data to be passed via vendor interface
6266 * @data_len:Length of the data to be passed
6267 * @data_len: Length of the data received
6268 *
6269 * This function is used to enable or disable the collection of packet
6270 * statistics from the firmware
6271 *
6272 * Return: 0 on success and errno on failure
6273 */
6274
6275static int
6276wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6277 struct wireless_dev *wdev,
6278 const void *data, int data_len)
6279
6280
6281{
6282 int ret = 0;
6283
6284 vos_ssr_protect(__func__);
6285 ret = __wlan_hdd_cfg80211_get_wifi_info(wiphy,
6286 wdev, data, data_len);
6287 vos_ssr_unprotect(__func__);
6288
6289 return ret;
6290}
6291
6292
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306293/*
6294 * define short names for the global vendor params
6295 * used by __wlan_hdd_cfg80211_monitor_rssi()
6296 */
6297#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX
6298#define PARAM_REQUEST_ID QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID
6299#define PARAM_CONTROL QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL
6300#define PARAM_MIN_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI
6301#define PARAM_MAX_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI
6302
6303/**---------------------------------------------------------------------------
6304
6305 \brief hdd_rssi_monitor_start_done - callback to be executed when rssi
6306 monitor start is completed successfully.
6307
6308 \return - None
6309
6310 --------------------------------------------------------------------------*/
6311void hdd_rssi_monitor_start_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6312{
6313 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6314
6315 if (NULL == pHddCtx)
6316 {
6317 hddLog(VOS_TRACE_LEVEL_ERROR,
6318 "%s: HDD context is NULL",__func__);
6319 return;
6320 }
6321
6322 if (VOS_STATUS_SUCCESS == status)
6323 {
6324 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor start successful"));
6325 }
6326 else
6327 {
6328 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor start not successful"));
6329 }
6330
6331 return;
6332}
6333
6334/**---------------------------------------------------------------------------
6335
6336 \brief hdd_rssi_monitor_stop_done - callback to be executed when rssi monitor
6337 stop is completed successfully.
6338
6339 \return - None
6340
6341 --------------------------------------------------------------------------*/
6342void hdd_rssi_monitor_stop_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6343{
6344 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6345
6346 if (NULL == pHddCtx)
6347 {
6348 hddLog(VOS_TRACE_LEVEL_ERROR,
6349 "%s: HDD context is NULL",__func__);
6350 return;
6351 }
6352
6353 if (VOS_STATUS_SUCCESS == status)
6354 {
6355 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor stop successful"));
6356 }
6357 else
6358 {
6359 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor stop not successful"));
6360 }
6361
6362 return;
6363}
6364
6365/**
6366 * __wlan_hdd_cfg80211_monitor_rssi() - monitor rssi
6367 * @wiphy: Pointer to wireless phy
6368 * @wdev: Pointer to wireless device
6369 * @data: Pointer to data
6370 * @data_len: Data length
6371 *
6372 * Return: 0 on success, negative errno on failure
6373 */
6374
6375static int
6376__wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy,
6377 struct wireless_dev *wdev,
6378 const void *data,
6379 int data_len)
6380{
6381 struct net_device *dev = wdev->netdev;
6382 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6383 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6384 hdd_station_ctx_t *pHddStaCtx;
6385 struct nlattr *tb[PARAM_MAX + 1];
6386 tpSirRssiMonitorReq pReq;
6387 eHalStatus status;
6388 int ret;
6389 uint32_t control;
6390 static const struct nla_policy policy[PARAM_MAX + 1] = {
6391 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6392 [PARAM_CONTROL] = { .type = NLA_U32 },
6393 [PARAM_MIN_RSSI] = { .type = NLA_S8 },
6394 [PARAM_MAX_RSSI] = { .type = NLA_S8 },
6395 };
6396
6397 ENTER();
6398
6399 ret = wlan_hdd_validate_context(hdd_ctx);
6400 if (0 != ret) {
6401 return -EINVAL;
6402 }
6403
6404 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6405 hddLog(LOGE, FL("Not in Connected state!"));
6406 return -ENOTSUPP;
6407 }
6408
6409 if (nla_parse(tb, PARAM_MAX, data, data_len, policy)) {
6410 hddLog(LOGE, FL("Invalid ATTR"));
6411 return -EINVAL;
6412 }
6413
6414 if (!tb[PARAM_REQUEST_ID]) {
6415 hddLog(LOGE, FL("attr request id failed"));
6416 return -EINVAL;
6417 }
6418
6419 if (!tb[PARAM_CONTROL]) {
6420 hddLog(LOGE, FL("attr control failed"));
6421 return -EINVAL;
6422 }
6423
6424 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6425
6426 pReq = vos_mem_malloc(sizeof(tSirRssiMonitorReq));
6427 if(NULL == pReq)
6428 {
6429 hddLog(LOGE,
6430 FL("vos_mem_alloc failed "));
6431 return eHAL_STATUS_FAILED_ALLOC;
6432 }
6433 vos_mem_set(pReq, sizeof(tSirRssiMonitorReq), 0);
6434
6435 pReq->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]);
6436 pReq->sessionId = pAdapter->sessionId;
6437 pReq->rssiMonitorCbContext = hdd_ctx;
6438 control = nla_get_u32(tb[PARAM_CONTROL]);
6439 vos_mem_copy( &pReq->currentBssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
6440
6441 hddLog(LOG1, FL("Request Id: %u Session_id: %d Control: %d"),
6442 pReq->requestId, pReq->sessionId, control);
6443
6444 if (control == QCA_WLAN_RSSI_MONITORING_START) {
6445 if (!tb[PARAM_MIN_RSSI]) {
6446 hddLog(LOGE, FL("attr min rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306447 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306448 }
6449
6450 if (!tb[PARAM_MAX_RSSI]) {
6451 hddLog(LOGE, FL("attr max rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306452 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306453 }
6454
6455 pReq->minRssi = nla_get_s8(tb[PARAM_MIN_RSSI]);
6456 pReq->maxRssi = nla_get_s8(tb[PARAM_MAX_RSSI]);
6457 pReq->rssiMonitorCallback = hdd_rssi_monitor_start_done;
6458
6459 if (!(pReq->minRssi < pReq->maxRssi)) {
6460 hddLog(LOGW, FL("min_rssi: %d must be less than max_rssi: %d"),
6461 pReq->minRssi, pReq->maxRssi);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306462 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306463 }
6464 hddLog(LOG1, FL("Min_rssi: %d Max_rssi: %d"),
6465 pReq->minRssi, pReq->maxRssi);
6466 status = sme_StartRssiMonitoring(hdd_ctx->hHal, pReq);
6467
6468 }
6469 else if (control == QCA_WLAN_RSSI_MONITORING_STOP) {
6470 pReq->rssiMonitorCallback = hdd_rssi_monitor_stop_done;
6471 status = sme_StopRssiMonitoring(hdd_ctx->hHal, pReq);
6472 }
6473 else {
6474 hddLog(LOGE, FL("Invalid control cmd: %d"), control);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306475 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306476 }
6477
6478 if (!HAL_STATUS_SUCCESS(status)) {
6479 hddLog(LOGE,
6480 FL("sme_set_rssi_monitoring failed(err=%d)"), status);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306481 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306482 }
6483
6484 return 0;
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306485fail:
6486 vos_mem_free(pReq);
6487 return -EINVAL;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306488}
6489
6490/*
6491 * done with short names for the global vendor params
6492 * used by __wlan_hdd_cfg80211_monitor_rssi()
6493 */
6494#undef PARAM_MAX
6495#undef PARAM_CONTROL
6496#undef PARAM_REQUEST_ID
6497#undef PARAM_MAX_RSSI
6498#undef PARAM_MIN_RSSI
6499
6500/**
6501 * wlan_hdd_cfg80211_monitor_rssi() - SSR wrapper to rssi monitoring
6502 * @wiphy: wiphy structure pointer
6503 * @wdev: Wireless device structure pointer
6504 * @data: Pointer to the data received
6505 * @data_len: Length of @data
6506 *
6507 * Return: 0 on success; errno on failure
6508 */
6509static int
6510wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, struct wireless_dev *wdev,
6511 const void *data, int data_len)
6512{
6513 int ret;
6514
6515 vos_ssr_protect(__func__);
6516 ret = __wlan_hdd_cfg80211_monitor_rssi(wiphy, wdev, data, data_len);
6517 vos_ssr_unprotect(__func__);
6518
6519 return ret;
6520}
6521
6522/**
6523 * hdd_rssi_threshold_breached_cb() - rssi breached NL event
6524 * @hddctx: HDD context
6525 * @data: rssi breached event data
6526 *
6527 * This function reads the rssi breached event %data and fill in the skb with
6528 * NL attributes and send up the NL event.
6529 * This callback execute in atomic context and must not invoke any
6530 * blocking calls.
6531 *
6532 * Return: none
6533 */
6534void hdd_rssi_threshold_breached_cb(void *hddctx,
6535 struct rssi_breach_event *data)
6536{
6537 hdd_context_t *pHddCtx = (hdd_context_t *)hddctx;
6538 int status;
6539 struct sk_buff *skb;
6540
6541 ENTER();
6542 status = wlan_hdd_validate_context(pHddCtx);
6543
6544 if (0 != status) {
6545 return;
6546 }
6547
6548 if (!data) {
6549 hddLog(LOGE, FL("data is null"));
6550 return;
6551 }
6552
6553 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
6554#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
6555 NULL,
6556#endif
6557 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
6558 QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX,
6559 GFP_KERNEL);
6560
6561 if (!skb) {
6562 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
6563 return;
6564 }
6565
6566 hddLog(LOG1, "Req Id: %u Current rssi: %d",
6567 data->request_id, data->curr_rssi);
6568 hddLog(LOG1, "Current BSSID: "MAC_ADDRESS_STR,
6569 MAC_ADDR_ARRAY(data->curr_bssid.bytes));
6570
6571 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
6572 data->request_id) ||
6573 nla_put(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID,
6574 sizeof(data->curr_bssid), data->curr_bssid.bytes) ||
6575 nla_put_s8(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI,
6576 data->curr_rssi)) {
6577 hddLog(LOGE, FL("nla put fail"));
6578 goto fail;
6579 }
6580
6581 cfg80211_vendor_event(skb, GFP_KERNEL);
6582 return;
6583
6584fail:
6585 kfree_skb(skb);
6586 return;
6587}
6588
6589
6590
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306591/**
6592 * __wlan_hdd_cfg80211_setband() - set band
6593 * @wiphy: Pointer to wireless phy
6594 * @wdev: Pointer to wireless device
6595 * @data: Pointer to data
6596 * @data_len: Data length
6597 *
6598 * Return: 0 on success, negative errno on failure
6599 */
6600static int
6601__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6602 struct wireless_dev *wdev,
6603 const void *data,
6604 int data_len)
6605{
6606 struct net_device *dev = wdev->netdev;
6607 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6608 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6609 int ret;
6610 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
6611 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
6612
6613 ENTER();
6614
6615 ret = wlan_hdd_validate_context(hdd_ctx);
6616 if (0 != ret) {
6617 hddLog(LOGE, FL("HDD context is not valid"));
6618 return ret;
6619 }
6620
6621 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
6622 policy)) {
6623 hddLog(LOGE, FL("Invalid ATTR"));
6624 return -EINVAL;
6625 }
6626
6627 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
6628 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
6629 return -EINVAL;
6630 }
6631
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306632 hdd_ctx->isSetBandByNL = TRUE;
6633 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306634 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306635 hdd_ctx->isSetBandByNL = FALSE;
6636
6637 EXIT();
6638 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306639}
6640
6641/**
6642 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
6643 * @wiphy: wiphy structure pointer
6644 * @wdev: Wireless device structure pointer
6645 * @data: Pointer to the data received
6646 * @data_len: Length of @data
6647 *
6648 * Return: 0 on success; errno on failure
6649 */
6650static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6651 struct wireless_dev *wdev,
6652 const void *data,
6653 int data_len)
6654{
6655 int ret = 0;
6656
6657 vos_ssr_protect(__func__);
6658 ret = __wlan_hdd_cfg80211_setband(wiphy,
6659 wdev, data, data_len);
6660 vos_ssr_unprotect(__func__);
6661
6662 return ret;
6663}
6664
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05306665#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
6666/**
6667 * hdd_map_req_id_to_pattern_id() - map request id to pattern id
6668 * @hdd_ctx: HDD context
6669 * @request_id: [input] request id
6670 * @pattern_id: [output] pattern id
6671 *
6672 * This function loops through request id to pattern id array
6673 * if the slot is available, store the request id and return pattern id
6674 * if entry exists, return the pattern id
6675 *
6676 * Return: 0 on success and errno on failure
6677 */
6678static int hdd_map_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
6679 uint32_t request_id,
6680 uint8_t *pattern_id)
6681{
6682 uint32_t i;
6683
6684 mutex_lock(&hdd_ctx->op_ctx.op_lock);
6685 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
6686 {
6687 if (hdd_ctx->op_ctx.op_table[i].request_id == 0)
6688 {
6689 hdd_ctx->op_ctx.op_table[i].request_id = request_id;
6690 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6691 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6692 return 0;
6693 } else if (hdd_ctx->op_ctx.op_table[i].request_id ==
6694 request_id) {
6695 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6696 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6697 return 0;
6698 }
6699 }
6700 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6701 return -EINVAL;
6702}
6703
6704/**
6705 * hdd_unmap_req_id_to_pattern_id() - unmap request id to pattern id
6706 * @hdd_ctx: HDD context
6707 * @request_id: [input] request id
6708 * @pattern_id: [output] pattern id
6709 *
6710 * This function loops through request id to pattern id array
6711 * reset request id to 0 (slot available again) and
6712 * return pattern id
6713 *
6714 * Return: 0 on success and errno on failure
6715 */
6716static int hdd_unmap_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
6717 uint32_t request_id,
6718 uint8_t *pattern_id)
6719{
6720 uint32_t i;
6721
6722 mutex_lock(&hdd_ctx->op_ctx.op_lock);
6723 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
6724 {
6725 if (hdd_ctx->op_ctx.op_table[i].request_id == request_id)
6726 {
6727 hdd_ctx->op_ctx.op_table[i].request_id = 0;
6728 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6729 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6730 return 0;
6731 }
6732 }
6733 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6734 return -EINVAL;
6735}
6736
6737
6738/*
6739 * define short names for the global vendor params
6740 * used by __wlan_hdd_cfg80211_offloaded_packets()
6741 */
6742#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX
6743#define PARAM_REQUEST_ID \
6744 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID
6745#define PARAM_CONTROL \
6746 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL
6747#define PARAM_IP_PACKET \
6748 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA
6749#define PARAM_SRC_MAC_ADDR \
6750 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR
6751#define PARAM_DST_MAC_ADDR \
6752 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR
6753#define PARAM_PERIOD QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD
6754
6755/**
6756 * wlan_hdd_add_tx_ptrn() - add tx pattern
6757 * @adapter: adapter pointer
6758 * @hdd_ctx: hdd context
6759 * @tb: nl attributes
6760 *
6761 * This function reads the NL attributes and forms a AddTxPtrn message
6762 * posts it to SME.
6763 *
6764 */
6765static int
6766wlan_hdd_add_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
6767 struct nlattr **tb)
6768{
6769 struct sSirAddPeriodicTxPtrn *add_req;
6770 eHalStatus status;
6771 uint32_t request_id, ret, len;
6772 uint8_t pattern_id = 0;
6773 v_MACADDR_t dst_addr;
6774 uint16_t eth_type = htons(ETH_P_IP);
6775
6776 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(adapter)))
6777 {
6778 hddLog(LOGE, FL("Not in Connected state!"));
6779 return -ENOTSUPP;
6780 }
6781
6782 add_req = vos_mem_malloc(sizeof(*add_req));
6783 if (!add_req)
6784 {
6785 hddLog(LOGE, FL("memory allocation failed"));
6786 return -ENOMEM;
6787 }
6788
6789 /* Parse and fetch request Id */
6790 if (!tb[PARAM_REQUEST_ID])
6791 {
6792 hddLog(LOGE, FL("attr request id failed"));
6793 goto fail;
6794 }
6795
6796 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
6797 hddLog(LOG1, FL("Request Id: %u"), request_id);
6798 if (request_id == 0)
6799 {
6800 hddLog(LOGE, FL("request_id cannot be zero"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306801 goto fail;
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05306802 }
6803
6804 if (!tb[PARAM_PERIOD])
6805 {
6806 hddLog(LOGE, FL("attr period failed"));
6807 goto fail;
6808 }
6809 add_req->usPtrnIntervalMs = nla_get_u32(tb[PARAM_PERIOD]);
6810 hddLog(LOG1, FL("Period: %u ms"), add_req->usPtrnIntervalMs);
6811 if (add_req->usPtrnIntervalMs == 0)
6812 {
6813 hddLog(LOGE, FL("Invalid interval zero, return failure"));
6814 goto fail;
6815 }
6816
6817 if (!tb[PARAM_SRC_MAC_ADDR])
6818 {
6819 hddLog(LOGE, FL("attr source mac address failed"));
6820 goto fail;
6821 }
6822 nla_memcpy(add_req->macAddress, tb[PARAM_SRC_MAC_ADDR],
6823 VOS_MAC_ADDR_SIZE);
6824 hddLog(LOG1, "input src mac address: "MAC_ADDRESS_STR,
6825 MAC_ADDR_ARRAY(add_req->macAddress));
6826
6827 if (memcmp(add_req->macAddress, adapter->macAddressCurrent.bytes,
6828 VOS_MAC_ADDR_SIZE))
6829 {
6830 hddLog(LOGE,
6831 FL("input src mac address and connected ap bssid are different"));
6832 goto fail;
6833 }
6834
6835 if (!tb[PARAM_DST_MAC_ADDR])
6836 {
6837 hddLog(LOGE, FL("attr dst mac address failed"));
6838 goto fail;
6839 }
6840 nla_memcpy(dst_addr.bytes, tb[PARAM_DST_MAC_ADDR], VOS_MAC_ADDR_SIZE);
6841 hddLog(LOG1, "input dst mac address: "MAC_ADDRESS_STR,
6842 MAC_ADDR_ARRAY(dst_addr.bytes));
6843
6844 if (!tb[PARAM_IP_PACKET])
6845 {
6846 hddLog(LOGE, FL("attr ip packet failed"));
6847 goto fail;
6848 }
6849 add_req->ucPtrnSize = nla_len(tb[PARAM_IP_PACKET]);
6850 hddLog(LOG1, FL("IP packet len: %u"), add_req->ucPtrnSize);
6851
6852 if (add_req->ucPtrnSize < 0 ||
6853 add_req->ucPtrnSize > (PERIODIC_TX_PTRN_MAX_SIZE -
6854 HDD_ETH_HEADER_LEN))
6855 {
6856 hddLog(LOGE, FL("Invalid IP packet len: %d"),
6857 add_req->ucPtrnSize);
6858 goto fail;
6859 }
6860
6861 len = 0;
6862 vos_mem_copy(&add_req->ucPattern[0], dst_addr.bytes, VOS_MAC_ADDR_SIZE);
6863 len += VOS_MAC_ADDR_SIZE;
6864 vos_mem_copy(&add_req->ucPattern[len], add_req->macAddress,
6865 VOS_MAC_ADDR_SIZE);
6866 len += VOS_MAC_ADDR_SIZE;
6867 vos_mem_copy(&add_req->ucPattern[len], &eth_type, 2);
6868 len += 2;
6869
6870 /*
6871 * This is the IP packet, add 14 bytes Ethernet (802.3) header
6872 * ------------------------------------------------------------
6873 * | 14 bytes Ethernet (802.3) header | IP header and payload |
6874 * ------------------------------------------------------------
6875 */
6876 vos_mem_copy(&add_req->ucPattern[len],
6877 nla_data(tb[PARAM_IP_PACKET]),
6878 add_req->ucPtrnSize);
6879 add_req->ucPtrnSize += len;
6880
6881 VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6882 add_req->ucPattern, add_req->ucPtrnSize);
6883
6884 ret = hdd_map_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
6885 if (ret)
6886 {
6887 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
6888 goto fail;
6889 }
6890 add_req->ucPtrnId = pattern_id;
6891 hddLog(LOG1, FL("pattern id: %d"), add_req->ucPtrnId);
6892
6893 status = sme_AddPeriodicTxPtrn(hdd_ctx->hHal, add_req);
6894 if (!HAL_STATUS_SUCCESS(status))
6895 {
6896 hddLog(LOGE,
6897 FL("sme_AddPeriodicTxPtrn failed (err=%d)"), status);
6898 goto fail;
6899 }
6900
6901 EXIT();
6902 vos_mem_free(add_req);
6903 return 0;
6904
6905fail:
6906 vos_mem_free(add_req);
6907 return -EINVAL;
6908}
6909
6910/**
6911 * wlan_hdd_del_tx_ptrn() - delete tx pattern
6912 * @adapter: adapter pointer
6913 * @hdd_ctx: hdd context
6914 * @tb: nl attributes
6915 *
6916 * This function reads the NL attributes and forms a DelTxPtrn message
6917 * posts it to SME.
6918 *
6919 */
6920static int
6921wlan_hdd_del_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
6922 struct nlattr **tb)
6923{
6924 struct sSirDelPeriodicTxPtrn *del_req;
6925 eHalStatus status;
6926 uint32_t request_id, ret;
6927 uint8_t pattern_id = 0;
6928
6929 /* Parse and fetch request Id */
6930 if (!tb[PARAM_REQUEST_ID])
6931 {
6932 hddLog(LOGE, FL("attr request id failed"));
6933 return -EINVAL;
6934 }
6935 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
6936 if (request_id == 0)
6937 {
6938 hddLog(LOGE, FL("request_id cannot be zero"));
6939 return -EINVAL;
6940 }
6941
6942 ret = hdd_unmap_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
6943 if (ret)
6944 {
6945 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
6946 return -EINVAL;
6947 }
6948
6949 del_req = vos_mem_malloc(sizeof(*del_req));
6950 if (!del_req)
6951 {
6952 hddLog(LOGE, FL("memory allocation failed"));
6953 return -ENOMEM;
6954 }
6955
6956 vos_mem_set(del_req, sizeof(*del_req), 0);
6957 vos_mem_copy(del_req->macAddress, adapter->macAddressCurrent.bytes,
6958 VOS_MAC_ADDR_SIZE);
6959 hddLog(LOG1, MAC_ADDRESS_STR, MAC_ADDR_ARRAY(del_req->macAddress));
6960 del_req->ucPatternIdBitmap |= (0x1 << pattern_id);
6961 hddLog(LOG1, FL("Request Id: %u Pattern id: %d, bitmap %04x"),
6962 request_id, pattern_id, del_req->ucPatternIdBitmap);
6963
6964 status = sme_DelPeriodicTxPtrn(hdd_ctx->hHal, del_req);
6965 if (!HAL_STATUS_SUCCESS(status))
6966 {
6967 hddLog(LOGE,
6968 FL("sme_DelPeriodicTxPtrn failed (err=%d)"), status);
6969 goto fail;
6970 }
6971
6972 EXIT();
6973 vos_mem_free(del_req);
6974 return 0;
6975
6976fail:
6977 vos_mem_free(del_req);
6978 return -EINVAL;
6979}
6980
6981
6982/**
6983 * __wlan_hdd_cfg80211_offloaded_packets() - send offloaded packets
6984 * @wiphy: Pointer to wireless phy
6985 * @wdev: Pointer to wireless device
6986 * @data: Pointer to data
6987 * @data_len: Data length
6988 *
6989 * Return: 0 on success, negative errno on failure
6990 */
6991static int
6992__wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
6993 struct wireless_dev *wdev,
6994 const void *data,
6995 int data_len)
6996{
6997 struct net_device *dev = wdev->netdev;
6998 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
6999 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7000 struct nlattr *tb[PARAM_MAX + 1];
7001 uint8_t control;
7002 int ret;
7003 static const struct nla_policy policy[PARAM_MAX + 1] =
7004 {
7005 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
7006 [PARAM_CONTROL] = { .type = NLA_U32 },
7007 [PARAM_SRC_MAC_ADDR] = { .type = NLA_BINARY,
7008 .len = VOS_MAC_ADDR_SIZE },
7009 [PARAM_DST_MAC_ADDR] = { .type = NLA_BINARY,
7010 .len = VOS_MAC_ADDR_SIZE },
7011 [PARAM_PERIOD] = { .type = NLA_U32 },
7012 };
7013
7014 ENTER();
7015
7016 ret = wlan_hdd_validate_context(hdd_ctx);
7017 if (0 != ret)
7018 {
7019 hddLog(LOGE, FL("HDD context is not valid"));
7020 return ret;
7021 }
7022
7023 if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN))
7024 {
7025 hddLog(LOGE,
7026 FL("Periodic Tx Pattern Offload feature is not supported in FW!"));
7027 return -ENOTSUPP;
7028 }
7029
7030 if (nla_parse(tb, PARAM_MAX, data, data_len, policy))
7031 {
7032 hddLog(LOGE, FL("Invalid ATTR"));
7033 return -EINVAL;
7034 }
7035
7036 if (!tb[PARAM_CONTROL])
7037 {
7038 hddLog(LOGE, FL("attr control failed"));
7039 return -EINVAL;
7040 }
7041 control = nla_get_u32(tb[PARAM_CONTROL]);
7042 hddLog(LOG1, FL("Control: %d"), control);
7043
7044 if (control == WLAN_START_OFFLOADED_PACKETS)
7045 return wlan_hdd_add_tx_ptrn(adapter, hdd_ctx, tb);
7046 else if (control == WLAN_STOP_OFFLOADED_PACKETS)
7047 return wlan_hdd_del_tx_ptrn(adapter, hdd_ctx, tb);
7048 else
7049 {
7050 hddLog(LOGE, FL("Invalid control: %d"), control);
7051 return -EINVAL;
7052 }
7053}
7054
7055/*
7056 * done with short names for the global vendor params
7057 * used by __wlan_hdd_cfg80211_offloaded_packets()
7058 */
7059#undef PARAM_MAX
7060#undef PARAM_REQUEST_ID
7061#undef PARAM_CONTROL
7062#undef PARAM_IP_PACKET
7063#undef PARAM_SRC_MAC_ADDR
7064#undef PARAM_DST_MAC_ADDR
7065#undef PARAM_PERIOD
7066
7067/**
7068 * wlan_hdd_cfg80211_offloaded_packets() - Wrapper to offload packets
7069 * @wiphy: wiphy structure pointer
7070 * @wdev: Wireless device structure pointer
7071 * @data: Pointer to the data received
7072 * @data_len: Length of @data
7073 *
7074 * Return: 0 on success; errno on failure
7075 */
7076static int wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7077 struct wireless_dev *wdev,
7078 const void *data,
7079 int data_len)
7080{
7081 int ret = 0;
7082
7083 vos_ssr_protect(__func__);
7084 ret = __wlan_hdd_cfg80211_offloaded_packets(wiphy,
7085 wdev, data, data_len);
7086 vos_ssr_unprotect(__func__);
7087
7088 return ret;
7089}
7090#endif
7091
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307092static const struct
7093nla_policy
7094qca_wlan_vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
7095 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
7096};
7097
7098/**
7099 * wlan_hdd_cfg80211_get_link_properties() - This function is used to
7100 * get link properties like nss, rate flags and operating frequency for
7101 * the connection with the given peer.
7102 * @wiphy: WIPHY structure pointer
7103 * @wdev: Wireless device structure pointer
7104 * @data: Pointer to the data received
7105 * @data_len: Length of the data received
7106 *
7107 * This function return the above link properties on success.
7108 *
7109 * Return: 0 on success and errno on failure
7110 */
7111static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
7112 struct wireless_dev *wdev,
7113 const void *data,
7114 int data_len)
7115{
7116 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7117 struct net_device *dev = wdev->netdev;
7118 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7119 hdd_station_ctx_t *hdd_sta_ctx;
7120 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX+1];
7121 uint8_t peer_mac[VOS_MAC_ADDR_SIZE];
7122 uint32_t sta_id;
7123 struct sk_buff *reply_skb;
7124 uint32_t rate_flags = 0;
7125 uint8_t nss;
7126 uint8_t final_rate_flags = 0;
7127 uint32_t freq;
7128 v_CONTEXT_t pVosContext = NULL;
7129 ptSapContext pSapCtx = NULL;
7130
7131 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
7132 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
7133 return -EINVAL;
7134 }
7135
7136 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7137 qca_wlan_vendor_attr_policy)) {
7138 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid attribute"));
7139 return -EINVAL;
7140 }
7141
7142 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
7143 hddLog(VOS_TRACE_LEVEL_ERROR,
7144 FL("Attribute peerMac not provided for mode=%d"),
7145 adapter->device_mode);
7146 return -EINVAL;
7147 }
7148
7149 memcpy(peer_mac, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
7150 sizeof(peer_mac));
7151 hddLog(VOS_TRACE_LEVEL_INFO,
7152 FL("peerMac="MAC_ADDRESS_STR" for device_mode:%d"),
7153 MAC_ADDR_ARRAY(peer_mac), adapter->device_mode);
7154
7155 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
7156 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
7157 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
7158 if ((hdd_sta_ctx->conn_info.connState !=
7159 eConnectionState_Associated) ||
7160 !vos_mem_compare(hdd_sta_ctx->conn_info.bssId, peer_mac,
7161 VOS_MAC_ADDRESS_LEN)) {
7162 hddLog(VOS_TRACE_LEVEL_ERROR,
7163 FL("Not Associated to mac "MAC_ADDRESS_STR),
7164 MAC_ADDR_ARRAY(peer_mac));
7165 return -EINVAL;
7166 }
7167
7168 nss = 1; //pronto supports only one spatial stream
7169 freq = vos_chan_to_freq(
7170 hdd_sta_ctx->conn_info.operationChannel);
7171 rate_flags = hdd_sta_ctx->conn_info.rate_flags;
7172
7173 } else if (adapter->device_mode == WLAN_HDD_P2P_GO ||
7174 adapter->device_mode == WLAN_HDD_SOFTAP) {
7175
7176 pVosContext = ( WLAN_HDD_GET_CTX(adapter))->pvosContext;
7177 pSapCtx = VOS_GET_SAP_CB(pVosContext);
7178 if(pSapCtx == NULL){
7179 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7180 FL("psapCtx is NULL"));
7181 return -ENOENT;
7182 }
7183
7184
7185 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
7186 if (pSapCtx->aStaInfo[sta_id].isUsed &&
7187 !vos_is_macaddr_broadcast(
7188 &pSapCtx->aStaInfo[sta_id].macAddrSTA) &&
7189 vos_mem_compare(
7190 &pSapCtx->aStaInfo[sta_id].macAddrSTA,
7191 peer_mac, VOS_MAC_ADDRESS_LEN))
7192 break;
7193 }
7194
7195 if (WLAN_MAX_STA_COUNT == sta_id) {
7196 hddLog(VOS_TRACE_LEVEL_ERROR,
7197 FL("No active peer with mac="MAC_ADDRESS_STR),
7198 MAC_ADDR_ARRAY(peer_mac));
7199 return -EINVAL;
7200 }
7201
7202 nss = 1; //pronto supports only one spatial stream
7203 freq = vos_chan_to_freq(
7204 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operatingChannel);
7205 rate_flags = pSapCtx->aStaInfo[sta_id].rate_flags;
7206 } else {
7207 hddLog(VOS_TRACE_LEVEL_ERROR,
7208 FL("Not Associated! with mac"MAC_ADDRESS_STR),
7209 MAC_ADDR_ARRAY(peer_mac));
7210 return -EINVAL;
7211 }
7212
7213 if (!(rate_flags & eHAL_TX_RATE_LEGACY)) {
7214 if (rate_flags & eHAL_TX_RATE_VHT80) {
7215 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7216 final_rate_flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
7217 } else if (rate_flags & eHAL_TX_RATE_VHT40) {
7218 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7219 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7220 } else if (rate_flags & eHAL_TX_RATE_VHT20) {
7221 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7222 } else if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40)) {
7223 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7224 if (rate_flags & eHAL_TX_RATE_HT40)
7225 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7226 }
7227
7228 if (rate_flags & eHAL_TX_RATE_SGI) {
7229 if (!(final_rate_flags & RATE_INFO_FLAGS_VHT_MCS))
7230 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7231 final_rate_flags |= RATE_INFO_FLAGS_SHORT_GI;
7232 }
7233 }
7234
7235 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7236 sizeof(u8) + sizeof(u8) + sizeof(u32) + NLMSG_HDRLEN);
7237
7238 if (NULL == reply_skb) {
7239 hddLog(VOS_TRACE_LEVEL_ERROR,
7240 FL("getLinkProperties: skb alloc failed"));
7241 return -EINVAL;
7242 }
7243
7244 if (nla_put_u8(reply_skb,
7245 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS,
7246 nss) ||
7247 nla_put_u8(reply_skb,
7248 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS,
7249 final_rate_flags) ||
7250 nla_put_u32(reply_skb,
7251 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ,
7252 freq)) {
7253 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_put failed"));
7254 kfree_skb(reply_skb);
7255 return -EINVAL;
7256 }
7257
7258 return cfg80211_vendor_cmd_reply(reply_skb);
7259}
7260
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307261#define BEACON_MISS_THRESH_2_4 \
7262 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24
7263#define BEACON_MISS_THRESH_5_0 \
7264 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307265#define PARAM_WIFICONFIG_MAX QCA_WLAN_VENDOR_ATTR_CONFIG_MAX
7266#define PARAM_MODULATED_DTIM QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM
7267#define PARAM_STATS_AVG_FACTOR QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR
7268#define PARAM_GUARD_TIME QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307269#define PARAM_BCNMISS_PENALTY_PARAM_COUNT \
7270 QCA_WLAN_VENDOR_ATTR_CONFIG_PENALIZE_AFTER_NCONS_BEACON_MISS
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307271
7272/**
7273 * __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7274 * vendor command
7275 *
7276 * @wiphy: wiphy device pointer
7277 * @wdev: wireless device pointer
7278 * @data: Vendor command data buffer
7279 * @data_len: Buffer length
7280 *
7281 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7282 *
7283 * Return: EOK or other error codes.
7284 */
7285
7286static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7287 struct wireless_dev *wdev,
7288 const void *data,
7289 int data_len)
7290{
7291 struct net_device *dev = wdev->netdev;
7292 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7293 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7294 hdd_station_ctx_t *pHddStaCtx;
7295 struct nlattr *tb[PARAM_WIFICONFIG_MAX + 1];
7296 tpSetWifiConfigParams pReq;
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307297 tModifyRoamParamsReqParams modifyRoamParamsReq;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307298 eHalStatus status;
7299 int ret_val;
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307300 uint8_t hb_thresh_val;
7301
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307302 static const struct nla_policy policy[PARAM_WIFICONFIG_MAX + 1] = {
7303 [PARAM_STATS_AVG_FACTOR] = { .type = NLA_U16 },
7304 [PARAM_MODULATED_DTIM] = { .type = NLA_U32 },
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307305 [PARAM_GUARD_TIME] = { .type = NLA_U32},
7306 [PARAM_BCNMISS_PENALTY_PARAM_COUNT] =
7307 { .type = NLA_U32},
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307308 [BEACON_MISS_THRESH_2_4] = { .type = NLA_U8 },
7309 [BEACON_MISS_THRESH_5_0] = { .type = NLA_U8 },
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307310 };
7311
7312 ENTER();
7313
7314 if (VOS_FTM_MODE == hdd_get_conparam()) {
7315 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7316 return -EINVAL;
7317 }
7318
7319 ret_val = wlan_hdd_validate_context(pHddCtx);
7320 if (ret_val) {
7321 return ret_val;
7322 }
7323
7324 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7325
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307326 if (nla_parse(tb, PARAM_WIFICONFIG_MAX, data, data_len, policy)) {
7327 hddLog(LOGE, FL("Invalid ATTR"));
7328 return -EINVAL;
7329 }
7330
7331 /* check the Wifi Capability */
7332 if ( (TRUE != pHddCtx->cfg_ini->fEnableWifiConfig) &&
7333 (TRUE != sme_IsFeatureSupportedByFW(WIFI_CONFIG)))
7334 {
7335 hddLog(VOS_TRACE_LEVEL_ERROR,
7336 FL("WIFICONFIG not supported by Firmware"));
7337 return -EINVAL;
7338 }
7339
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307340 if (tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]) {
7341 modifyRoamParamsReq.param = WIFI_CONFIG_SET_BCNMISS_PENALTY_COUNT;
7342 modifyRoamParamsReq.value =
7343 nla_get_u32(tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]);
7344
7345 if (eHAL_STATUS_SUCCESS !=
7346 sme_setBcnMissPenaltyCount(pHddCtx->hHal,&modifyRoamParamsReq))
7347 {
7348 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed", __func__);
7349 ret_val = -EINVAL;
7350 }
7351 return ret_val;
7352 }
7353
7354 /* Moved this down in order to provide provision to set beacon
7355 * miss penalty count irrespective of connection state.
7356 */
7357 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
7358 hddLog(LOGE, FL("Not in Connected state!"));
7359 return -ENOTSUPP;
7360 }
7361
7362 pReq = vos_mem_malloc(sizeof(tSetWifiConfigParams));
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307363
7364 if (!pReq) {
7365 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7366 "%s: Not able to allocate memory for tSetWifiConfigParams",
7367 __func__);
7368 return eHAL_STATUS_E_MALLOC_FAILED;
7369 }
7370
7371 vos_mem_set(pReq, sizeof(tSetWifiConfigParams), 0);
7372
7373 pReq->sessionId = pAdapter->sessionId;
7374 vos_mem_copy( &pReq->bssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
7375
7376 if (tb[PARAM_MODULATED_DTIM]) {
7377 pReq->paramValue = nla_get_u32(
7378 tb[PARAM_MODULATED_DTIM]);
7379 hddLog(LOG1, FL("Modulated DTIM: pReq->paramValue:%d "),
7380 pReq->paramValue);
Arun Khandavalli876886f2015-11-23 11:42:27 +05307381 pHddCtx->cfg_ini->enableDynamicDTIM = pReq->paramValue;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307382 hdd_set_pwrparams(pHddCtx);
7383 if (BMPS == pmcGetPmcState(pHddCtx->hHal)) {
7384 hddLog( LOG1, FL("WifiConfig: Requesting FullPower!"));
7385
7386 sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
7387 iw_full_power_cbfn, pAdapter,
7388 eSME_FULL_PWR_NEEDED_BY_HDD);
7389 }
7390 else
7391 {
7392 hddLog( LOG1, FL("WifiConfig Not in BMPS state"));
7393 }
7394 }
7395
7396 if (tb[PARAM_STATS_AVG_FACTOR]) {
7397 pReq->paramType = WIFI_CONFIG_SET_AVG_STATS_FACTOR;
7398 pReq->paramValue = nla_get_u16(
7399 tb[PARAM_STATS_AVG_FACTOR]);
7400 hddLog(LOG1, FL("AVG_STATS_FACTOR pReq->paramType:%d,pReq->paramValue:%d "),
7401 pReq->paramType, pReq->paramValue);
7402 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7403
7404 if (eHAL_STATUS_SUCCESS != status)
7405 {
7406 vos_mem_free(pReq);
7407 pReq = NULL;
7408 ret_val = -EPERM;
7409 return ret_val;
7410 }
7411 }
7412
7413
7414 if (tb[PARAM_GUARD_TIME]) {
7415 pReq->paramType = WIFI_CONFIG_SET_GUARD_TIME;
7416 pReq->paramValue = nla_get_u32(
7417 tb[PARAM_GUARD_TIME]);
7418 hddLog(LOG1, FL("GUARD_TIME pReq->paramType:%d,pReq->paramValue:%d "),
7419 pReq->paramType, pReq->paramValue);
7420 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7421
7422 if (eHAL_STATUS_SUCCESS != status)
7423 {
7424 vos_mem_free(pReq);
7425 pReq = NULL;
7426 ret_val = -EPERM;
7427 return ret_val;
7428 }
7429
7430 }
7431
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307432 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]) {
7433 hb_thresh_val = nla_get_u8(
7434 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]);
7435
7436 hddLog(LOG1, "WLAN set heartbeat threshold for 2.4Ghz %d",
7437 hb_thresh_val);
7438 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7439 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
7440 NULL, eANI_BOOLEAN_FALSE);
7441
7442 status = sme_update_hb_threshold(
7443 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
7444 WNI_CFG_HEART_BEAT_THRESHOLD,
7445 hb_thresh_val, eCSR_BAND_24);
7446 if (eHAL_STATUS_SUCCESS != status) {
7447 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
7448 vos_mem_free(pReq);
7449 pReq = NULL;
7450 return -EPERM;
7451 }
7452 }
7453
7454 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]) {
7455 hb_thresh_val = nla_get_u8(
7456 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]);
7457
7458 hddLog(LOG1, "WLAN set heartbeat threshold for 5Ghz %d",
7459 hb_thresh_val);
7460 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7461 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
7462 NULL, eANI_BOOLEAN_FALSE);
7463
7464 status = sme_update_hb_threshold(
7465 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
7466 WNI_CFG_HEART_BEAT_THRESHOLD,
7467 hb_thresh_val, eCSR_BAND_5G);
7468 if (eHAL_STATUS_SUCCESS != status) {
7469 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
7470 vos_mem_free(pReq);
7471 pReq = NULL;
7472 return -EPERM;
7473 }
7474 }
7475
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307476 EXIT();
7477 return ret_val;
7478}
7479
7480/**
7481 * wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7482 * vendor command
7483 *
7484 * @wiphy: wiphy device pointer
7485 * @wdev: wireless device pointer
7486 * @data: Vendor command data buffer
7487 * @data_len: Buffer length
7488 *
7489 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7490 *
7491 * Return: EOK or other error codes.
7492 */
7493static int wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7494 struct wireless_dev *wdev,
7495 const void *data,
7496 int data_len)
7497{
7498 int ret;
7499
7500 vos_ssr_protect(__func__);
7501 ret = __wlan_hdd_cfg80211_wifi_configuration_set(wiphy, wdev,
7502 data, data_len);
7503 vos_ssr_unprotect(__func__);
7504
7505 return ret;
7506}
Anurag Chouhan6ee81542017-02-09 18:09:27 +05307507
7508/*
7509 * define short names for the global vendor params
7510 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
7511 */
7512#define STATS_SET_INVALID \
7513 QCA_ATTR_NUD_STATS_SET_INVALID
7514#define STATS_SET_START \
7515 QCA_ATTR_NUD_STATS_SET_START
7516#define STATS_GW_IPV4 \
7517 QCA_ATTR_NUD_STATS_GW_IPV4
7518#define STATS_SET_MAX \
7519 QCA_ATTR_NUD_STATS_SET_MAX
7520
7521const struct nla_policy
7522qca_wlan_vendor_set_nud_stats[STATS_SET_MAX +1] =
7523{
7524 [STATS_SET_START] = {.type = NLA_FLAG },
7525 [STATS_GW_IPV4] = {.type = NLA_U32 },
7526};
7527
7528/**
7529 * hdd_set_nud_stats_cb() - hdd callback api to get status
7530 * @data: pointer to adapter
7531 * @rsp: status
7532 *
7533 * Return: None
7534 */
7535static void hdd_set_nud_stats_cb(void *data, VOS_STATUS rsp)
7536{
7537
7538 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
7539
7540 if (NULL == adapter)
7541 return;
7542
7543 if (VOS_STATUS_SUCCESS == rsp) {
7544 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7545 "%s success received STATS_SET_START", __func__);
7546 } else {
7547 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7548 "%s STATS_SET_START Failed!!", __func__);
7549 }
7550 return;
7551}
7552
7553/**
7554 * __wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
7555 * @wiphy: pointer to wireless wiphy structure.
7556 * @wdev: pointer to wireless_dev structure.
7557 * @data: pointer to apfind configuration data.
7558 * @data_len: the length in byte of apfind data.
7559 *
7560 * This is called when wlan driver needs to send arp stats to
7561 * firmware.
7562 *
7563 * Return: An error code or 0 on success.
7564 */
7565static int __wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
7566 struct wireless_dev *wdev,
7567 const void *data, int data_len)
7568{
7569 struct nlattr *tb[STATS_SET_MAX + 1];
7570 struct net_device *dev = wdev->netdev;
7571 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7572 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7573 setArpStatsParams arp_stats_params;
7574 int err = 0;
7575
7576 ENTER();
7577
7578 err = wlan_hdd_validate_context(hdd_ctx);
7579 if (0 != err)
7580 return err;
7581
7582 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
7583 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7584 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
7585 return -EINVAL;
7586 }
7587
7588 err = nla_parse(tb, STATS_SET_MAX, data, data_len,
7589 qca_wlan_vendor_set_nud_stats);
7590 if (err)
7591 {
7592 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7593 "%s STATS_SET_START ATTR", __func__);
7594 return err;
7595 }
7596
7597 if (tb[STATS_SET_START])
7598 {
7599 if (!tb[STATS_GW_IPV4]) {
7600 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7601 "%s STATS_SET_START CMD", __func__);
7602 return -EINVAL;
7603 }
7604 arp_stats_params.flag = true;
7605 arp_stats_params.ip_addr = nla_get_u32(tb[STATS_GW_IPV4]);
7606 } else {
7607 arp_stats_params.flag = false;
7608 }
7609 if (arp_stats_params.flag) {
7610 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7611 "%s STATS_SET_START Cleared!!", __func__);
7612 vos_mem_zero(&adapter->hdd_stats.hddArpStats, sizeof(adapter->hdd_stats.hddArpStats));
7613 }
7614
7615 arp_stats_params.pkt_type = 1; // ARP packet type
7616
7617 arp_stats_params.rsp_cb_fn = hdd_set_nud_stats_cb;
7618 arp_stats_params.data_ctx = adapter;
7619
7620 if (eHAL_STATUS_SUCCESS !=
7621 sme_set_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
7622 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7623 "%s STATS_SET_START CMD Failed!!", __func__);
7624 return -EINVAL;
7625 }
7626
7627 EXIT();
7628
7629 return err;
7630}
7631
7632/**
7633 * wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
7634 * @wiphy: pointer to wireless wiphy structure.
7635 * @wdev: pointer to wireless_dev structure.
7636 * @data: pointer to apfind configuration data.
7637 * @data_len: the length in byte of apfind data.
7638 *
7639 * This is called when wlan driver needs to send arp stats to
7640 * firmware.
7641 *
7642 * Return: An error code or 0 on success.
7643 */
7644static int wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
7645 struct wireless_dev *wdev,
7646 const void *data, int data_len)
7647{
7648 int ret;
7649
7650 vos_ssr_protect(__func__);
7651 ret = __wlan_hdd_cfg80211_set_nud_stats(wiphy, wdev, data, data_len);
7652 vos_ssr_unprotect(__func__);
7653
7654 return ret;
7655}
7656#undef STATS_SET_INVALID
7657#undef STATS_SET_START
7658#undef STATS_GW_IPV4
7659#undef STATS_SET_MAX
7660
7661/*
7662 * define short names for the global vendor params
7663 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
7664 */
7665#define STATS_GET_INVALID \
7666 QCA_ATTR_NUD_STATS_SET_INVALID
7667#define COUNT_FROM_NETDEV \
7668 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
7669#define COUNT_TO_LOWER_MAC \
7670 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
7671#define RX_COUNT_BY_LOWER_MAC \
7672 QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
7673#define COUNT_TX_SUCCESS \
7674 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
7675#define RSP_RX_COUNT_BY_LOWER_MAC \
7676 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
7677#define RSP_RX_COUNT_BY_UPPER_MAC \
7678 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
7679#define RSP_COUNT_TO_NETDEV \
7680 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
7681#define RSP_COUNT_OUT_OF_ORDER_DROP \
7682 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
7683#define AP_LINK_ACTIVE \
7684 QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
7685#define AP_LINK_DAD \
7686 QCA_ATTR_NUD_STATS_AP_LINK_DAD
7687#define STATS_GET_MAX \
7688 QCA_ATTR_NUD_STATS_GET_MAX
7689
7690const struct nla_policy
7691qca_wlan_vendor_get_nud_stats[STATS_GET_MAX +1] =
7692{
7693 [COUNT_FROM_NETDEV] = {.type = NLA_U16 },
7694 [COUNT_TO_LOWER_MAC] = {.type = NLA_U16 },
7695 [RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
7696 [COUNT_TX_SUCCESS] = {.type = NLA_U16 },
7697 [RSP_RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
7698 [RSP_RX_COUNT_BY_UPPER_MAC] = {.type = NLA_U16 },
7699 [RSP_COUNT_TO_NETDEV] = {.type = NLA_U16 },
7700 [RSP_COUNT_OUT_OF_ORDER_DROP] = {.type = NLA_U16 },
7701 [AP_LINK_ACTIVE] = {.type = NLA_FLAG },
7702 [AP_LINK_DAD] = {.type = NLA_FLAG },
7703};
7704
7705static void hdd_get_nud_stats_cb(void *data, rsp_stats *rsp)
7706{
7707
7708 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
7709 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
7710 struct hdd_nud_stats_context *context;
7711 int status;
7712
7713 ENTER();
7714
7715 if (NULL == adapter)
7716 return;
7717
7718 status = wlan_hdd_validate_context(hdd_ctx);
7719 if (0 != status) {
7720 return;
7721 }
7722
7723 if (!rsp) {
7724 hddLog(LOGE, FL("data is null"));
7725 return;
7726 }
7727
7728 adapter->hdd_stats.hddArpStats.tx_fw_cnt = rsp->tx_fw_cnt;
7729 adapter->hdd_stats.hddArpStats.rx_fw_cnt = rsp->rx_fw_cnt;
7730 adapter->hdd_stats.hddArpStats.tx_ack_cnt = rsp->tx_ack_cnt;
7731 adapter->dad |= rsp->dad;
7732
7733 spin_lock(&hdd_context_lock);
7734 context = &hdd_ctx->nud_stats_context;
7735 complete(&context->response_event);
7736 spin_unlock(&hdd_context_lock);
7737
7738 return;
7739}
7740static int __wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
7741 struct wireless_dev *wdev,
7742 const void *data, int data_len)
7743{
7744 int err = 0;
7745 unsigned long rc;
7746 struct hdd_nud_stats_context *context;
7747 struct net_device *dev = wdev->netdev;
7748 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7749 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7750 getArpStatsParams arp_stats_params;
7751 struct sk_buff *skb;
7752
7753 ENTER();
7754
7755 err = wlan_hdd_validate_context(hdd_ctx);
7756 if (0 != err)
7757 return err;
7758
7759 arp_stats_params.pkt_type = WLAN_NUD_STATS_ARP_PKT_TYPE;
7760 arp_stats_params.get_rsp_cb_fn = hdd_get_nud_stats_cb;
7761 arp_stats_params.data_ctx = adapter;
7762
7763 spin_lock(&hdd_context_lock);
7764 context = &hdd_ctx->nud_stats_context;
7765 INIT_COMPLETION(context->response_event);
7766 spin_unlock(&hdd_context_lock);
7767
7768 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
7769 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7770 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
7771 return -EINVAL;
7772 }
7773
7774 if (eHAL_STATUS_SUCCESS !=
7775 sme_get_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
7776 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7777 "%s STATS_SET_START CMD Failed!!", __func__);
7778 return -EINVAL;
7779 }
7780
7781 rc = wait_for_completion_timeout(&context->response_event,
7782 msecs_to_jiffies(WLAN_WAIT_TIME_NUD_STATS));
7783 if (!rc)
7784 {
7785 hddLog(LOGE,
7786 FL("Target response timed out request "));
7787 return -ETIMEDOUT;
7788 }
7789
7790 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7791 WLAN_NUD_STATS_LEN);
7792 if (!skb)
7793 {
7794 hddLog(VOS_TRACE_LEVEL_ERROR,
7795 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
7796 __func__);
7797 return -ENOMEM;
7798 }
7799
7800 if (nla_put_u16(skb, COUNT_FROM_NETDEV,
7801 adapter->hdd_stats.hddArpStats.txCount) ||
7802 nla_put_u16(skb, COUNT_TO_LOWER_MAC,
7803 adapter->hdd_stats.hddArpStats.tx_host_fw_sent) ||
7804 nla_put_u16(skb, RX_COUNT_BY_LOWER_MAC,
7805 adapter->hdd_stats.hddArpStats.tx_fw_cnt) ||
7806 nla_put_u16(skb, COUNT_TX_SUCCESS,
7807 adapter->hdd_stats.hddArpStats.tx_ack_cnt) ||
7808 nla_put_u16(skb, RSP_RX_COUNT_BY_LOWER_MAC,
7809 adapter->hdd_stats.hddArpStats.rx_fw_cnt) ||
7810 nla_put_u16(skb, RSP_RX_COUNT_BY_UPPER_MAC,
7811 adapter->hdd_stats.hddArpStats.rxCount) ||
7812 nla_put_u16(skb, RSP_COUNT_TO_NETDEV,
7813 adapter->hdd_stats.hddArpStats.rxDelivered) ||
7814 nla_put_u16(skb, RSP_COUNT_OUT_OF_ORDER_DROP,
7815 adapter->hdd_stats.hddArpStats.rx_host_drop_reorder)) {
7816 hddLog(LOGE, FL("nla put fail"));
7817 kfree_skb(skb);
7818 return -EINVAL;
7819 }
7820 if (adapter->con_status)
7821 nla_put_flag(skb, AP_LINK_ACTIVE);
7822 if (adapter->dad)
7823 nla_put_flag(skb, AP_LINK_DAD);
7824
7825 cfg80211_vendor_cmd_reply(skb);
7826 return err;
7827}
7828
7829static int wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
7830 struct wireless_dev *wdev,
7831 const void *data, int data_len)
7832{
7833 int ret;
7834
7835 vos_ssr_protect(__func__);
7836 ret = __wlan_hdd_cfg80211_get_nud_stats(wiphy, wdev, data, data_len);
7837 vos_ssr_unprotect(__func__);
7838
7839 return ret;
7840}
7841
7842#undef QCA_ATTR_NUD_STATS_SET_INVALID
7843#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
7844#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
7845#undef QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
7846#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
7847#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
7848#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
7849#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
7850#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
7851#undef QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
7852#undef QCA_ATTR_NUD_STATS_GET_MAX
7853
7854
7855
Kapil Guptaee33bf12016-12-20 18:27:37 +05307856#ifdef WLAN_FEATURE_APFIND
7857/**
7858 * __wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
7859 * @wiphy: pointer to wireless wiphy structure.
7860 * @wdev: pointer to wireless_dev structure.
7861 * @data: pointer to apfind configuration data.
7862 * @data_len: the length in byte of apfind data.
7863 *
7864 * This is called when wlan driver needs to send APFIND configurations to
7865 * firmware.
7866 *
7867 * Return: An error code or 0 on success.
7868 */
7869static int __wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
7870 struct wireless_dev *wdev,
7871 const void *data, int data_len)
7872{
7873 struct sme_ap_find_request_req apfind_req;
7874 VOS_STATUS status;
7875 int ret_val;
7876 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7877
7878 ENTER();
7879
7880 ret_val = wlan_hdd_validate_context(hdd_ctx);
7881 if (ret_val)
7882 return ret_val;
7883
7884 if (VOS_FTM_MODE == hdd_get_conparam()) {
7885 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7886 return -EPERM;
7887 }
7888
7889 apfind_req.request_data_len = data_len;
7890 apfind_req.request_data = data;
7891
7892 status = sme_apfind_set_cmd(&apfind_req);
7893 if (VOS_STATUS_SUCCESS != status) {
7894 ret_val = -EIO;
7895 }
7896 return ret_val;
7897}
7898
7899/**
7900 * wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
7901 * @wiphy: pointer to wireless wiphy structure.
7902 * @wdev: pointer to wireless_dev structure.
7903 * @data: pointer to apfind configuration data.
7904 * @data_len: the length in byte of apfind data.
7905 *
7906 * This is called when wlan driver needs to send APFIND configurations to
7907 * firmware.
7908 *
7909 * Return: An error code or 0 on success.
7910 */
7911static int wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
7912 struct wireless_dev *wdev,
7913 const void *data, int data_len)
7914{
7915 int ret;
7916
7917 vos_ssr_protect(__func__);
7918 ret = __wlan_hdd_cfg80211_apfind_cmd(wiphy, wdev, data, data_len);
7919 vos_ssr_unprotect(__func__);
7920
7921 return ret;
7922}
7923#endif /* WLAN_FEATURE_APFIND */
Sunil Duttc69bccb2014-05-26 21:30:20 +05307924const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
7925{
Mukul Sharma2a271632014-10-13 14:59:01 +05307926 {
7927 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7928 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
7929 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7930 WIPHY_VENDOR_CMD_NEED_NETDEV |
7931 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307932 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05307933 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05307934
7935 {
7936 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7937 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
7938 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7939 WIPHY_VENDOR_CMD_NEED_NETDEV |
7940 WIPHY_VENDOR_CMD_NEED_RUNNING,
7941 .doit = wlan_hdd_cfg80211_nan_request
7942 },
7943
Sunil Duttc69bccb2014-05-26 21:30:20 +05307944#ifdef WLAN_FEATURE_LINK_LAYER_STATS
7945 {
7946 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7947 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
7948 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7949 WIPHY_VENDOR_CMD_NEED_NETDEV |
7950 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307951 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05307952 },
7953
7954 {
7955 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7956 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
7957 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7958 WIPHY_VENDOR_CMD_NEED_NETDEV |
7959 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307960 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05307961 },
7962
7963 {
7964 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7965 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
7966 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7967 WIPHY_VENDOR_CMD_NEED_NETDEV |
7968 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307969 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05307970 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05307971#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05307972#ifdef WLAN_FEATURE_EXTSCAN
7973 {
7974 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7975 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
7976 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7977 WIPHY_VENDOR_CMD_NEED_NETDEV |
7978 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307979 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05307980 },
7981 {
7982 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7983 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
7984 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7985 WIPHY_VENDOR_CMD_NEED_NETDEV |
7986 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307987 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05307988 },
7989 {
7990 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7991 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
7992 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7993 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307994 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05307995 },
7996 {
7997 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7998 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
7999 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8000 WIPHY_VENDOR_CMD_NEED_NETDEV |
8001 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308002 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05308003 },
8004 {
8005 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8006 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
8007 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8008 WIPHY_VENDOR_CMD_NEED_NETDEV |
8009 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308010 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05308011 },
8012 {
8013 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8014 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
8015 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8016 WIPHY_VENDOR_CMD_NEED_NETDEV |
8017 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308018 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308019 },
8020 {
8021 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8022 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
8023 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8024 WIPHY_VENDOR_CMD_NEED_NETDEV |
8025 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308026 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308027 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05308028 {
8029 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8030 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST,
8031 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8032 WIPHY_VENDOR_CMD_NEED_NETDEV |
8033 WIPHY_VENDOR_CMD_NEED_RUNNING,
8034 .doit = wlan_hdd_cfg80211_extscan_set_ssid_hotlist
8035 },
8036 {
8037 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8038 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST,
8039 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8040 WIPHY_VENDOR_CMD_NEED_NETDEV |
8041 WIPHY_VENDOR_CMD_NEED_RUNNING,
8042 .doit = wlan_hdd_cfg80211_extscan_reset_ssid_hotlist
8043 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308044#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308045/*EXT TDLS*/
8046 {
8047 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8048 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
8049 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8050 WIPHY_VENDOR_CMD_NEED_NETDEV |
8051 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308052 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05308053 },
8054 {
8055 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8056 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
8057 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8058 WIPHY_VENDOR_CMD_NEED_NETDEV |
8059 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308060 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05308061 },
8062 {
8063 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8064 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
8065 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8066 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308067 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05308068 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05308069 {
8070 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8071 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
8072 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8073 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308074 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05308075 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05308076 {
8077 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8078 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
8079 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8080 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308081 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05308082 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308083 {
8084 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8085 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
8086 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8087 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308088 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308089 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308090 {
8091 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8092 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
8093 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8094 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308095 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308096 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308097 {
8098 .info.vendor_id = QCA_NL80211_VENDOR_ID,
c_manjeecfd1efb2015-09-25 19:32:34 +05308099 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
8100 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8101 WIPHY_VENDOR_CMD_NEED_NETDEV |
8102 WIPHY_VENDOR_CMD_NEED_RUNNING,
8103 .doit = wlan_hdd_cfg80211_get_fw_mem_dump
8104 },
8105 {
8106 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308107 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
8108 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8109 WIPHY_VENDOR_CMD_NEED_NETDEV |
8110 WIPHY_VENDOR_CMD_NEED_RUNNING,
8111 .doit = wlan_hdd_cfg80211_setband
Sushant Kaushik8e644982015-09-23 12:18:54 +05308112 },
8113 {
8114 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8115 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
8116 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8117 WIPHY_VENDOR_CMD_NEED_NETDEV,
8118 .doit = wlan_hdd_cfg80211_wifi_logger_start
8119 },
Sushant Kaushik847890c2015-09-28 16:05:17 +05308120 {
8121 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8122 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
8123 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8124 WIPHY_VENDOR_CMD_NEED_NETDEV|
8125 WIPHY_VENDOR_CMD_NEED_RUNNING,
8126 .doit = wlan_hdd_cfg80211_get_wifi_info
Sachin Ahujac08f72a2015-09-22 15:25:47 +05308127 },
8128 {
8129 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8130 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
8131 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8132 WIPHY_VENDOR_CMD_NEED_NETDEV |
8133 WIPHY_VENDOR_CMD_NEED_RUNNING,
8134 .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308135 },
8136 {
8137 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8138 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,
8139 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8140 WIPHY_VENDOR_CMD_NEED_NETDEV |
8141 WIPHY_VENDOR_CMD_NEED_RUNNING,
8142 .doit = wlan_hdd_cfg80211_monitor_rssi
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308143 },
8144#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
8145 {
8146 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8147 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS,
8148 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8149 WIPHY_VENDOR_CMD_NEED_NETDEV |
8150 WIPHY_VENDOR_CMD_NEED_RUNNING,
8151 .doit = wlan_hdd_cfg80211_offloaded_packets
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308152 },
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308153#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308154 {
8155 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8156 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
8157 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8158 WIPHY_VENDOR_CMD_NEED_NETDEV |
8159 WIPHY_VENDOR_CMD_NEED_RUNNING,
8160 .doit = wlan_hdd_cfg80211_get_link_properties
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05308161 },
8162 {
8163 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8164 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION,
8165 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8166 WIPHY_VENDOR_CMD_NEED_NETDEV |
8167 WIPHY_VENDOR_CMD_NEED_RUNNING,
8168 .doit = wlan_hdd_cfg80211_wifi_configuration_set
Kapil Guptaee33bf12016-12-20 18:27:37 +05308169 },
8170#ifdef WLAN_FEATURE_APFIND
8171 {
8172 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8173 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_APFIND,
8174 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8175 WIPHY_VENDOR_CMD_NEED_NETDEV,
8176 .doit = wlan_hdd_cfg80211_apfind_cmd
8177 },
8178#endif /* WLAN_FEATURE_APFIND */
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308179 {
8180 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8181 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET,
8182 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8183 WIPHY_VENDOR_CMD_NEED_NETDEV |
8184 WIPHY_VENDOR_CMD_NEED_RUNNING,
8185 .doit = wlan_hdd_cfg80211_set_nud_stats
8186 },
8187 {
8188 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8189 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8190 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8191 WIPHY_VENDOR_CMD_NEED_NETDEV |
8192 WIPHY_VENDOR_CMD_NEED_RUNNING,
8193 .doit = wlan_hdd_cfg80211_get_nud_stats
8194 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308195};
8196
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008197/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05308198static const
8199struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008200{
8201#ifdef FEATURE_WLAN_CH_AVOID
8202 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05308203 .vendor_id = QCA_NL80211_VENDOR_ID,
8204 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008205 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308206#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
8207#ifdef WLAN_FEATURE_LINK_LAYER_STATS
8208 {
8209 /* Index = 1*/
8210 .vendor_id = QCA_NL80211_VENDOR_ID,
8211 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
8212 },
8213 {
8214 /* Index = 2*/
8215 .vendor_id = QCA_NL80211_VENDOR_ID,
8216 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
8217 },
8218 {
8219 /* Index = 3*/
8220 .vendor_id = QCA_NL80211_VENDOR_ID,
8221 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
8222 },
8223 {
8224 /* Index = 4*/
8225 .vendor_id = QCA_NL80211_VENDOR_ID,
8226 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
8227 },
8228 {
8229 /* Index = 5*/
8230 .vendor_id = QCA_NL80211_VENDOR_ID,
8231 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
8232 },
8233 {
8234 /* Index = 6*/
8235 .vendor_id = QCA_NL80211_VENDOR_ID,
8236 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
8237 },
8238#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308239#ifdef WLAN_FEATURE_EXTSCAN
8240 {
8241 .vendor_id = QCA_NL80211_VENDOR_ID,
8242 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
8243 },
8244 {
8245 .vendor_id = QCA_NL80211_VENDOR_ID,
8246 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
8247 },
8248 {
8249 .vendor_id = QCA_NL80211_VENDOR_ID,
8250 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
8251 },
8252 {
8253 .vendor_id = QCA_NL80211_VENDOR_ID,
8254 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
8255 },
8256 {
8257 .vendor_id = QCA_NL80211_VENDOR_ID,
8258 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
8259 },
8260 {
8261 .vendor_id = QCA_NL80211_VENDOR_ID,
8262 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
8263 },
8264 {
8265 .vendor_id = QCA_NL80211_VENDOR_ID,
8266 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
8267 },
8268 {
8269 .vendor_id = QCA_NL80211_VENDOR_ID,
8270 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
8271 },
8272 {
8273 .vendor_id = QCA_NL80211_VENDOR_ID,
8274 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
8275 },
8276 {
8277 .vendor_id = QCA_NL80211_VENDOR_ID,
8278 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
8279 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05308280 {
8281 .vendor_id = QCA_NL80211_VENDOR_ID,
8282 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST
8283 },
8284 {
8285 .vendor_id = QCA_NL80211_VENDOR_ID,
8286 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST
8287 },
8288 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND_INDEX] = {
8289 .vendor_id = QCA_NL80211_VENDOR_ID,
8290 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND
8291 },
8292 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST_INDEX] = {
8293 .vendor_id = QCA_NL80211_VENDOR_ID,
8294 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST
8295 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308296#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308297/*EXT TDLS*/
8298 {
8299 .vendor_id = QCA_NL80211_VENDOR_ID,
8300 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
8301 },
c_manjeecfd1efb2015-09-25 19:32:34 +05308302 [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
8303 .vendor_id = QCA_NL80211_VENDOR_ID,
8304 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
8305 },
8306
Srinivas Dasari030bad32015-02-18 23:23:54 +05308307
8308 {
8309 .vendor_id = QCA_NL80211_VENDOR_ID,
8310 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
8311 },
8312
Sushant Kaushik084f6592015-09-10 13:11:56 +05308313 {
8314 .vendor_id = QCA_NL80211_VENDOR_ID,
8315 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308316 },
8317 [QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = {
8318 .vendor_id = QCA_NL80211_VENDOR_ID,
8319 .subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI
8320 },
Padma, Santhosh Kumar7bbc7d92015-12-08 20:23:19 +05308321 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX] = {
8322 .vendor_id = QCA_NL80211_VENDOR_ID,
8323 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST
8324 },
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308325 [QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET_INDEX] = {
8326 .vendor_id = QCA_NL80211_VENDOR_ID,
8327 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8328 },
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008329};
8330
Jeff Johnson295189b2012-06-20 16:38:30 -07008331/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308332 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308333 * This function is called by hdd_wlan_startup()
8334 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308335 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07008336 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308337struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07008338{
8339 struct wiphy *wiphy;
8340 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308341 /*
8342 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07008343 */
8344 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
8345
8346 if (!wiphy)
8347 {
8348 /* Print error and jump into err label and free the memory */
8349 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
8350 return NULL;
8351 }
8352
Sunil Duttc69bccb2014-05-26 21:30:20 +05308353
Jeff Johnson295189b2012-06-20 16:38:30 -07008354 return wiphy;
8355}
8356
Anurag Chouhan343af7e2016-12-16 13:11:19 +05308357#if (LINUX_VERSION_CODE > KERNEL_VERSION(4,4,0)) || \
8358 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
8359/**
8360 * hdd_config_sched_scan_plans_to_wiphy() - configure sched scan plans to wiphy
8361 * @wiphy: pointer to wiphy
8362 * @config: pointer to config
8363 *
8364 * Return: None
8365 */
8366static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
8367 hdd_config_t *config)
8368{
8369 wiphy->max_sched_scan_plans = MAX_SCHED_SCAN_PLANS;
8370 if (config->max_sched_scan_plan_interval)
8371 wiphy->max_sched_scan_plan_interval =
8372 config->max_sched_scan_plan_interval;
8373 if (config->max_sched_scan_plan_iterations)
8374 wiphy->max_sched_scan_plan_iterations =
8375 config->max_sched_scan_plan_iterations;
8376}
8377#else
8378static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
8379 hdd_config_t *config)
8380{
8381}
8382#endif
8383
Jeff Johnson295189b2012-06-20 16:38:30 -07008384/*
8385 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308386 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07008387 * private ioctl to change the band value
8388 */
8389int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
8390{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308391 int i, j;
8392 eNVChannelEnabledType channelEnabledState;
8393
Jeff Johnsone7245742012-09-05 17:12:55 -07008394 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308395
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308396 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07008397 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308398
8399 if (NULL == wiphy->bands[i])
8400 {
8401 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
8402 __func__, i);
8403 continue;
8404 }
8405
8406 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
8407 {
8408 struct ieee80211_supported_band *band = wiphy->bands[i];
8409
8410 channelEnabledState = vos_nv_getChannelEnabledState(
8411 band->channels[j].hw_value);
8412
8413 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
8414 {
Abhishek Singh678227a2014-11-04 10:52:38 +05308415 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308416 continue;
8417 }
8418 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
8419 {
8420 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8421 continue;
8422 }
8423
8424 if (NV_CHANNEL_DISABLE == channelEnabledState ||
8425 NV_CHANNEL_INVALID == channelEnabledState)
8426 {
8427 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8428 }
8429 else if (NV_CHANNEL_DFS == channelEnabledState)
8430 {
8431 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
8432 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
8433 }
8434 else
8435 {
8436 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
8437 |IEEE80211_CHAN_RADAR);
8438 }
8439 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008440 }
8441 return 0;
8442}
8443/*
8444 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308445 * This function is called by hdd_wlan_startup()
8446 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07008447 * This function is used to initialize and register wiphy structure.
8448 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308449int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07008450 struct wiphy *wiphy,
8451 hdd_config_t *pCfg
8452 )
8453{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308454 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05308455 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
8456
Jeff Johnsone7245742012-09-05 17:12:55 -07008457 ENTER();
8458
Jeff Johnson295189b2012-06-20 16:38:30 -07008459 /* Now bind the underlying wlan device with wiphy */
8460 set_wiphy_dev(wiphy, dev);
8461
8462 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07008463
Kiet Lam6c583332013-10-14 05:37:09 +05308464#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07008465 /* the flag for the other case would be initialzed in
8466 vos_init_wiphy_from_nv_bin */
Manjeet Singh9e19de62016-08-18 18:26:41 +05308467#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
8468 wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
8469#else
Amar Singhal0a402232013-10-11 20:57:16 -07008470 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05308471#endif
Manjeet Singh9e19de62016-08-18 18:26:41 +05308472#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07008473
Amar Singhalfddc28c2013-09-05 13:03:40 -07008474 /* This will disable updating of NL channels from passive to
8475 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308476#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
8477 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
8478#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07008479 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308480#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07008481
Amar Singhala49cbc52013-10-08 18:37:44 -07008482
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008483#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07008484 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
8485 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
8486 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07008487 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308488#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Rajeev Kumar Sirasanagandla0d6dd752016-08-17 15:01:39 +05308489 wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308490#else
8491 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
8492#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008493#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07008494
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08008495#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07008496 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08008497#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07008498 || pCfg->isFastRoamIniFeatureEnabled
8499#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08008500#ifdef FEATURE_WLAN_ESE
8501 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07008502#endif
8503 )
8504 {
8505 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
8506 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08008507#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008508#ifdef FEATURE_WLAN_TDLS
8509 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
8510 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
8511#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308512#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05308513 if (pCfg->configPNOScanSupport)
8514 {
8515 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
8516 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
8517 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
8518 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
8519 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308520#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008521
Abhishek Singh10d85972015-04-17 10:27:23 +05308522#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
8523 wiphy->features |= NL80211_FEATURE_HT_IBSS;
8524#endif
8525
Amar Singhalfddc28c2013-09-05 13:03:40 -07008526#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07008527 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
8528 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07008529 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07008530 driver need to determine what to do with both
8531 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07008532
8533 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07008534#else
8535 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07008536#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008537
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308538 wiphy->max_scan_ssids = MAX_SCAN_SSID;
8539
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05308540 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07008541
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308542 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
8543
Jeff Johnson295189b2012-06-20 16:38:30 -07008544 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05308545 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
8546 | BIT(NL80211_IFTYPE_ADHOC)
8547 | BIT(NL80211_IFTYPE_P2P_CLIENT)
8548 | BIT(NL80211_IFTYPE_P2P_GO)
8549 | BIT(NL80211_IFTYPE_AP);
8550
8551 if (VOS_MONITOR_MODE == hdd_get_conparam())
8552 {
8553 wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
8554 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008555
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308556 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008557 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308558#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
8559 if( pCfg->enableMCC )
8560 {
8561 /* Currently, supports up to two channels */
8562 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008563
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308564 if( !pCfg->allowMCCGODiffBI )
8565 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008566
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308567 }
8568 wiphy->iface_combinations = &wlan_hdd_iface_combination;
8569 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008570#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308571 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008572
Jeff Johnson295189b2012-06-20 16:38:30 -07008573 /* Before registering we need to update the ht capabilitied based
8574 * on ini values*/
8575 if( !pCfg->ShortGI20MhzEnable )
8576 {
8577 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
8578 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
Jeff Johnson295189b2012-06-20 16:38:30 -07008579 }
8580
8581 if( !pCfg->ShortGI40MhzEnable )
8582 {
8583 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
8584 }
8585
8586 if( !pCfg->nChannelBondingMode5GHz )
8587 {
8588 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
8589 }
Agrawal Ashish97dec502015-11-26 20:20:58 +05308590 /*
8591 * In case of static linked driver at the time of driver unload,
8592 * module exit doesn't happens. Module cleanup helps in cleaning
8593 * of static memory.
8594 * If driver load happens statically, at the time of driver unload,
8595 * wiphy flags don't get reset because of static memory.
8596 * It's better not to store channel in static memory.
8597 */
8598 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
8599 wiphy->bands[IEEE80211_BAND_2GHZ]->channels =
8600 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_2_4_GHZ));
8601 if (wiphy->bands[IEEE80211_BAND_2GHZ]->channels == NULL)
8602 {
8603 hddLog(VOS_TRACE_LEVEL_ERROR,
8604 FL("Not enough memory to allocate channels"));
8605 return -ENOMEM;
8606 }
8607 vos_mem_copy(wiphy->bands[IEEE80211_BAND_2GHZ]->channels,
8608 &hdd_channels_2_4_GHZ[0],
8609 sizeof(hdd_channels_2_4_GHZ));
Jeff Johnson295189b2012-06-20 16:38:30 -07008610
Agrawal Ashish97dec502015-11-26 20:20:58 +05308611 if (true == hdd_is_5g_supported(pHddCtx))
8612 {
8613 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
8614 wiphy->bands[IEEE80211_BAND_5GHZ]->channels =
8615 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_5_GHZ));
8616 if (wiphy->bands[IEEE80211_BAND_5GHZ]->channels == NULL)
8617 {
8618 hddLog(VOS_TRACE_LEVEL_ERROR,
8619 FL("Not enough memory to allocate channels"));
8620 vos_mem_free(wiphy->bands[IEEE80211_BAND_2GHZ]->channels);
8621 wiphy->bands[IEEE80211_BAND_2GHZ]->channels = NULL;
8622 return -ENOMEM;
8623 }
8624 vos_mem_copy(wiphy->bands[IEEE80211_BAND_5GHZ]->channels,
8625 &hdd_channels_5_GHZ[0],
8626 sizeof(hdd_channels_5_GHZ));
8627 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308628
8629 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
8630 {
8631
8632 if (NULL == wiphy->bands[i])
8633 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05308634 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308635 __func__, i);
8636 continue;
8637 }
8638
8639 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
8640 {
8641 struct ieee80211_supported_band *band = wiphy->bands[i];
8642
8643 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
8644 {
8645 // Enable social channels for P2P
8646 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
8647 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
8648 else
8649 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8650 continue;
8651 }
8652 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
8653 {
8654 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8655 continue;
8656 }
8657 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008658 }
8659 /*Initialise the supported cipher suite details*/
8660 wiphy->cipher_suites = hdd_cipher_suites;
8661 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
8662
8663 /*signal strength in mBm (100*dBm) */
8664 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
8665
8666#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05308667 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07008668#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008669
Sunil Duttc69bccb2014-05-26 21:30:20 +05308670 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
8671 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008672 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
8673 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
8674
Anurag Chouhan343af7e2016-12-16 13:11:19 +05308675 hdd_config_sched_scan_plans_to_wiphy(wiphy, pCfg);
8676
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308677 EXIT();
8678 return 0;
8679}
8680
8681/* In this function we are registering wiphy. */
8682int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
8683{
8684 ENTER();
8685 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008686 if (0 > wiphy_register(wiphy))
8687 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308688 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07008689 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8690 return -EIO;
8691 }
8692
8693 EXIT();
8694 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308695}
Jeff Johnson295189b2012-06-20 16:38:30 -07008696
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308697/* In this function we are updating channel list when,
8698 regulatory domain is FCC and country code is US.
8699 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
8700 As per FCC smart phone is not a indoor device.
8701 GO should not opeate on indoor channels */
8702void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
8703{
8704 int j;
8705 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
8706 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
8707 //Default counrtycode from NV at the time of wiphy initialization.
8708 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
8709 &defaultCountryCode[0]))
8710 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008711 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308712 }
8713 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
8714 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308715 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
8716 {
8717 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
8718 return;
8719 }
8720 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
8721 {
8722 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
8723 // Mark UNII -1 band channel as passive
8724 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
8725 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
8726 }
8727 }
8728}
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05308729/* This function registers for all frame which supplicant is interested in */
8730void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008731{
Jeff Johnson295189b2012-06-20 16:38:30 -07008732 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8733 /* Register for all P2P action, public action etc frames */
8734 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
Jeff Johnsone7245742012-09-05 17:12:55 -07008735 ENTER();
Abhishek Singh16e05762015-11-30 14:29:27 +05308736 /* Register frame indication call back */
8737 sme_register_mgmt_frame_ind_callback(hHal, hdd_indicate_mgmt_frame);
Jeff Johnson295189b2012-06-20 16:38:30 -07008738 /* Right now we are registering these frame when driver is getting
8739 initialized. Once we will move to 2.6.37 kernel, in which we have
8740 frame register ops, we will move this code as a part of that */
8741 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308742 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07008743 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
8744
8745 /* GAS Initial Response */
8746 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8747 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308748
Jeff Johnson295189b2012-06-20 16:38:30 -07008749 /* GAS Comeback Request */
8750 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8751 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
8752
8753 /* GAS Comeback Response */
8754 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8755 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
8756
8757 /* P2P Public Action */
8758 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308759 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07008760 P2P_PUBLIC_ACTION_FRAME_SIZE );
8761
8762 /* P2P Action */
8763 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8764 (v_U8_t*)P2P_ACTION_FRAME,
8765 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07008766
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05308767 /* WNM BSS Transition Request frame */
8768 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8769 (v_U8_t*)WNM_BSS_ACTION_FRAME,
8770 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07008771
8772 /* WNM-Notification */
8773 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8774 (v_U8_t*)WNM_NOTIFICATION_FRAME,
8775 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008776}
8777
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05308778void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008779{
Jeff Johnson295189b2012-06-20 16:38:30 -07008780 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8781 /* Register for all P2P action, public action etc frames */
8782 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
8783
Jeff Johnsone7245742012-09-05 17:12:55 -07008784 ENTER();
8785
Jeff Johnson295189b2012-06-20 16:38:30 -07008786 /* Right now we are registering these frame when driver is getting
8787 initialized. Once we will move to 2.6.37 kernel, in which we have
8788 frame register ops, we will move this code as a part of that */
8789 /* GAS Initial Request */
8790
8791 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8792 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
8793
8794 /* GAS Initial Response */
8795 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8796 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308797
Jeff Johnson295189b2012-06-20 16:38:30 -07008798 /* GAS Comeback Request */
8799 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8800 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
8801
8802 /* GAS Comeback Response */
8803 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8804 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
8805
8806 /* P2P Public Action */
8807 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308808 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07008809 P2P_PUBLIC_ACTION_FRAME_SIZE );
8810
8811 /* P2P Action */
8812 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8813 (v_U8_t*)P2P_ACTION_FRAME,
8814 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07008815 /* WNM-Notification */
8816 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8817 (v_U8_t*)WNM_NOTIFICATION_FRAME,
8818 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008819}
8820
8821#ifdef FEATURE_WLAN_WAPI
8822void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05308823 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07008824{
8825 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8826 tCsrRoamSetKey setKey;
8827 v_BOOL_t isConnected = TRUE;
8828 int status = 0;
8829 v_U32_t roamId= 0xFF;
8830 tANI_U8 *pKeyPtr = NULL;
8831 int n = 0;
8832
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308833 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
8834 __func__, hdd_device_modetoString(pAdapter->device_mode),
8835 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008836
Gopichand Nakkalae7480202013-02-11 15:24:22 +05308837 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07008838 setKey.keyId = key_index; // Store Key ID
8839 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
8840 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
8841 setKey.paeRole = 0 ; // the PAE role
8842 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
8843 {
8844 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
8845 }
8846 else
8847 {
8848 isConnected = hdd_connIsConnected(pHddStaCtx);
8849 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
8850 }
8851 setKey.keyLength = key_Len;
8852 pKeyPtr = setKey.Key;
8853 memcpy( pKeyPtr, key, key_Len);
8854
Arif Hussain6d2a3322013-11-17 19:50:10 -08008855 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07008856 __func__, key_Len);
8857 for (n = 0 ; n < key_Len; n++)
8858 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
8859 __func__,n,setKey.Key[n]);
8860
8861 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8862 if ( isConnected )
8863 {
8864 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8865 pAdapter->sessionId, &setKey, &roamId );
8866 }
8867 if ( status != 0 )
8868 {
8869 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8870 "[%4d] sme_RoamSetKey returned ERROR status= %d",
8871 __LINE__, status );
8872 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8873 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308874 /* Need to clear any trace of key value in the memory.
8875 * Thus zero out the memory even though it is local
8876 * variable.
8877 */
8878 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07008879}
8880#endif /* FEATURE_WLAN_WAPI*/
8881
8882#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308883int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07008884 beacon_data_t **ppBeacon,
8885 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008886#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308887int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008888 beacon_data_t **ppBeacon,
8889 struct cfg80211_beacon_data *params,
8890 int dtim_period)
8891#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308892{
Jeff Johnson295189b2012-06-20 16:38:30 -07008893 int size;
8894 beacon_data_t *beacon = NULL;
8895 beacon_data_t *old = NULL;
Kapil Gupta137ef892016-12-13 19:38:00 +05308896 int head_len, tail_len, proberesp_ies_len, assocresp_ies_len;
8897 const u8 *head, *tail, *proberesp_ies, *assocresp_ies;
Jeff Johnson295189b2012-06-20 16:38:30 -07008898
Jeff Johnsone7245742012-09-05 17:12:55 -07008899 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008900 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308901 {
8902 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8903 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008904 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308905 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008906
8907 old = pAdapter->sessionCtx.ap.beacon;
8908
8909 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308910 {
8911 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8912 FL("session(%d) old and new heads points to NULL"),
8913 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008914 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308915 }
8916
8917 if (params->tail && !params->tail_len)
8918 {
8919 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8920 FL("tail_len is zero but tail is not NULL"));
8921 return -EINVAL;
8922 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008923
Jeff Johnson295189b2012-06-20 16:38:30 -07008924#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
8925 /* Kernel 3.0 is not updating dtim_period for set beacon */
8926 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308927 {
8928 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8929 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008930 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308931 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008932#endif
8933
Kapil Gupta137ef892016-12-13 19:38:00 +05308934 if (params->head)
8935 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008936 head_len = params->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05308937 head = params->head;
8938 } else
8939 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008940 head_len = old->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05308941 head = old->head;
8942 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008943
Kapil Gupta137ef892016-12-13 19:38:00 +05308944 if (params->tail || !old)
8945 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008946 tail_len = params->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05308947 tail = params->tail;
8948 } else
8949 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008950 tail_len = old->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05308951 tail = old->tail;
8952 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008953
Kapil Gupta137ef892016-12-13 19:38:00 +05308954 if (params->proberesp_ies || !old)
8955 {
8956 proberesp_ies_len = params->proberesp_ies_len;
8957 proberesp_ies = params->proberesp_ies;
8958 } else
8959 {
8960 proberesp_ies_len = old->proberesp_ies_len;
8961 proberesp_ies = old->proberesp_ies;
8962 }
8963
8964 if (params->assocresp_ies || !old)
8965 {
8966 assocresp_ies_len = params->assocresp_ies_len;
8967 assocresp_ies = params->assocresp_ies;
8968 } else
8969 {
8970 assocresp_ies_len = old->assocresp_ies_len;
8971 assocresp_ies = old->assocresp_ies;
8972 }
8973
8974 size = sizeof(beacon_data_t) + head_len + tail_len +
8975 proberesp_ies_len + assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07008976
8977 beacon = kzalloc(size, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07008978 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308979 {
8980 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8981 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008982 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308983 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008984
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008985#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Kapil Gupta137ef892016-12-13 19:38:00 +05308986 if (params->dtim_period)
Jeff Johnson295189b2012-06-20 16:38:30 -07008987 beacon->dtim_period = params->dtim_period;
8988 else
8989 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008990#else
Kapil Gupta137ef892016-12-13 19:38:00 +05308991 if (dtim_period)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008992 beacon->dtim_period = dtim_period;
8993 else
8994 beacon->dtim_period = old->dtim_period;
8995#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308996
Jeff Johnson295189b2012-06-20 16:38:30 -07008997 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
8998 beacon->tail = beacon->head + head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05308999 beacon->proberesp_ies = beacon->tail + tail_len;
9000 beacon->assocresp_ies = beacon->proberesp_ies + proberesp_ies_len;
9001
Jeff Johnson295189b2012-06-20 16:38:30 -07009002 beacon->head_len = head_len;
9003 beacon->tail_len = tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309004 beacon->proberesp_ies_len = proberesp_ies_len;
9005 beacon->assocresp_ies_len= assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009006
c_manjee527ecac2017-01-25 12:25:27 +05309007 if (head && head_len)
9008 memcpy(beacon->head, head, head_len);
9009 if (tail && tail_len)
9010 memcpy(beacon->tail, tail, tail_len);
9011 if (proberesp_ies && proberesp_ies_len)
9012 memcpy(beacon->proberesp_ies, proberesp_ies, proberesp_ies_len);
9013 if (assocresp_ies && assocresp_ies_len)
9014 memcpy(beacon->assocresp_ies, assocresp_ies, assocresp_ies_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009015
9016 *ppBeacon = beacon;
9017
9018 kfree(old);
9019
9020 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009021}
Jeff Johnson295189b2012-06-20 16:38:30 -07009022
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309023v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
9024#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
9025 const v_U8_t *pIes,
9026#else
9027 v_U8_t *pIes,
9028#endif
9029 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009030{
9031 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309032 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07009033 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309034
Jeff Johnson295189b2012-06-20 16:38:30 -07009035 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309036 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009037 elem_id = ptr[0];
9038 elem_len = ptr[1];
9039 left -= 2;
9040 if(elem_len > left)
9041 {
9042 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07009043 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009044 eid,elem_len,left);
9045 return NULL;
9046 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309047 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009048 {
9049 return ptr;
9050 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309051
Jeff Johnson295189b2012-06-20 16:38:30 -07009052 left -= elem_len;
9053 ptr += (elem_len + 2);
9054 }
9055 return NULL;
9056}
9057
Jeff Johnson295189b2012-06-20 16:38:30 -07009058/* Check if rate is 11g rate or not */
9059static int wlan_hdd_rate_is_11g(u8 rate)
9060{
Sanjay Devnani28322e22013-06-21 16:13:40 -07009061 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009062 u8 i;
9063 for (i = 0; i < 8; i++)
9064 {
9065 if(rate == gRateArray[i])
9066 return TRUE;
9067 }
9068 return FALSE;
9069}
9070
9071/* Check for 11g rate and set proper 11g only mode */
9072static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
9073 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
9074{
9075 u8 i, num_rates = pIe[0];
9076
9077 pIe += 1;
9078 for ( i = 0; i < num_rates; i++)
9079 {
9080 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
9081 {
9082 /* If rate set have 11g rate than change the mode to 11G */
9083 *pSapHw_mode = eSAP_DOT11_MODE_11g;
9084 if (pIe[i] & BASIC_RATE_MASK)
9085 {
9086 /* If we have 11g rate as basic rate, it means mode
9087 is 11g only mode.
9088 */
9089 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
9090 *pCheckRatesfor11g = FALSE;
9091 }
9092 }
9093 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
9094 {
9095 *require_ht = TRUE;
9096 }
9097 }
9098 return;
9099}
9100
9101static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
9102{
9103 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9104 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9105 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9106 u8 checkRatesfor11g = TRUE;
9107 u8 require_ht = FALSE;
9108 u8 *pIe=NULL;
9109
9110 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
9111
9112 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
9113 pBeacon->head_len, WLAN_EID_SUPP_RATES);
9114 if (pIe != NULL)
9115 {
9116 pIe += 1;
9117 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9118 &pConfig->SapHw_mode);
9119 }
9120
9121 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9122 WLAN_EID_EXT_SUPP_RATES);
9123 if (pIe != NULL)
9124 {
9125
9126 pIe += 1;
9127 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9128 &pConfig->SapHw_mode);
9129 }
9130
9131 if( pConfig->channel > 14 )
9132 {
9133 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
9134 }
9135
9136 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9137 WLAN_EID_HT_CAPABILITY);
9138
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309139 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009140 {
9141 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
9142 if(require_ht)
9143 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
9144 }
9145}
9146
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309147static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
9148 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
9149{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009150 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309151 v_U8_t *pIe = NULL;
9152 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9153
9154 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
9155 pBeacon->tail, pBeacon->tail_len);
9156
9157 if (pIe)
9158 {
9159 ielen = pIe[1] + 2;
9160 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9161 {
9162 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
9163 }
9164 else
9165 {
9166 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
9167 return -EINVAL;
9168 }
9169 *total_ielen += ielen;
9170 }
9171 return 0;
9172}
9173
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009174static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
9175 v_U8_t *genie, v_U8_t *total_ielen)
9176{
9177 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9178 int left = pBeacon->tail_len;
9179 v_U8_t *ptr = pBeacon->tail;
9180 v_U8_t elem_id, elem_len;
9181 v_U16_t ielen = 0;
9182
9183 if ( NULL == ptr || 0 == left )
9184 return;
9185
9186 while (left >= 2)
9187 {
9188 elem_id = ptr[0];
9189 elem_len = ptr[1];
9190 left -= 2;
9191 if (elem_len > left)
9192 {
9193 hddLog( VOS_TRACE_LEVEL_ERROR,
9194 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
9195 elem_id, elem_len, left);
9196 return;
9197 }
9198 if (IE_EID_VENDOR == elem_id)
9199 {
9200 /* skipping the VSIE's which we don't want to include or
9201 * it will be included by existing code
9202 */
9203 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
9204#ifdef WLAN_FEATURE_WFD
9205 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
9206#endif
9207 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9208 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9209 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
9210 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9211 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
9212 {
9213 ielen = ptr[1] + 2;
9214 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9215 {
9216 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
9217 *total_ielen += ielen;
9218 }
9219 else
9220 {
9221 hddLog( VOS_TRACE_LEVEL_ERROR,
9222 "IE Length is too big "
9223 "IEs eid=%d elem_len=%d total_ie_lent=%d",
9224 elem_id, elem_len, *total_ielen);
9225 }
9226 }
9227 }
9228
9229 left -= elem_len;
9230 ptr += (elem_len + 2);
9231 }
9232 return;
9233}
9234
Kapil Gupta137ef892016-12-13 19:38:00 +05309235int wlan_hdd_cfg80211_update_apies(hdd_adapter_t *pHostapdAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009236{
9237 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309238 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009239 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07009240 int ret = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +05309241 beacon_data_t *pBeacon = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009242
9243 genie = vos_mem_malloc(MAX_GENIE_LEN);
9244
9245 if(genie == NULL) {
9246
9247 return -ENOMEM;
9248 }
9249
Kapil Gupta137ef892016-12-13 19:38:00 +05309250 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309251 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9252 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009253 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309254 hddLog(LOGE,
9255 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309256 ret = -EINVAL;
9257 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009258 }
9259
9260#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309261 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9262 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
9263 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309264 hddLog(LOGE,
9265 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309266 ret = -EINVAL;
9267 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009268 }
9269#endif
9270
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309271 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9272 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009273 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309274 hddLog(LOGE,
9275 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309276 ret = -EINVAL;
9277 goto done;
9278 }
9279
9280 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
9281 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009282 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07009283 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009284
9285 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9286 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
9287 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
9288 {
9289 hddLog(LOGE,
9290 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009291 ret = -EINVAL;
9292 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009293 }
9294
9295 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9296 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
9297 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9298 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9299 ==eHAL_STATUS_FAILURE)
9300 {
9301 hddLog(LOGE,
9302 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009303 ret = -EINVAL;
9304 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009305 }
9306
9307 // Added for ProResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +05309308 if ((pBeacon->proberesp_ies != NULL) && (pBeacon->proberesp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009309 {
Kapil Gupta137ef892016-12-13 19:38:00 +05309310 u16 rem_probe_resp_ie_len = pBeacon->proberesp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009311 u8 probe_rsp_ie_len[3] = {0};
9312 u8 counter = 0;
9313 /* Check Probe Resp Length if it is greater then 255 then Store
9314 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
9315 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
9316 Store More then 255 bytes into One Variable.
9317 */
9318 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
9319 {
9320 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
9321 {
9322 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
9323 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
9324 }
9325 else
9326 {
9327 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
9328 rem_probe_resp_ie_len = 0;
9329 }
9330 }
9331
9332 rem_probe_resp_ie_len = 0;
9333
9334 if (probe_rsp_ie_len[0] > 0)
9335 {
9336 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9337 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
Kapil Gupta137ef892016-12-13 19:38:00 +05309338 (tANI_U8*)&pBeacon->
9339 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07009340 probe_rsp_ie_len[0], NULL,
9341 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9342 {
9343 hddLog(LOGE,
9344 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009345 ret = -EINVAL;
9346 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009347 }
9348 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
9349 }
9350
9351 if (probe_rsp_ie_len[1] > 0)
9352 {
9353 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9354 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
Kapil Gupta137ef892016-12-13 19:38:00 +05309355 (tANI_U8*)&pBeacon->
9356 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07009357 probe_rsp_ie_len[1], NULL,
9358 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9359 {
9360 hddLog(LOGE,
9361 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009362 ret = -EINVAL;
9363 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009364 }
9365 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
9366 }
9367
9368 if (probe_rsp_ie_len[2] > 0)
9369 {
9370 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9371 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
Kapil Gupta137ef892016-12-13 19:38:00 +05309372 (tANI_U8*)&pBeacon->
9373 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07009374 probe_rsp_ie_len[2], NULL,
9375 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9376 {
9377 hddLog(LOGE,
9378 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009379 ret = -EINVAL;
9380 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009381 }
9382 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
9383 }
9384
9385 if (probe_rsp_ie_len[1] == 0 )
9386 {
9387 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9388 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
9389 eANI_BOOLEAN_FALSE) )
9390 {
9391 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009392 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009393 }
9394 }
9395
9396 if (probe_rsp_ie_len[2] == 0 )
9397 {
9398 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9399 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
9400 eANI_BOOLEAN_FALSE) )
9401 {
9402 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009403 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009404 }
9405 }
9406
9407 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9408 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
9409 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9410 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9411 == eHAL_STATUS_FAILURE)
9412 {
9413 hddLog(LOGE,
9414 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009415 ret = -EINVAL;
9416 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009417 }
9418 }
9419 else
9420 {
9421 // Reset WNI_CFG_PROBE_RSP Flags
9422 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
9423
9424 hddLog(VOS_TRACE_LEVEL_INFO,
9425 "%s: No Probe Response IE received in set beacon",
9426 __func__);
9427 }
9428
9429 // Added for AssocResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +05309430 if ((pBeacon->assocresp_ies != NULL) && (pBeacon->assocresp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009431 {
9432 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
Kapil Gupta137ef892016-12-13 19:38:00 +05309433 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)pBeacon->assocresp_ies,
9434 pBeacon->assocresp_ies_len, NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -07009435 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9436 {
9437 hddLog(LOGE,
9438 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009439 ret = -EINVAL;
9440 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009441 }
9442
9443 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9444 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
9445 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9446 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9447 == eHAL_STATUS_FAILURE)
9448 {
9449 hddLog(LOGE,
9450 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009451 ret = -EINVAL;
9452 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009453 }
9454 }
9455 else
9456 {
9457 hddLog(VOS_TRACE_LEVEL_INFO,
9458 "%s: No Assoc Response IE received in set beacon",
9459 __func__);
9460
9461 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9462 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
9463 eANI_BOOLEAN_FALSE) )
9464 {
9465 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009466 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009467 }
9468 }
9469
Jeff Johnsone7245742012-09-05 17:12:55 -07009470done:
Jeff Johnson295189b2012-06-20 16:38:30 -07009471 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309472 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009473}
Jeff Johnson295189b2012-06-20 16:38:30 -07009474
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309475/*
Jeff Johnson295189b2012-06-20 16:38:30 -07009476 * FUNCTION: wlan_hdd_validate_operation_channel
9477 * called by wlan_hdd_cfg80211_start_bss() and
9478 * wlan_hdd_cfg80211_set_channel()
9479 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309480 * channel list.
9481 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07009482VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07009483{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309484
Jeff Johnson295189b2012-06-20 16:38:30 -07009485 v_U32_t num_ch = 0;
9486 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
9487 u32 indx = 0;
9488 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309489 v_U8_t fValidChannel = FALSE, count = 0;
9490 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309491
Jeff Johnson295189b2012-06-20 16:38:30 -07009492 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
9493
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309494 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07009495 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309496 /* Validate the channel */
9497 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07009498 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309499 if ( channel == rfChannels[count].channelNum )
9500 {
9501 fValidChannel = TRUE;
9502 break;
9503 }
9504 }
9505 if (fValidChannel != TRUE)
9506 {
9507 hddLog(VOS_TRACE_LEVEL_ERROR,
9508 "%s: Invalid Channel [%d]", __func__, channel);
9509 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009510 }
9511 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309512 else
Jeff Johnson295189b2012-06-20 16:38:30 -07009513 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309514 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
9515 valid_ch, &num_ch))
9516 {
9517 hddLog(VOS_TRACE_LEVEL_ERROR,
9518 "%s: failed to get valid channel list", __func__);
9519 return VOS_STATUS_E_FAILURE;
9520 }
9521 for (indx = 0; indx < num_ch; indx++)
9522 {
9523 if (channel == valid_ch[indx])
9524 {
9525 break;
9526 }
9527 }
9528
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05309529 if (indx >= num_ch)
9530 {
9531 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
9532 {
9533 eCsrBand band;
9534 unsigned int freq;
9535
9536 sme_GetFreqBand(hHal, &band);
9537
9538 if (eCSR_BAND_5G == band)
9539 {
9540#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
9541 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
9542 {
9543 freq = ieee80211_channel_to_frequency(channel,
9544 IEEE80211_BAND_2GHZ);
9545 }
9546 else
9547 {
9548 freq = ieee80211_channel_to_frequency(channel,
9549 IEEE80211_BAND_5GHZ);
9550 }
9551#else
9552 freq = ieee80211_channel_to_frequency(channel);
9553#endif
9554 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
9555 return VOS_STATUS_SUCCESS;
9556 }
9557 }
9558
9559 hddLog(VOS_TRACE_LEVEL_ERROR,
9560 "%s: Invalid Channel [%d]", __func__, channel);
9561 return VOS_STATUS_E_FAILURE;
9562 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009563 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05309564
Jeff Johnson295189b2012-06-20 16:38:30 -07009565 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309566
Jeff Johnson295189b2012-06-20 16:38:30 -07009567}
9568
Viral Modi3a32cc52013-02-08 11:14:52 -08009569/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309570 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08009571 * This function is used to set the channel number
9572 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309573static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08009574 struct ieee80211_channel *chan,
9575 enum nl80211_channel_type channel_type
9576 )
9577{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309578 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08009579 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07009580 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08009581 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309582 hdd_context_t *pHddCtx;
9583 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009584
9585 ENTER();
9586
9587 if( NULL == dev )
9588 {
9589 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009590 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08009591 return -ENODEV;
9592 }
9593 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309594
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309595 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9596 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
9597 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08009598 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309599 "%s: device_mode = %s (%d) freq = %d", __func__,
9600 hdd_device_modetoString(pAdapter->device_mode),
9601 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309602
9603 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9604 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309605 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08009606 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309607 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009608 }
9609
9610 /*
9611 * Do freq to chan conversion
9612 * TODO: for 11a
9613 */
9614
9615 channel = ieee80211_frequency_to_channel(freq);
9616
9617 /* Check freq range */
9618 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
9619 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
9620 {
9621 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009622 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08009623 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
9624 WNI_CFG_CURRENT_CHANNEL_STAMAX);
9625 return -EINVAL;
9626 }
9627
9628 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
9629
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05309630 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
9631 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08009632 {
9633 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
9634 {
9635 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009636 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08009637 return -EINVAL;
9638 }
9639 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
9640 "%s: set channel to [%d] for device mode =%d",
9641 __func__, channel,pAdapter->device_mode);
9642 }
9643 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08009644 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08009645 )
9646 {
9647 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9648 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
9649 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9650
9651 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
9652 {
9653 /* Link is up then return cant set channel*/
9654 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009655 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08009656 return -EINVAL;
9657 }
9658
9659 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
9660 pHddStaCtx->conn_info.operationChannel = channel;
9661 pRoamProfile->ChannelInfo.ChannelList =
9662 &pHddStaCtx->conn_info.operationChannel;
9663 }
9664 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08009665 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08009666 )
9667 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309668 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
9669 {
9670 if(VOS_STATUS_SUCCESS !=
9671 wlan_hdd_validate_operation_channel(pAdapter,channel))
9672 {
9673 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009674 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309675 return -EINVAL;
9676 }
9677 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
9678 }
9679 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08009680 {
9681 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
9682
9683 /* If auto channel selection is configured as enable/ 1 then ignore
9684 channel set by supplicant
9685 */
9686 if ( cfg_param->apAutoChannelSelection )
9687 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309688 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
9689 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08009690 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309691 "%s: set channel to auto channel (0) for device mode =%s (%d)",
9692 __func__, hdd_device_modetoString(pAdapter->device_mode),
9693 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08009694 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309695 else
9696 {
9697 if(VOS_STATUS_SUCCESS !=
9698 wlan_hdd_validate_operation_channel(pAdapter,channel))
9699 {
9700 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009701 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309702 return -EINVAL;
9703 }
9704 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
9705 }
Viral Modi3a32cc52013-02-08 11:14:52 -08009706 }
9707 }
9708 else
9709 {
9710 hddLog(VOS_TRACE_LEVEL_FATAL,
9711 "%s: Invalid device mode failed to set valid channel", __func__);
9712 return -EINVAL;
9713 }
9714 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309715 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009716}
9717
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309718static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
9719 struct net_device *dev,
9720 struct ieee80211_channel *chan,
9721 enum nl80211_channel_type channel_type
9722 )
9723{
9724 int ret;
9725
9726 vos_ssr_protect(__func__);
9727 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
9728 vos_ssr_unprotect(__func__);
9729
9730 return ret;
9731}
9732
Anurag Chouhan83026002016-12-13 22:46:21 +05309733#ifdef DHCP_SERVER_OFFLOAD
9734void hdd_dhcp_server_offload_done(void *fw_dhcp_srv_offload_cb_context,
9735 VOS_STATUS status)
9736{
9737 hdd_adapter_t* adapter = (hdd_adapter_t*)fw_dhcp_srv_offload_cb_context;
9738
9739 ENTER();
9740
9741 if (NULL == adapter)
9742 {
9743 hddLog(VOS_TRACE_LEVEL_ERROR,
9744 "%s: adapter is NULL",__func__);
9745 return;
9746 }
9747
9748 adapter->dhcp_status.dhcp_offload_status = status;
9749 vos_event_set(&adapter->dhcp_status.vos_event);
9750 return;
9751}
9752
9753/**
9754 * wlan_hdd_set_dhcp_server_offload() - set dhcp server offload
9755 * @hostapd_adapter: pointer to hostapd adapter.
9756 *
9757 * Return: None
9758 */
9759static VOS_STATUS wlan_hdd_set_dhcp_server_offload(hdd_adapter_t *hostapd_adapter)
9760{
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
9771 ret = wlan_hdd_validate_context(hdd_ctx);
9772 if (0 != ret)
9773 return VOS_STATUS_E_INVAL;
9774
9775 /* Prepare the request to send to SME */
9776 dhcp_srv_info = vos_mem_malloc(sizeof(*dhcp_srv_info));
9777 if (NULL == dhcp_srv_info) {
9778 hddLog(VOS_TRACE_LEVEL_ERROR,
9779 "%s: could not allocate tDhcpSrvOffloadInfo!", __func__);
9780 return VOS_STATUS_E_NOMEM;
9781 }
9782
9783 vos_mem_zero(dhcp_srv_info, sizeof(*dhcp_srv_info));
9784
9785 dhcp_srv_info->bssidx = hostapd_adapter->sessionId;
9786 dhcp_srv_info->dhcp_srv_offload_enabled = TRUE;
9787 dhcp_srv_info->dhcp_client_num = hdd_ctx->cfg_ini->dhcp_max_num_clients;
9788 dhcp_srv_info->start_lsb = hdd_ctx->cfg_ini->dhcp_start_lsb;
9789 dhcp_srv_info->dhcp_offload_callback = hdd_dhcp_server_offload_done;
9790 dhcp_srv_info->dhcp_server_offload_cb_context = hostapd_adapter;
9791
9792 hdd_string_to_u8_array(hdd_ctx->cfg_ini->dhcp_srv_ip,
9793 srv_ip,
9794 &num_entries,
Anurag Chouhanac145c22016-11-22 16:51:47 +05309795 IPADDR_NUM_ENTRIES, ".");
Anurag Chouhan83026002016-12-13 22:46:21 +05309796 if (num_entries != IPADDR_NUM_ENTRIES) {
9797 hddLog(VOS_TRACE_LEVEL_ERROR,
9798 "%s: incorrect IP address (%s) assigned for DHCP server!",
9799 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
9800 vos_mem_free(dhcp_srv_info);
9801 return VOS_STATUS_E_FAILURE;
9802 }
9803
9804 if ((srv_ip[0] >= 224) && (srv_ip[0] <= 239)) {
9805 hddLog(VOS_TRACE_LEVEL_ERROR,
9806 "%s: invalid IP address (%s)! It could NOT be multicast IP address!",
9807 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
9808 vos_mem_free(dhcp_srv_info);
9809 return VOS_STATUS_E_FAILURE;
9810 }
9811
9812 if (srv_ip[IPADDR_NUM_ENTRIES-1] >= DHCP_START_POOL_ADDRESS) {
9813 hddLog(VOS_TRACE_LEVEL_ERROR,
9814 "%s: invalid IP address (%s)! The last field must be less than 100!",
9815 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
9816 vos_mem_free(dhcp_srv_info);
9817 return VOS_STATUS_E_FAILURE;
9818 }
9819
9820 for (num = 0; num < num_entries; num++) {
9821 temp = srv_ip[num];
9822 dhcp_srv_info->dhcp_srv_ip |= (temp << (8 * num));
9823 }
9824
9825 if (eHAL_STATUS_SUCCESS !=
9826 sme_set_dhcp_srv_offload(hdd_ctx->hHal, dhcp_srv_info)) {
9827 hddLog(VOS_TRACE_LEVEL_ERROR,
9828 "%s: sme_set_dhcp_srv_offload fail!", __func__);
9829 vos_mem_free(dhcp_srv_info);
9830 return VOS_STATUS_E_FAILURE;
9831 }
9832
9833 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
9834 "%s: enable DHCP Server offload successfully!", __func__);
9835
9836 vos_mem_free(dhcp_srv_info);
9837 return 0;
9838}
9839#endif /* DHCP_SERVER_OFFLOAD */
9840
Jeff Johnson295189b2012-06-20 16:38:30 -07009841#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9842static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
9843 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009844#else
9845static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
9846 struct cfg80211_beacon_data *params,
9847 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309848 enum nl80211_hidden_ssid hidden_ssid,
9849 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009850#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009851{
9852 tsap_Config_t *pConfig;
9853 beacon_data_t *pBeacon = NULL;
9854 struct ieee80211_mgmt *pMgmt_frame;
9855 v_U8_t *pIe=NULL;
9856 v_U16_t capab_info;
9857 eCsrAuthType RSNAuthType;
9858 eCsrEncryptionType RSNEncryptType;
9859 eCsrEncryptionType mcRSNEncryptType;
9860 int status = VOS_STATUS_SUCCESS;
9861 tpWLAN_SAPEventCB pSapEventCallback;
9862 hdd_hostapd_state_t *pHostapdState;
Jeff Johnson295189b2012-06-20 16:38:30 -07009863 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309864 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009865 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309866 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07009867 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08009868 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05309869 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07009870 v_BOOL_t MFPCapable = VOS_FALSE;
9871 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309872 v_BOOL_t sapEnable11AC =
9873 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Kapil Gupta137ef892016-12-13 19:38:00 +05309874 u_int16_t prev_rsn_length = 0;
9875
Jeff Johnson295189b2012-06-20 16:38:30 -07009876 ENTER();
9877
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309878 iniConfig = pHddCtx->cfg_ini;
9879
Jeff Johnson295189b2012-06-20 16:38:30 -07009880 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
9881
9882 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9883
9884 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9885
9886 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9887
9888 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
9889
9890 //channel is already set in the set_channel Call back
9891 //pConfig->channel = pCommitConfig->channel;
9892
9893 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309894 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07009895 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
9896
9897 pConfig->dtim_period = pBeacon->dtim_period;
9898
Arif Hussain6d2a3322013-11-17 19:50:10 -08009899 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07009900 pConfig->dtim_period);
9901
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08009902 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07009903 {
9904 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07009905 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05309906 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
9907 {
9908 tANI_BOOLEAN restartNeeded;
9909 pConfig->ieee80211d = 1;
9910 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
9911 sme_setRegInfo(hHal, pConfig->countryCode);
9912 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
9913 }
9914 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009915 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07009916 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07009917 pConfig->ieee80211d = 1;
9918 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
9919 sme_setRegInfo(hHal, pConfig->countryCode);
9920 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07009921 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07009922 else
9923 {
9924 pConfig->ieee80211d = 0;
9925 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309926 /*
9927 * If auto channel is configured i.e. channel is 0,
9928 * so skip channel validation.
9929 */
9930 if( AUTO_CHANNEL_SELECT != pConfig->channel )
9931 {
9932 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
9933 {
9934 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009935 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309936 return -EINVAL;
9937 }
9938 }
9939 else
9940 {
9941 if(1 != pHddCtx->is_dynamic_channel_range_set)
9942 {
9943 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
9944 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
9945 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
9946 }
9947 pHddCtx->is_dynamic_channel_range_set = 0;
9948 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009949 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07009950 else
Jeff Johnson295189b2012-06-20 16:38:30 -07009951 {
9952 pConfig->ieee80211d = 0;
9953 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309954
9955#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9956 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
9957 pConfig->authType = eSAP_OPEN_SYSTEM;
9958 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
9959 pConfig->authType = eSAP_SHARED_KEY;
9960 else
9961 pConfig->authType = eSAP_AUTO_SWITCH;
9962#else
9963 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
9964 pConfig->authType = eSAP_OPEN_SYSTEM;
9965 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
9966 pConfig->authType = eSAP_SHARED_KEY;
9967 else
9968 pConfig->authType = eSAP_AUTO_SWITCH;
9969#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009970
9971 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309972
9973 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07009974 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
Agrawal Ashisha8e8a722016-10-18 19:07:45 +05309975#ifdef SAP_AUTH_OFFLOAD
9976 /* In case of sap offload, hostapd.conf is configuted with open mode and
9977 * security is configured from ini file. Due to open mode in hostapd.conf
9978 * privacy bit is set to false which will result in not sending,
9979 * data packets as encrypted.
9980 * If enable_sap_auth_offload is enabled in ini and
9981 * sap_auth_offload_sec_type is type of WPA2-PSK,
9982 * driver will set privacy bit to 1.
9983 */
9984 if (pHddCtx->cfg_ini->enable_sap_auth_offload &&
9985 pHddCtx->cfg_ini->sap_auth_offload_sec_type)
9986 pConfig->privacy = VOS_TRUE;
9987#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009988
9989 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
9990
9991 /*Set wps station to configured*/
9992 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
9993
9994 if(pIe)
9995 {
9996 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
9997 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009998 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07009999 return -EINVAL;
10000 }
10001 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
10002 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -070010003 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -070010004 /* Check 15 bit of WPS IE as it contain information for wps state
10005 * WPS state
10006 */
10007 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
10008 {
10009 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
10010 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
10011 {
10012 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
10013 }
10014 }
10015 }
10016 else
10017 {
10018 pConfig->wps_state = SAP_WPS_DISABLED;
10019 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010020 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -070010021
c_hpothufe599e92014-06-16 11:38:55 +053010022 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
10023 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
10024 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
10025 eCSR_ENCRYPT_TYPE_NONE;
10026
Jeff Johnson295189b2012-06-20 16:38:30 -070010027 pConfig->RSNWPAReqIELength = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +053010028 memset(&pConfig->RSNWPAReqIE[0], 0, sizeof(pConfig->RSNWPAReqIE));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010029 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070010030 WLAN_EID_RSN);
10031 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010032 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010033 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053010034 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
10035 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
10036 pConfig->RSNWPAReqIELength);
10037 else
10038 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
10039 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010040 /* The actual processing may eventually be more extensive than
10041 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -070010042 * by the app.
10043 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010044 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070010045 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
10046 &RSNEncryptType,
10047 &mcRSNEncryptType,
10048 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080010049 &MFPCapable,
10050 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053010051 pConfig->RSNWPAReqIE[1]+2,
10052 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010053
10054 if( VOS_STATUS_SUCCESS == status )
10055 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010056 /* Now copy over all the security attributes you have
10057 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070010058 * */
10059 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
10060 pConfig->mcRSNEncryptType = mcRSNEncryptType;
10061 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
10062 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010063 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080010064 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070010065 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
10066 }
10067 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010068
Jeff Johnson295189b2012-06-20 16:38:30 -070010069 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
10070 pBeacon->tail, pBeacon->tail_len);
10071
10072 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
10073 {
Kapil Gupta137ef892016-12-13 19:38:00 +053010074 if (pConfig->RSNWPAReqIE[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070010075 {
10076 /*Mixed mode WPA/WPA2*/
Kapil Gupta137ef892016-12-13 19:38:00 +053010077 prev_rsn_length = pConfig->RSNWPAReqIELength;
Jeff Johnson295189b2012-06-20 16:38:30 -070010078 pConfig->RSNWPAReqIELength += pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053010079 if (pConfig->RSNWPAReqIELength <=
10080 (sizeof(pConfig->RSNWPAReqIE) - prev_rsn_length))
10081 memcpy(&pConfig->RSNWPAReqIE[0] + prev_rsn_length, pIe,
10082 pIe[1] + 2);
10083 else
10084 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
10085 pConfig->RSNWPAReqIELength);
10086
Jeff Johnson295189b2012-06-20 16:38:30 -070010087 }
10088 else
10089 {
10090 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053010091 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
10092 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
10093 pConfig->RSNWPAReqIELength);
10094 else
10095 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
10096 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010097 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070010098 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
10099 &RSNEncryptType,
10100 &mcRSNEncryptType,
10101 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080010102 &MFPCapable,
10103 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053010104 pConfig->RSNWPAReqIE[1]+2,
10105 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010106
10107 if( VOS_STATUS_SUCCESS == status )
10108 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010109 /* Now copy over all the security attributes you have
10110 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070010111 * */
10112 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
10113 pConfig->mcRSNEncryptType = mcRSNEncryptType;
10114 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
10115 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010116 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080010117 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070010118 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
10119 }
10120 }
10121 }
10122
Kapil Gupta137ef892016-12-13 19:38:00 +053010123 if (pConfig->RSNWPAReqIELength > sizeof(pConfig->RSNWPAReqIE)) {
Jeff Johnson4416a782013-03-25 14:17:50 -070010124 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
10125 return -EINVAL;
10126 }
10127
Jeff Johnson295189b2012-06-20 16:38:30 -070010128 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
10129
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010130#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010131 if (params->ssid != NULL)
10132 {
10133 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
10134 pConfig->SSIDinfo.ssid.length = params->ssid_len;
10135 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
10136 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
10137 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010138#else
10139 if (ssid != NULL)
10140 {
10141 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
10142 pConfig->SSIDinfo.ssid.length = ssid_len;
10143 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
10144 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
10145 }
10146#endif
10147
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010148 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -070010149 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010150
Jeff Johnson295189b2012-06-20 16:38:30 -070010151 /* default value */
10152 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
10153 pConfig->num_accept_mac = 0;
10154 pConfig->num_deny_mac = 0;
10155
10156 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
10157 pBeacon->tail, pBeacon->tail_len);
10158
10159 /* pIe for black list is following form:
10160 type : 1 byte
10161 length : 1 byte
10162 OUI : 4 bytes
10163 acl type : 1 byte
10164 no of mac addr in black list: 1 byte
10165 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010166 */
10167 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010168 {
10169 pConfig->SapMacaddr_acl = pIe[6];
10170 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080010171 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010172 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053010173 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
10174 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010175 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
10176 for (i = 0; i < pConfig->num_deny_mac; i++)
10177 {
10178 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
10179 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010180 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010181 }
10182 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
10183 pBeacon->tail, pBeacon->tail_len);
10184
10185 /* pIe for white list is following form:
10186 type : 1 byte
10187 length : 1 byte
10188 OUI : 4 bytes
10189 acl type : 1 byte
10190 no of mac addr in white list: 1 byte
10191 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010192 */
10193 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010194 {
10195 pConfig->SapMacaddr_acl = pIe[6];
10196 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080010197 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010198 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053010199 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
10200 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010201 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
10202 for (i = 0; i < pConfig->num_accept_mac; i++)
10203 {
10204 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
10205 acl_entry++;
10206 }
10207 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053010208
Jeff Johnson295189b2012-06-20 16:38:30 -070010209 wlan_hdd_set_sapHwmode(pHostapdAdapter);
10210
Jeff Johnsone7245742012-09-05 17:12:55 -070010211#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080010212 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +053010213 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
10214 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +053010215 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
10216 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080010217 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
10218 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +053010219 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
10220 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -070010221 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053010222 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -070010223 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +053010224 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070010225
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010226 /* If ACS disable and selected channel <= 14
10227 * OR
10228 * ACS enabled and ACS operating band is choosen as 2.4
10229 * AND
10230 * VHT in 2.4G Disabled
10231 * THEN
10232 * Fallback to 11N mode
10233 */
10234 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
10235 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +053010236 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010237 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -070010238 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053010239 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
10240 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070010241 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
10242 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010243 }
10244#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010245
Jeff Johnson295189b2012-06-20 16:38:30 -070010246 // ht_capab is not what the name conveys,this is used for protection bitmap
10247 pConfig->ht_capab =
10248 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
10249
Kapil Gupta137ef892016-12-13 19:38:00 +053010250 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -070010251 {
10252 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
10253 return -EINVAL;
10254 }
10255
10256 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010257 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -070010258 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
10259 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010260 pConfig->obssProtEnabled =
10261 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -070010262
Chet Lanctot8cecea22014-02-11 19:09:36 -080010263#ifdef WLAN_FEATURE_11W
10264 pConfig->mfpCapable = MFPCapable;
10265 pConfig->mfpRequired = MFPRequired;
10266 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
10267 pConfig->mfpCapable, pConfig->mfpRequired);
10268#endif
10269
Arif Hussain6d2a3322013-11-17 19:50:10 -080010270 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -070010271 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -080010272 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
10273 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
10274 (int)pConfig->channel);
10275 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
10276 pConfig->SapHw_mode, pConfig->privacy,
10277 pConfig->authType);
10278 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
10279 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
10280 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
10281 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -070010282
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010283 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -070010284 {
10285 //Bss already started. just return.
10286 //TODO Probably it should update some beacon params.
10287 hddLog( LOGE, "Bss Already started...Ignore the request");
10288 EXIT();
10289 return 0;
10290 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010291
Agarwal Ashish51325b52014-06-16 16:50:49 +053010292 if (vos_max_concurrent_connections_reached()) {
10293 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10294 return -EINVAL;
10295 }
10296
Jeff Johnson295189b2012-06-20 16:38:30 -070010297 pConfig->persona = pHostapdAdapter->device_mode;
10298
Peng Xu2446a892014-09-05 17:21:18 +053010299 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
10300 if ( NULL != psmeConfig)
10301 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053010302 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +053010303 sme_GetConfigParam(hHal, psmeConfig);
10304 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053010305#ifdef WLAN_FEATURE_AP_HT40_24G
10306 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
10307 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
10308 && pHddCtx->cfg_ini->apHT40_24GEnabled)
10309 {
10310 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
10311 sme_UpdateConfig (hHal, psmeConfig);
10312 }
10313#endif
Peng Xu2446a892014-09-05 17:21:18 +053010314 vos_mem_free(psmeConfig);
10315 }
Peng Xuafc34e32014-09-25 13:23:55 +053010316 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +053010317
Jeff Johnson295189b2012-06-20 16:38:30 -070010318 pSapEventCallback = hdd_hostapd_SAPEventCB;
10319 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
10320 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
10321 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010322 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -070010323 return -EINVAL;
10324 }
10325
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010326 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -070010327 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
10328
10329 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010330
Jeff Johnson295189b2012-06-20 16:38:30 -070010331 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010332 {
10333 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010334 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -070010335 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070010336 VOS_ASSERT(0);
10337 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010338
Jeff Johnson295189b2012-06-20 16:38:30 -070010339 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053010340 if (WLANSAP_get_sessionId(pVosContext, &pHostapdAdapter->sessionId) !=
10341 VOS_STATUS_SUCCESS)
10342 {
10343 hddLog(LOGE,FL("Fail to get Softap sessionID"));
10344 VOS_ASSERT(0);
10345 }
Kaushik, Sushantf6070802014-10-15 15:09:23 +053010346 /* Initialize WMM configuation */
10347 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010348 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010349
Anurag Chouhan83026002016-12-13 22:46:21 +053010350#ifdef DHCP_SERVER_OFFLOAD
10351 /* set dhcp server offload */
10352 if (iniConfig->enable_dhcp_srv_offload &&
10353 sme_IsFeatureSupportedByFW(SAP_OFFLOADS)) {
10354 status = wlan_hdd_set_dhcp_server_offload(pHostapdAdapter);
10355 if (!VOS_IS_STATUS_SUCCESS(status))
10356 {
10357 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10358 ("HDD DHCP Server Offload Failed!!"));
10359 return -EINVAL;
10360 }
10361 vos_event_reset(&pHostapdAdapter->dhcp_status.vos_event);
10362 status = vos_wait_single_event(&pHostapdAdapter->dhcp_status.vos_event, 2000);
10363 if (!VOS_IS_STATUS_SUCCESS(status) || pHostapdAdapter->dhcp_status.dhcp_offload_status)
10364 {
10365 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10366 ("ERROR: DHCP HDD vos wait for single_event failed!! %d"),
10367 pHostapdAdapter->dhcp_status.dhcp_offload_status);
10368 return -EINVAL;
10369 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010370#ifdef MDNS_OFFLOAD
10371 if (iniConfig->enable_mdns_offload) {
10372 status = wlan_hdd_set_mdns_offload(pHostapdAdapter);
10373 if (VOS_IS_STATUS_SUCCESS(status))
10374 {
10375 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10376 ("HDD MDNS Server Offload Failed!!"));
10377 return -EINVAL;
10378 }
10379 vos_event_reset(&pHostapdAdapter->mdns_status.vos_event);
10380 status = vos_wait_single_event(&pHostapdAdapter->
10381 mdns_status.vos_event, 2000);
10382 if (!VOS_IS_STATUS_SUCCESS(status) ||
10383 pHostapdAdapter->mdns_status.mdns_enable_status ||
10384 pHostapdAdapter->mdns_status.mdns_fqdn_status ||
10385 pHostapdAdapter->mdns_status.mdns_resp_status)
10386 {
10387 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10388 ("MDNS HDD vos wait for single_event failed!! enable %d fqdn %d resp %d"),
10389 pHostapdAdapter->mdns_status.mdns_enable_status,
10390 pHostapdAdapter->mdns_status.mdns_fqdn_status,
10391 pHostapdAdapter->mdns_status.mdns_resp_status);
10392 return -EINVAL;
10393 }
10394 }
10395#endif /* MDNS_OFFLOAD */
10396 } else {
10397 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10398 ("DHCP Disabled ini %d, FW %d"),
10399 iniConfig->enable_dhcp_srv_offload,
10400 sme_IsFeatureSupportedByFW(SAP_OFFLOADS));
Anurag Chouhan83026002016-12-13 22:46:21 +053010401 }
10402#endif /* DHCP_SERVER_OFFLOAD */
10403
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010404#ifdef WLAN_FEATURE_P2P_DEBUG
10405 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
10406 {
10407 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
10408 {
10409 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
10410 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -080010411 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010412 }
10413 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
10414 {
10415 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
10416 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -080010417 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010418 }
10419 }
10420#endif
Ashish Kumar Dhanotiya42aa5152017-01-03 20:25:57 +053010421 /* Check and restart SAP if it is on Unsafe channel */
10422 hdd_check_for_unsafe_ch(pHostapdAdapter, pHddCtx);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010423
Jeff Johnson295189b2012-06-20 16:38:30 -070010424 pHostapdState->bCommit = TRUE;
10425 EXIT();
10426
10427 return 0;
10428}
10429
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010430#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010431static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010432 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070010433 struct beacon_parameters *params)
10434{
10435 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010436 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010437 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010438
10439 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010440
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010441 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10442 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
10443 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010444 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
10445 hdd_device_modetoString(pAdapter->device_mode),
10446 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010447
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010448 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10449 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010450 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010451 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010452 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010453 }
10454
Agarwal Ashish51325b52014-06-16 16:50:49 +053010455 if (vos_max_concurrent_connections_reached()) {
10456 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10457 return -EINVAL;
10458 }
10459
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010460 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010461 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070010462 )
10463 {
10464 beacon_data_t *old,*new;
10465
10466 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010467
Jeff Johnson295189b2012-06-20 16:38:30 -070010468 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010469 {
10470 hddLog(VOS_TRACE_LEVEL_WARN,
10471 FL("already beacon info added to session(%d)"),
10472 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070010473 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010474 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010475
10476 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
10477
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010478 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -070010479 {
10480 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010481 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010482 return -EINVAL;
10483 }
10484
10485 pAdapter->sessionCtx.ap.beacon = new;
10486
10487 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
10488 }
10489
10490 EXIT();
10491 return status;
10492}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010493
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010494static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
10495 struct net_device *dev,
10496 struct beacon_parameters *params)
10497{
10498 int ret;
10499
10500 vos_ssr_protect(__func__);
10501 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
10502 vos_ssr_unprotect(__func__);
10503
10504 return ret;
10505}
10506
10507static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010508 struct net_device *dev,
10509 struct beacon_parameters *params)
10510{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010511 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010512 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10513 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010514 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010515
10516 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010517
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010518 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10519 TRACE_CODE_HDD_CFG80211_SET_BEACON,
10520 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
10521 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10522 __func__, hdd_device_modetoString(pAdapter->device_mode),
10523 pAdapter->device_mode);
10524
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010525 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10526 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010527 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010528 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010529 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010530 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010531
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010532 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010533 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010534 )
Jeff Johnson295189b2012-06-20 16:38:30 -070010535 {
10536 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010537
Jeff Johnson295189b2012-06-20 16:38:30 -070010538 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010539
Jeff Johnson295189b2012-06-20 16:38:30 -070010540 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010541 {
10542 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10543 FL("session(%d) old and new heads points to NULL"),
10544 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070010545 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010546 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010547
10548 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
10549
10550 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010551 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010552 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010553 return -EINVAL;
10554 }
10555
10556 pAdapter->sessionCtx.ap.beacon = new;
10557
10558 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
10559 }
10560
10561 EXIT();
10562 return status;
10563}
10564
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010565static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
10566 struct net_device *dev,
10567 struct beacon_parameters *params)
10568{
10569 int ret;
10570
10571 vos_ssr_protect(__func__);
10572 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
10573 vos_ssr_unprotect(__func__);
10574
10575 return ret;
10576}
10577
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010578#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10579
10580#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010581static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010582 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010583#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010584static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010585 struct net_device *dev)
10586#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010587{
10588 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -070010589 hdd_context_t *pHddCtx = NULL;
10590 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010591 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010592 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010593
10594 ENTER();
10595
10596 if (NULL == pAdapter)
10597 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010598 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010599 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010600 return -ENODEV;
10601 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010602
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010603 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10604 TRACE_CODE_HDD_CFG80211_STOP_AP,
10605 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010606 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10607 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010608 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010609 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010610 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -070010611 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010612
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010613 pScanInfo = &pHddCtx->scan_info;
10614
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010615 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10616 __func__, hdd_device_modetoString(pAdapter->device_mode),
10617 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010618
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010619 ret = wlan_hdd_scan_abort(pAdapter);
10620
Girish Gowli4bf7a632014-06-12 13:42:11 +053010621 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -070010622 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010623 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10624 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010625
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010626 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -070010627 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010628 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10629 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -080010630
Jeff Johnsone7245742012-09-05 17:12:55 -070010631 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010632 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -070010633 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010634 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070010635 }
10636
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010637 /* Delete all associated STAs before stopping AP/P2P GO */
10638 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +053010639 hdd_hostapd_stop(dev);
10640
Jeff Johnson295189b2012-06-20 16:38:30 -070010641 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010642 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070010643 )
10644 {
10645 beacon_data_t *old;
10646
10647 old = pAdapter->sessionCtx.ap.beacon;
10648
10649 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010650 {
10651 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10652 FL("session(%d) beacon data points to NULL"),
10653 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070010654 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010655 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010656
Jeff Johnson295189b2012-06-20 16:38:30 -070010657 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010658
10659 mutex_lock(&pHddCtx->sap_lock);
10660 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
10661 {
Jeff Johnson4416a782013-03-25 14:17:50 -070010662 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -070010663 {
10664 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
10665
10666 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
10667
10668 if (!VOS_IS_STATUS_SUCCESS(status))
10669 {
10670 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010671 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -070010672 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010673 }
10674 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010675 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010676 /* BSS stopped, clear the active sessions for this device mode */
10677 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010678 }
10679 mutex_unlock(&pHddCtx->sap_lock);
10680
10681 if(status != VOS_STATUS_SUCCESS)
10682 {
10683 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010684 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010685 return -EINVAL;
10686 }
10687
Jeff Johnson4416a782013-03-25 14:17:50 -070010688 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070010689 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
10690 ==eHAL_STATUS_FAILURE)
10691 {
10692 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010693 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010694 }
10695
Jeff Johnson4416a782013-03-25 14:17:50 -070010696 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070010697 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
10698 eANI_BOOLEAN_FALSE) )
10699 {
10700 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010701 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010702 }
10703
10704 // Reset WNI_CFG_PROBE_RSP Flags
10705 wlan_hdd_reset_prob_rspies(pAdapter);
10706
10707 pAdapter->sessionCtx.ap.beacon = NULL;
10708 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010709#ifdef WLAN_FEATURE_P2P_DEBUG
10710 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
10711 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
10712 {
10713 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
10714 "GO got removed");
10715 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
10716 }
10717#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010718 }
10719 EXIT();
10720 return status;
10721}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010722
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010723#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10724static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
10725 struct net_device *dev)
10726{
10727 int ret;
10728
10729 vos_ssr_protect(__func__);
10730 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
10731 vos_ssr_unprotect(__func__);
10732
10733 return ret;
10734}
10735#else
10736static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
10737 struct net_device *dev)
10738{
10739 int ret;
10740
10741 vos_ssr_protect(__func__);
10742 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
10743 vos_ssr_unprotect(__func__);
10744
10745 return ret;
10746}
10747#endif
10748
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010749#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
10750
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010751static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010752 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010753 struct cfg80211_ap_settings *params)
10754{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010755 hdd_adapter_t *pAdapter;
10756 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010757 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010758
10759 ENTER();
10760
Girish Gowlib143d7a2015-02-18 19:39:55 +053010761 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010762 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010763 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +053010764 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010765 return -ENODEV;
10766 }
10767
10768 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
10769 if (NULL == pAdapter)
10770 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010771 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010772 "%s: HDD adapter is Null", __func__);
10773 return -ENODEV;
10774 }
10775
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010776 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10777 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
10778 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010779 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
10780 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010781 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010782 "%s: HDD adapter magic is invalid", __func__);
10783 return -ENODEV;
10784 }
10785
10786 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010787 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010788 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010789 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010790 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010791 }
10792
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010793 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
10794 __func__, hdd_device_modetoString(pAdapter->device_mode),
10795 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010796
10797 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010798 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010799 )
10800 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010801 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010802
10803 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010804
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010805 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010806 {
10807 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
10808 FL("already beacon info added to session(%d)"),
10809 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010810 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010811 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010812
Girish Gowlib143d7a2015-02-18 19:39:55 +053010813#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10814 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
10815 &new,
10816 &params->beacon);
10817#else
10818 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
10819 &new,
10820 &params->beacon,
10821 params->dtim_period);
10822#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010823
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010824 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010825 {
10826 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010827 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010828 return -EINVAL;
10829 }
10830 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -080010831#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -070010832 wlan_hdd_cfg80211_set_channel(wiphy, dev,
10833#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
10834 params->channel, params->channel_type);
10835#else
10836 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
10837#endif
Viral Modi3a32cc52013-02-08 11:14:52 -080010838#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010839 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010840 params->ssid_len, params->hidden_ssid,
10841 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010842 }
10843
10844 EXIT();
10845 return status;
10846}
10847
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010848static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
10849 struct net_device *dev,
10850 struct cfg80211_ap_settings *params)
10851{
10852 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010853
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010854 vos_ssr_protect(__func__);
10855 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
10856 vos_ssr_unprotect(__func__);
10857
10858 return ret;
10859}
10860
10861static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010862 struct net_device *dev,
10863 struct cfg80211_beacon_data *params)
10864{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010865 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010866 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010867 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010868
10869 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010870
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010871 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10872 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
10873 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -080010874 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010875 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010876
10877 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10878 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010879 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010880 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010881 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010882 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010883
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010884 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010885 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010886 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010887 {
10888 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010889
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010890 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010891
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010892 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010893 {
10894 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10895 FL("session(%d) beacon data points to NULL"),
10896 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010897 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010898 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010899
10900 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
10901
10902 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010903 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010904 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010905 return -EINVAL;
10906 }
10907
10908 pAdapter->sessionCtx.ap.beacon = new;
10909
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010910 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
10911 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010912 }
10913
10914 EXIT();
10915 return status;
10916}
10917
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010918static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
10919 struct net_device *dev,
10920 struct cfg80211_beacon_data *params)
10921{
10922 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010923
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010924 vos_ssr_protect(__func__);
10925 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
10926 vos_ssr_unprotect(__func__);
10927
10928 return ret;
10929}
10930
10931#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010932
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010933static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010934 struct net_device *dev,
10935 struct bss_parameters *params)
10936{
10937 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010938 hdd_context_t *pHddCtx;
10939 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010940
10941 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010942
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010943 if (NULL == pAdapter)
10944 {
10945 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10946 "%s: HDD adapter is Null", __func__);
10947 return -ENODEV;
10948 }
10949 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010950 ret = wlan_hdd_validate_context(pHddCtx);
10951 if (0 != ret)
10952 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010953 return ret;
10954 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010955 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10956 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
10957 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010958 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10959 __func__, hdd_device_modetoString(pAdapter->device_mode),
10960 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010961
10962 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010963 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010964 )
Jeff Johnson295189b2012-06-20 16:38:30 -070010965 {
10966 /* ap_isolate == -1 means that in change bss, upper layer doesn't
10967 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010968 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -070010969 {
10970 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010971 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010972 }
10973
10974 EXIT();
10975 return 0;
10976}
10977
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010978static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
10979 struct net_device *dev,
10980 struct bss_parameters *params)
10981{
10982 int ret;
10983
10984 vos_ssr_protect(__func__);
10985 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
10986 vos_ssr_unprotect(__func__);
10987
10988 return ret;
10989}
Kiet Lam10841362013-11-01 11:36:50 +053010990/* FUNCTION: wlan_hdd_change_country_code_cd
10991* to wait for contry code completion
10992*/
10993void* wlan_hdd_change_country_code_cb(void *pAdapter)
10994{
10995 hdd_adapter_t *call_back_pAdapter = pAdapter;
10996 complete(&call_back_pAdapter->change_country_code);
10997 return NULL;
10998}
10999
Jeff Johnson295189b2012-06-20 16:38:30 -070011000/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053011001 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -070011002 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
11003 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053011004int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011005 struct net_device *ndev,
11006 enum nl80211_iftype type,
11007 u32 *flags,
11008 struct vif_params *params
11009 )
11010{
11011 struct wireless_dev *wdev;
11012 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011013 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -070011014 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011015 tCsrRoamProfile *pRoamProfile = NULL;
11016 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011017 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011018 eMib_dot11DesiredBssType connectedBssType;
11019 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011020 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011021
11022 ENTER();
11023
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011024 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011025 {
11026 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11027 "%s: Adapter context is null", __func__);
11028 return VOS_STATUS_E_FAILURE;
11029 }
11030
11031 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11032 if (!pHddCtx)
11033 {
11034 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11035 "%s: HDD context is null", __func__);
11036 return VOS_STATUS_E_FAILURE;
11037 }
11038
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011039 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11040 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
11041 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011042 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011043 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011044 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011045 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011046 }
11047
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011048 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11049 __func__, hdd_device_modetoString(pAdapter->device_mode),
11050 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011051
Agarwal Ashish51325b52014-06-16 16:50:49 +053011052 if (vos_max_concurrent_connections_reached()) {
11053 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11054 return -EINVAL;
11055 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011056 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070011057 wdev = ndev->ieee80211_ptr;
11058
11059#ifdef WLAN_BTAMP_FEATURE
11060 if((NL80211_IFTYPE_P2P_CLIENT == type)||
11061 (NL80211_IFTYPE_ADHOC == type)||
11062 (NL80211_IFTYPE_AP == type)||
11063 (NL80211_IFTYPE_P2P_GO == type))
11064 {
11065 pHddCtx->isAmpAllowed = VOS_FALSE;
11066 // stop AMP traffic
11067 status = WLANBAP_StopAmp();
11068 if(VOS_STATUS_SUCCESS != status )
11069 {
11070 pHddCtx->isAmpAllowed = VOS_TRUE;
11071 hddLog(VOS_TRACE_LEVEL_FATAL,
11072 "%s: Failed to stop AMP", __func__);
11073 return -EINVAL;
11074 }
11075 }
11076#endif //WLAN_BTAMP_FEATURE
11077 /* Reset the current device mode bit mask*/
11078 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
11079
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +053011080 if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
11081 ((type == NL80211_IFTYPE_P2P_CLIENT) ||
11082 (type == NL80211_IFTYPE_P2P_GO)))
11083 {
11084 /* Notify Mode change in case of concurrency.
11085 * Below function invokes TDLS teardown Functionality Since TDLS is
11086 * not Supported in case of concurrency i.e Once P2P session
11087 * is detected disable offchannel and teardown TDLS links
11088 */
11089 hddLog(LOG1,
11090 FL("Device mode = %d Interface type = %d"),
11091 pAdapter->device_mode, type);
11092 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
11093 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +053011094
Jeff Johnson295189b2012-06-20 16:38:30 -070011095 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070011096 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -070011097 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -070011098 )
11099 {
11100 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011101 if (!pWextState)
11102 {
11103 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11104 "%s: pWextState is null", __func__);
11105 return VOS_STATUS_E_FAILURE;
11106 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011107 pRoamProfile = &pWextState->roamProfile;
11108 LastBSSType = pRoamProfile->BSSType;
11109
11110 switch (type)
11111 {
11112 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070011113 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070011114 hddLog(VOS_TRACE_LEVEL_INFO,
11115 "%s: setting interface Type to INFRASTRUCTURE", __func__);
11116 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -070011117#ifdef WLAN_FEATURE_11AC
11118 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
11119 {
11120 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
11121 }
11122#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011123 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -070011124 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011125 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080011126 //Check for sub-string p2p to confirm its a p2p interface
11127 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011128 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +053011129#ifdef FEATURE_WLAN_TDLS
11130 mutex_lock(&pHddCtx->tdls_lock);
11131 wlan_hdd_tdls_exit(pAdapter, TRUE);
11132 mutex_unlock(&pHddCtx->tdls_lock);
11133#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -080011134 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
11135 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
11136 }
11137 else
11138 {
11139 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070011140 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080011141 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011142 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +053011143
Jeff Johnson295189b2012-06-20 16:38:30 -070011144 case NL80211_IFTYPE_ADHOC:
11145 hddLog(VOS_TRACE_LEVEL_INFO,
11146 "%s: setting interface Type to ADHOC", __func__);
11147 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
11148 pRoamProfile->phyMode =
11149 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -070011150 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011151 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +053011152 hdd_set_ibss_ops( pAdapter );
11153 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +053011154
11155 status = hdd_sta_id_hash_attach(pAdapter);
11156 if (VOS_STATUS_SUCCESS != status) {
11157 hddLog(VOS_TRACE_LEVEL_ERROR,
11158 FL("Failed to initialize hash for IBSS"));
11159 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011160 break;
11161
11162 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070011163 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070011164 {
11165 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
11166 "%s: setting interface Type to %s", __func__,
11167 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
11168
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080011169 //Cancel any remain on channel for GO mode
11170 if (NL80211_IFTYPE_P2P_GO == type)
11171 {
11172 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
11173 }
Mohit Khanna0f232092012-09-11 14:46:08 -070011174 if (NL80211_IFTYPE_AP == type)
11175 {
11176 /* As Loading WLAN Driver one interface being created for p2p device
11177 * address. This will take one HW STA and the max number of clients
11178 * that can connect to softAP will be reduced by one. so while changing
11179 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
11180 * interface as it is not required in SoftAP mode.
11181 */
11182
11183 // Get P2P Adapter
11184 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
11185
11186 if (pP2pAdapter)
11187 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053011188 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +053011189 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -070011190 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
11191 }
11192 }
Swaroop Goltia2e32212014-04-09 23:37:33 +053011193 //Disable IMPS & BMPS for SAP/GO
11194 if(VOS_STATUS_E_FAILURE ==
11195 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
11196 {
11197 //Fail to Exit BMPS
11198 VOS_ASSERT(0);
11199 }
Deepthi Gowri500fc472014-08-11 19:53:10 +053011200
11201 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
11202
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011203#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -070011204
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011205 /* A Mutex Lock is introduced while changing the mode to
11206 * protect the concurrent access for the Adapters by TDLS
11207 * module.
11208 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011209 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011210#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011211 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +053011212 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011213 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -070011214 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
11215 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011216#ifdef FEATURE_WLAN_TDLS
11217 mutex_unlock(&pHddCtx->tdls_lock);
11218#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070011219 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
11220 (pConfig->apRandomBssidEnabled))
11221 {
11222 /* To meet Android requirements create a randomized
11223 MAC address of the form 02:1A:11:Fx:xx:xx */
11224 get_random_bytes(&ndev->dev_addr[3], 3);
11225 ndev->dev_addr[0] = 0x02;
11226 ndev->dev_addr[1] = 0x1A;
11227 ndev->dev_addr[2] = 0x11;
11228 ndev->dev_addr[3] |= 0xF0;
11229 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
11230 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -080011231 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
11232 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070011233 }
11234
Jeff Johnson295189b2012-06-20 16:38:30 -070011235 hdd_set_ap_ops( pAdapter->dev );
11236
Kiet Lam10841362013-11-01 11:36:50 +053011237 /* This is for only SAP mode where users can
11238 * control country through ini.
11239 * P2P GO follows station country code
11240 * acquired during the STA scanning. */
11241 if((NL80211_IFTYPE_AP == type) &&
11242 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
11243 {
11244 int status = 0;
11245 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
11246 "%s: setting country code from INI ", __func__);
11247 init_completion(&pAdapter->change_country_code);
11248 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
11249 (void *)(tSmeChangeCountryCallback)
11250 wlan_hdd_change_country_code_cb,
11251 pConfig->apCntryCode, pAdapter,
11252 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053011253 eSIR_FALSE,
11254 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +053011255 if (eHAL_STATUS_SUCCESS == status)
11256 {
11257 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011258 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +053011259 &pAdapter->change_country_code,
11260 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011261 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +053011262 {
11263 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011264 FL("SME Timed out while setting country code %ld"),
11265 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -080011266
11267 if (pHddCtx->isLogpInProgress)
11268 {
11269 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11270 "%s: LOGP in Progress. Ignore!!!", __func__);
11271 return -EAGAIN;
11272 }
Kiet Lam10841362013-11-01 11:36:50 +053011273 }
11274 }
11275 else
11276 {
11277 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011278 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +053011279 return -EINVAL;
11280 }
11281 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011282 status = hdd_init_ap_mode(pAdapter);
11283 if(status != VOS_STATUS_SUCCESS)
11284 {
11285 hddLog(VOS_TRACE_LEVEL_FATAL,
11286 "%s: Error initializing the ap mode", __func__);
11287 return -EINVAL;
11288 }
11289 hdd_set_conparam(1);
11290
Nirav Shah7e3c8132015-06-22 23:51:42 +053011291 status = hdd_sta_id_hash_attach(pAdapter);
11292 if (VOS_STATUS_SUCCESS != status)
11293 {
11294 hddLog(VOS_TRACE_LEVEL_ERROR,
11295 FL("Failed to initialize hash for AP"));
11296 return -EINVAL;
11297 }
11298
Jeff Johnson295189b2012-06-20 16:38:30 -070011299 /*interface type changed update in wiphy structure*/
11300 if(wdev)
11301 {
11302 wdev->iftype = type;
11303 pHddCtx->change_iface = type;
11304 }
11305 else
11306 {
11307 hddLog(VOS_TRACE_LEVEL_ERROR,
11308 "%s: ERROR !!!! Wireless dev is NULL", __func__);
11309 return -EINVAL;
11310 }
11311 goto done;
11312 }
11313
11314 default:
11315 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
11316 __func__);
11317 return -EOPNOTSUPP;
11318 }
11319 }
11320 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011321 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011322 )
11323 {
11324 switch(type)
11325 {
11326 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070011327 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070011328 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +053011329
11330 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011331#ifdef FEATURE_WLAN_TDLS
11332
11333 /* A Mutex Lock is introduced while changing the mode to
11334 * protect the concurrent access for the Adapters by TDLS
11335 * module.
11336 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011337 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011338#endif
c_hpothu002231a2015-02-05 14:58:51 +053011339 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011340 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080011341 //Check for sub-string p2p to confirm its a p2p interface
11342 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -080011343 {
11344 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
11345 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
11346 }
11347 else
11348 {
11349 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070011350 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080011351 }
Agrawal Ashishcfe83282016-09-29 13:03:45 +053011352
11353 /* set con_mode to STA only when no SAP concurrency mode */
11354 if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO)))
11355 hdd_set_conparam(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070011356 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070011357 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
11358 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011359#ifdef FEATURE_WLAN_TDLS
11360 mutex_unlock(&pHddCtx->tdls_lock);
11361#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +053011362 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -070011363 if( VOS_STATUS_SUCCESS != status )
11364 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -070011365 /* In case of JB, for P2P-GO, only change interface will be called,
11366 * This is the right place to enable back bmps_imps()
11367 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053011368 if (pHddCtx->hdd_wlan_suspended)
11369 {
11370 hdd_set_pwrparams(pHddCtx);
11371 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011372 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070011373 goto done;
11374 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070011375 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070011376 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070011377 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
11378 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -070011379 goto done;
11380 default:
11381 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
11382 __func__);
11383 return -EOPNOTSUPP;
11384
11385 }
11386
11387 }
11388 else
11389 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011390 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
11391 __func__, hdd_device_modetoString(pAdapter->device_mode),
11392 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011393 return -EOPNOTSUPP;
11394 }
11395
11396
11397 if(pRoamProfile)
11398 {
11399 if ( LastBSSType != pRoamProfile->BSSType )
11400 {
11401 /*interface type changed update in wiphy structure*/
11402 wdev->iftype = type;
11403
11404 /*the BSS mode changed, We need to issue disconnect
11405 if connected or in IBSS disconnect state*/
11406 if ( hdd_connGetConnectedBssType(
11407 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
11408 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
11409 {
11410 /*need to issue a disconnect to CSR.*/
11411 INIT_COMPLETION(pAdapter->disconnect_comp_var);
11412 if( eHAL_STATUS_SUCCESS ==
11413 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
11414 pAdapter->sessionId,
11415 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
11416 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011417 ret = wait_for_completion_interruptible_timeout(
11418 &pAdapter->disconnect_comp_var,
11419 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
11420 if (ret <= 0)
11421 {
11422 hddLog(VOS_TRACE_LEVEL_ERROR,
11423 FL("wait on disconnect_comp_var failed %ld"), ret);
11424 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011425 }
11426 }
11427 }
11428 }
11429
11430done:
11431 /*set bitmask based on updated value*/
11432 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -070011433
11434 /* Only STA mode support TM now
11435 * all other mode, TM feature should be disabled */
11436 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
11437 (~VOS_STA & pHddCtx->concurrency_mode) )
11438 {
11439 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
11440 }
11441
Jeff Johnson295189b2012-06-20 16:38:30 -070011442#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011443 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053011444 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -070011445 {
11446 //we are ok to do AMP
11447 pHddCtx->isAmpAllowed = VOS_TRUE;
11448 }
11449#endif //WLAN_BTAMP_FEATURE
11450 EXIT();
11451 return 0;
11452}
11453
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053011454/*
11455 * FUNCTION: wlan_hdd_cfg80211_change_iface
11456 * wrapper function to protect the actual implementation from SSR.
11457 */
11458int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
11459 struct net_device *ndev,
11460 enum nl80211_iftype type,
11461 u32 *flags,
11462 struct vif_params *params
11463 )
11464{
11465 int ret;
11466
11467 vos_ssr_protect(__func__);
11468 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
11469 vos_ssr_unprotect(__func__);
11470
11471 return ret;
11472}
11473
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011474#ifdef FEATURE_WLAN_TDLS
11475static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011476 struct net_device *dev,
11477#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
11478 const u8 *mac,
11479#else
11480 u8 *mac,
11481#endif
11482 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011483{
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011484 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011485 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011486 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011487 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053011488 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053011489 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011490
11491 ENTER();
11492
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053011493 if (!dev) {
11494 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
11495 return -EINVAL;
11496 }
11497
11498 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
11499 if (!pAdapter) {
11500 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
11501 return -EINVAL;
11502 }
11503
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053011504 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011505 {
11506 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11507 "Invalid arguments");
11508 return -EINVAL;
11509 }
Hoonki Lee27511902013-03-14 18:19:06 -070011510
11511 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
11512 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
11513 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011514 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070011515 "%s: TDLS mode is disabled OR not enabled in FW."
11516 MAC_ADDRESS_STR " Request declined.",
11517 __func__, MAC_ADDR_ARRAY(mac));
11518 return -ENOTSUPP;
11519 }
11520
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011521 if (pHddCtx->isLogpInProgress)
11522 {
11523 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11524 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053011525 wlan_hdd_tdls_set_link_status(pAdapter,
11526 mac,
11527 eTDLS_LINK_IDLE,
11528 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011529 return -EBUSY;
11530 }
11531
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053011532 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +053011533 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011534
11535 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011536 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011537 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
11538 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053011539 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011540 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070011541 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011542
11543 /* in add station, we accept existing valid staId if there is */
11544 if ((0 == update) &&
11545 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
11546 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011547 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011548 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011549 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011550 " link_status %d. staId %d. add station ignored.",
11551 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011552 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011553 return 0;
11554 }
11555 /* in change station, we accept only when staId is valid */
11556 if ((1 == update) &&
11557 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
11558 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
11559 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011560 tANI_U16 staId = pTdlsPeer->staId;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011561 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011562 "%s: " MAC_ADDRESS_STR
11563 " link status %d. staId %d. change station %s.",
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011564 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, staId,
11565 (TDLS_STA_INDEX_VALID(staId)) ? "ignored" : "declined");
11566 mutex_unlock(&pHddCtx->tdls_lock);
11567 return (TDLS_STA_INDEX_VALID(staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011568 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011569 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070011570
11571 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053011572 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011573 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011574 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11575 "%s: " MAC_ADDRESS_STR
11576 " TDLS setup is ongoing. Request declined.",
11577 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -070011578 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011579 }
11580
11581 /* first to check if we reached to maximum supported TDLS peer.
11582 TODO: for now, return -EPERM looks working fine,
11583 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011584 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
11585 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011586 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011587 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11588 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011589 " TDLS Max peer already connected. Request declined."
11590 " Num of peers (%d), Max allowed (%d).",
11591 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
11592 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070011593 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011594 }
11595 else
11596 {
11597 hddTdlsPeer_t *pTdlsPeer;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011598 mutex_lock(&pHddCtx->tdls_lock);
11599 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011600 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011601 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011602 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011603 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11604 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
11605 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011606 return -EPERM;
11607 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011608 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011609 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011610 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +053011611 wlan_hdd_tdls_set_link_status(pAdapter,
11612 mac,
11613 eTDLS_LINK_CONNECTING,
11614 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011615
Jeff Johnsond75fe012013-04-06 10:53:06 -070011616 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053011617 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011618 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011619 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011620 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -070011621 if(StaParams->htcap_present)
11622 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011623 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070011624 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011625 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070011626 "ht_capa->extended_capabilities: %0x",
11627 StaParams->HTCap.extendedHtCapInfo);
11628 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011629 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011630 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011631 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011632 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -070011633 if(StaParams->vhtcap_present)
11634 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011635 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070011636 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
11637 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
11638 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
11639 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011640 {
11641 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011642 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011643 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011644 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011645 "[%d]: %x ", i, StaParams->supported_rates[i]);
11646 }
Jeff Johnsond75fe012013-04-06 10:53:06 -070011647 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053011648 else if ((1 == update) && (NULL == StaParams))
11649 {
11650 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11651 "%s : update is true, but staParams is NULL. Error!", __func__);
11652 return -EPERM;
11653 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011654
11655 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
11656
11657 if (!update)
11658 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053011659 /*Before adding sta make sure that device exited from BMPS*/
11660 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
11661 {
11662 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11663 "%s: Adding tdls peer sta. Disable BMPS", __func__);
11664 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
11665 if (status != VOS_STATUS_SUCCESS) {
11666 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
11667 }
11668 }
11669
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011670 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011671 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011672 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053011673 hddLog(VOS_TRACE_LEVEL_ERROR,
11674 FL("Failed to add TDLS peer STA. Enable Bmps"));
11675 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011676 return -EPERM;
11677 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011678 }
11679 else
11680 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011681 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011682 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011683 if (ret != eHAL_STATUS_SUCCESS) {
11684 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
11685 return -EPERM;
11686 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011687 }
11688
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011689 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011690 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
11691
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053011692 mutex_lock(&pHddCtx->tdls_lock);
11693 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
11694
Masti, Narayanraddi07262462016-01-19 12:40:06 +053011695 if ((pTdlsPeer != NULL) &&
11696 (pTdlsPeer->link_status == eTDLS_LINK_TEARING))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011697 {
Masti, Narayanraddi07262462016-01-19 12:40:06 +053011698 hddLog(VOS_TRACE_LEVEL_ERROR,
11699 FL("peer link status %u"), pTdlsPeer->link_status);
11700 mutex_unlock(&pHddCtx->tdls_lock);
11701 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011702 }
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053011703 mutex_unlock(&pHddCtx->tdls_lock);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011704
Masti, Narayanraddi07262462016-01-19 12:40:06 +053011705 if (ret <= 0)
11706 {
11707 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11708 "%s: timeout waiting for tdls add station indication %ld",
11709 __func__, ret);
11710 goto error;
11711 }
11712
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011713 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
11714 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011715 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011716 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070011717 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011718 }
11719
11720 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -070011721
11722error:
Atul Mittal115287b2014-07-08 13:26:33 +053011723 wlan_hdd_tdls_set_link_status(pAdapter,
11724 mac,
11725 eTDLS_LINK_IDLE,
11726 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -070011727 return -EPERM;
11728
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011729}
11730#endif
11731
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011732static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011733 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011734#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
11735 const u8 *mac,
11736#else
Jeff Johnson295189b2012-06-20 16:38:30 -070011737 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011738#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011739 struct station_parameters *params)
11740{
11741 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011742 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +053011743 hdd_context_t *pHddCtx;
11744 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011745 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011746 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070011747#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011748 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011749 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011750 tANI_U8 isOffChannelSupported = 0;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011751 tANI_U8 isQosWmmSta = FALSE;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070011752#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070011753
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011754 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011755
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011756 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +053011757 if ((NULL == pAdapter))
11758 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011759 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053011760 "invalid adapter ");
11761 return -EINVAL;
11762 }
11763
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011764 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11765 TRACE_CODE_HDD_CHANGE_STATION,
11766 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +053011767 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +053011768
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011769 ret = wlan_hdd_validate_context(pHddCtx);
11770 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +053011771 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011772 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +053011773 }
11774
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011775 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11776
11777 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011778 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011779 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11780 "invalid HDD station context");
11781 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011782 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011783 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
11784
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011785 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
11786 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -070011787 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011788 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -070011789 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011790 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -070011791 WLANTL_STA_AUTHENTICATED);
11792
Gopichand Nakkala29149562013-05-10 21:43:41 +053011793 if (status != VOS_STATUS_SUCCESS)
11794 {
11795 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11796 "%s: Not able to change TL state to AUTHENTICATED", __func__);
11797 return -EINVAL;
11798 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011799 }
11800 }
Hoonki Leea6d49be2013-04-05 09:43:25 -070011801 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
11802 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +053011803#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011804 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
11805 StaParams.capability = params->capability;
11806 StaParams.uapsd_queues = params->uapsd_queues;
11807 StaParams.max_sp = params->max_sp;
11808
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011809 /* Convert (first channel , number of channels) tuple to
11810 * the total list of channels. This goes with the assumption
11811 * that if the first channel is < 14, then the next channels
11812 * are an incremental of 1 else an incremental of 4 till the number
11813 * of channels.
11814 */
11815 if (0 != params->supported_channels_len) {
11816 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
11817 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
11818 {
11819 int wifi_chan_index;
11820 StaParams.supported_channels[j] = params->supported_channels[i];
11821 wifi_chan_index =
11822 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
11823 no_of_channels = params->supported_channels[i+1];
11824 for(k=1; k <= no_of_channels; k++)
11825 {
11826 StaParams.supported_channels[j+1] =
11827 StaParams.supported_channels[j] + wifi_chan_index;
11828 j+=1;
11829 }
11830 }
11831 StaParams.supported_channels_len = j;
11832 }
11833 vos_mem_copy(StaParams.supported_oper_classes,
11834 params->supported_oper_classes,
11835 params->supported_oper_classes_len);
11836 StaParams.supported_oper_classes_len =
11837 params->supported_oper_classes_len;
11838
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011839 if (0 != params->ext_capab_len)
11840 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
11841 sizeof(StaParams.extn_capability));
11842
11843 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070011844 {
11845 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011846 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070011847 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011848
11849 StaParams.supported_rates_len = params->supported_rates_len;
11850
11851 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
11852 * The supported_rates array , for all the structures propogating till Add Sta
11853 * to the firmware has to be modified , if the supplicant (ieee80211) is
11854 * modified to send more rates.
11855 */
11856
11857 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
11858 */
11859 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
11860 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
11861
11862 if (0 != StaParams.supported_rates_len) {
11863 int i = 0;
11864 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
11865 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011866 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011867 "Supported Rates with Length %d", StaParams.supported_rates_len);
11868 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011869 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011870 "[%d]: %0x", i, StaParams.supported_rates[i]);
11871 }
11872
11873 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070011874 {
11875 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011876 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070011877 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011878
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011879 if (0 != params->ext_capab_len ) {
11880 /*Define A Macro : TODO Sunil*/
11881 if ((1<<4) & StaParams.extn_capability[3]) {
11882 isBufSta = 1;
11883 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011884 /* TDLS Channel Switching Support */
11885 if ((1<<6) & StaParams.extn_capability[3]) {
11886 isOffChannelSupported = 1;
11887 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011888 }
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011889
11890 if (pHddCtx->cfg_ini->fEnableTDLSWmmMode &&
Nitesh Shah48df4c02016-08-12 16:27:33 +053011891 (params->ht_capa || params->vht_capa ||
11892 (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME))))
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011893 /* TDLS Peer is WME/QoS capable */
11894 isQosWmmSta = TRUE;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011895
11896 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11897 "%s: TDLS Peer is QOS capable isQosWmmSta= %d HTcapPresent= %d",
11898 __func__, isQosWmmSta, StaParams.htcap_present);
11899
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011900 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
11901 &StaParams, isBufSta,
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011902 isOffChannelSupported,
11903 isQosWmmSta);
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011904
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053011905 if (VOS_STATUS_SUCCESS != status) {
11906 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11907 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
11908 return -EINVAL;
11909 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011910 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
11911
11912 if (VOS_STATUS_SUCCESS != status) {
11913 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11914 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
11915 return -EINVAL;
11916 }
11917 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -070011918#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +053011919 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011920 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011921 return status;
11922}
11923
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011924#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
11925static int wlan_hdd_change_station(struct wiphy *wiphy,
11926 struct net_device *dev,
11927 const u8 *mac,
11928 struct station_parameters *params)
11929#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011930static int wlan_hdd_change_station(struct wiphy *wiphy,
11931 struct net_device *dev,
11932 u8 *mac,
11933 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011934#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011935{
11936 int ret;
11937
11938 vos_ssr_protect(__func__);
11939 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
11940 vos_ssr_unprotect(__func__);
11941
11942 return ret;
11943}
11944
Jeff Johnson295189b2012-06-20 16:38:30 -070011945/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011946 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011947 * This function is used to initialize the key information
11948 */
11949#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011950static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011951 struct net_device *ndev,
11952 u8 key_index, bool pairwise,
11953 const u8 *mac_addr,
11954 struct key_params *params
11955 )
11956#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011957static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011958 struct net_device *ndev,
11959 u8 key_index, const u8 *mac_addr,
11960 struct key_params *params
11961 )
11962#endif
11963{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011964 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070011965 tCsrRoamSetKey setKey;
11966 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011967 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011968 v_U32_t roamId= 0xFF;
11969 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011970 hdd_hostapd_state_t *pHostapdState;
11971 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011972 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011973 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011974
11975 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011976
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011977 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11978 TRACE_CODE_HDD_CFG80211_ADD_KEY,
11979 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011980 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11981 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011982 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011983 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011984 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011985 }
11986
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011987 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11988 __func__, hdd_device_modetoString(pAdapter->device_mode),
11989 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011990
11991 if (CSR_MAX_NUM_KEY <= key_index)
11992 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011993 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011994 key_index);
11995
11996 return -EINVAL;
11997 }
11998
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011999 if (CSR_MAX_KEY_LEN < params->key_len)
12000 {
12001 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
12002 params->key_len);
12003
12004 return -EINVAL;
12005 }
12006
12007 hddLog(VOS_TRACE_LEVEL_INFO,
12008 "%s: called with key index = %d & key length %d",
12009 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070012010
12011 /*extract key idx, key len and key*/
12012 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
12013 setKey.keyId = key_index;
12014 setKey.keyLength = params->key_len;
12015 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
12016
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012017 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070012018 {
12019 case WLAN_CIPHER_SUITE_WEP40:
12020 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
12021 break;
12022
12023 case WLAN_CIPHER_SUITE_WEP104:
12024 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
12025 break;
12026
12027 case WLAN_CIPHER_SUITE_TKIP:
12028 {
12029 u8 *pKey = &setKey.Key[0];
12030 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
12031
12032 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
12033
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012034 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -070012035
12036 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012037 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070012038 |--------------|----------|----------|
12039 <---16bytes---><--8bytes--><--8bytes-->
12040
12041 */
12042 /*Sme expects the 32 bytes key to be in the below order
12043
12044 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012045 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070012046 |--------------|----------|----------|
12047 <---16bytes---><--8bytes--><--8bytes-->
12048 */
12049 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012050 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -070012051
12052 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012053 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070012054
12055 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012056 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070012057
12058
12059 break;
12060 }
12061
12062 case WLAN_CIPHER_SUITE_CCMP:
12063 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
12064 break;
12065
12066#ifdef FEATURE_WLAN_WAPI
12067 case WLAN_CIPHER_SUITE_SMS4:
12068 {
12069 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
12070 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
12071 params->key, params->key_len);
12072 return 0;
12073 }
12074#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070012075
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080012076#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070012077 case WLAN_CIPHER_SUITE_KRK:
12078 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
12079 break;
12080#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070012081
12082#ifdef WLAN_FEATURE_11W
12083 case WLAN_CIPHER_SUITE_AES_CMAC:
12084 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -070012085 break;
Chet Lanctot186b5732013-03-18 10:26:30 -070012086#endif
12087
Jeff Johnson295189b2012-06-20 16:38:30 -070012088 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012089 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070012090 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012091 status = -EOPNOTSUPP;
12092 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012093 }
12094
12095 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
12096 __func__, setKey.encType);
12097
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012098 if (
Jeff Johnson295189b2012-06-20 16:38:30 -070012099#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12100 (!pairwise)
12101#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012102 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -070012103#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012104 )
12105 {
12106 /* set group key*/
12107 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12108 "%s- %d: setting Broadcast key",
12109 __func__, __LINE__);
12110 setKey.keyDirection = eSIR_RX_ONLY;
12111 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
12112 }
12113 else
12114 {
12115 /* set pairwise key*/
12116 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12117 "%s- %d: setting pairwise key",
12118 __func__, __LINE__);
12119 setKey.keyDirection = eSIR_TX_RX;
12120 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
12121 }
12122 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
12123 {
12124 setKey.keyDirection = eSIR_TX_RX;
12125 /*Set the group key*/
12126 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
12127 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -070012128
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012129 if ( 0 != status )
12130 {
12131 hddLog(VOS_TRACE_LEVEL_ERROR,
12132 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012133 status = -EINVAL;
12134 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012135 }
12136 /*Save the keys here and call sme_RoamSetKey for setting
12137 the PTK after peer joins the IBSS network*/
12138 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
12139 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012140 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012141 }
Gopichand Nakkala29149562013-05-10 21:43:41 +053012142 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
12143 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
12144 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012145 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012146 if( pHostapdState->bssState == BSS_START )
12147 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012148 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12149 vos_status = wlan_hdd_check_ula_done(pAdapter);
12150
12151 if ( vos_status != VOS_STATUS_SUCCESS )
12152 {
12153 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12154 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
12155 __LINE__, vos_status );
12156
12157 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
12158
12159 status = -EINVAL;
12160 goto end;
12161 }
12162
Jeff Johnson295189b2012-06-20 16:38:30 -070012163 status = WLANSAP_SetKeySta( pVosContext, &setKey);
12164
12165 if ( status != eHAL_STATUS_SUCCESS )
12166 {
12167 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12168 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
12169 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012170 status = -EINVAL;
12171 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012172 }
12173 }
12174
12175 /* Saving WEP keys */
12176 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
12177 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
12178 {
12179 //Save the wep key in ap context. Issue setkey after the BSS is started.
12180 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
12181 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
12182 }
12183 else
12184 {
12185 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012186 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012187 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
12188 }
12189 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012190 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
12191 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012192 {
12193 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12194 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12195
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012196#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12197 if (!pairwise)
12198#else
12199 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
12200#endif
12201 {
12202 /* set group key*/
12203 if (pHddStaCtx->roam_info.deferKeyComplete)
12204 {
12205 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12206 "%s- %d: Perform Set key Complete",
12207 __func__, __LINE__);
12208 hdd_PerformRoamSetKeyComplete(pAdapter);
12209 }
12210 }
12211
Jeff Johnson295189b2012-06-20 16:38:30 -070012212 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
12213
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -080012214 pWextState->roamProfile.Keys.defaultIndex = key_index;
12215
12216
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012217 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070012218 params->key, params->key_len);
12219
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012220
Jeff Johnson295189b2012-06-20 16:38:30 -070012221 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
12222
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012223 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070012224 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012225 __func__, setKey.peerMac[0], setKey.peerMac[1],
12226 setKey.peerMac[2], setKey.peerMac[3],
12227 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070012228 setKey.keyDirection);
12229
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012230 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +053012231
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012232 if ( vos_status != VOS_STATUS_SUCCESS )
12233 {
12234 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012235 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
12236 __LINE__, vos_status );
12237
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012238 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012239
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012240 status = -EINVAL;
12241 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012242
12243 }
12244
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012245#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012246 /* The supplicant may attempt to set the PTK once pre-authentication
12247 is done. Save the key in the UMAC and include it in the ADD BSS
12248 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012249 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012250 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012251 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012252 hddLog(VOS_TRACE_LEVEL_INFO_MED,
12253 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012254 status = 0;
12255 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012256 }
12257 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
12258 {
12259 hddLog(VOS_TRACE_LEVEL_ERROR,
12260 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012261 status = -EINVAL;
12262 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012263 }
12264#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070012265
12266 /* issue set key request to SME*/
12267 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
12268 pAdapter->sessionId, &setKey, &roamId );
12269
12270 if ( 0 != status )
12271 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012272 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012273 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
12274 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012275 status = -EINVAL;
12276 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012277 }
12278
12279
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012280 /* in case of IBSS as there was no information available about WEP keys during
12281 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070012282 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012283 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
12284 !( ( IW_AUTH_KEY_MGMT_802_1X
12285 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070012286 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
12287 )
12288 &&
12289 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
12290 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
12291 )
12292 )
12293 {
12294 setKey.keyDirection = eSIR_RX_ONLY;
12295 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
12296
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012297 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070012298 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012299 __func__, setKey.peerMac[0], setKey.peerMac[1],
12300 setKey.peerMac[2], setKey.peerMac[3],
12301 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070012302 setKey.keyDirection);
12303
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012304 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070012305 pAdapter->sessionId, &setKey, &roamId );
12306
12307 if ( 0 != status )
12308 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012309 hddLog(VOS_TRACE_LEVEL_ERROR,
12310 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012311 __func__, status);
12312 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012313 status = -EINVAL;
12314 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012315 }
12316 }
12317 }
12318
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012319end:
12320 /* Need to clear any trace of key value in the memory.
12321 * Thus zero out the memory even though it is local
12322 * variable.
12323 */
12324 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012325 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012326 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012327}
12328
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012329#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12330static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
12331 struct net_device *ndev,
12332 u8 key_index, bool pairwise,
12333 const u8 *mac_addr,
12334 struct key_params *params
12335 )
12336#else
12337static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
12338 struct net_device *ndev,
12339 u8 key_index, const u8 *mac_addr,
12340 struct key_params *params
12341 )
12342#endif
12343{
12344 int ret;
12345 vos_ssr_protect(__func__);
12346#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12347 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
12348 mac_addr, params);
12349#else
12350 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
12351 params);
12352#endif
12353 vos_ssr_unprotect(__func__);
12354
12355 return ret;
12356}
12357
Jeff Johnson295189b2012-06-20 16:38:30 -070012358/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012359 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070012360 * This function is used to get the key information
12361 */
12362#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012363static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012364 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012365 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012366 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070012367 const u8 *mac_addr, void *cookie,
12368 void (*callback)(void *cookie, struct key_params*)
12369 )
12370#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012371static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012372 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012373 struct net_device *ndev,
12374 u8 key_index, const u8 *mac_addr, void *cookie,
12375 void (*callback)(void *cookie, struct key_params*)
12376 )
12377#endif
12378{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012379 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012380 hdd_wext_state_t *pWextState = NULL;
12381 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012382 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012383 hdd_context_t *pHddCtx;
12384 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012385
12386 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012387
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012388 if (NULL == pAdapter)
12389 {
12390 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12391 "%s: HDD adapter is Null", __func__);
12392 return -ENODEV;
12393 }
12394
12395 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12396 ret = wlan_hdd_validate_context(pHddCtx);
12397 if (0 != ret)
12398 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012399 return ret;
12400 }
12401
12402 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12403 pRoamProfile = &(pWextState->roamProfile);
12404
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012405 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12406 __func__, hdd_device_modetoString(pAdapter->device_mode),
12407 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012408
Jeff Johnson295189b2012-06-20 16:38:30 -070012409 memset(&params, 0, sizeof(params));
12410
12411 if (CSR_MAX_NUM_KEY <= key_index)
12412 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012413 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070012414 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012415 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012416
12417 switch(pRoamProfile->EncryptionType.encryptionType[0])
12418 {
12419 case eCSR_ENCRYPT_TYPE_NONE:
12420 params.cipher = IW_AUTH_CIPHER_NONE;
12421 break;
12422
12423 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
12424 case eCSR_ENCRYPT_TYPE_WEP40:
12425 params.cipher = WLAN_CIPHER_SUITE_WEP40;
12426 break;
12427
12428 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
12429 case eCSR_ENCRYPT_TYPE_WEP104:
12430 params.cipher = WLAN_CIPHER_SUITE_WEP104;
12431 break;
12432
12433 case eCSR_ENCRYPT_TYPE_TKIP:
12434 params.cipher = WLAN_CIPHER_SUITE_TKIP;
12435 break;
12436
12437 case eCSR_ENCRYPT_TYPE_AES:
12438 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
12439 break;
12440
12441 default:
12442 params.cipher = IW_AUTH_CIPHER_NONE;
12443 break;
12444 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012445
c_hpothuaaf19692014-05-17 17:01:48 +053012446 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12447 TRACE_CODE_HDD_CFG80211_GET_KEY,
12448 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012449
Jeff Johnson295189b2012-06-20 16:38:30 -070012450 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
12451 params.seq_len = 0;
12452 params.seq = NULL;
12453 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
12454 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012455 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012456 return 0;
12457}
12458
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012459#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12460static int wlan_hdd_cfg80211_get_key(
12461 struct wiphy *wiphy,
12462 struct net_device *ndev,
12463 u8 key_index, bool pairwise,
12464 const u8 *mac_addr, void *cookie,
12465 void (*callback)(void *cookie, struct key_params*)
12466 )
12467#else
12468static int wlan_hdd_cfg80211_get_key(
12469 struct wiphy *wiphy,
12470 struct net_device *ndev,
12471 u8 key_index, const u8 *mac_addr, void *cookie,
12472 void (*callback)(void *cookie, struct key_params*)
12473 )
12474#endif
12475{
12476 int ret;
12477
12478 vos_ssr_protect(__func__);
12479#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12480 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
12481 mac_addr, cookie, callback);
12482#else
12483 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
12484 callback);
12485#endif
12486 vos_ssr_unprotect(__func__);
12487
12488 return ret;
12489}
12490
Jeff Johnson295189b2012-06-20 16:38:30 -070012491/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012492 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070012493 * This function is used to delete the key information
12494 */
12495#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012496static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012497 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012498 u8 key_index,
12499 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070012500 const u8 *mac_addr
12501 )
12502#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012503static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012504 struct net_device *ndev,
12505 u8 key_index,
12506 const u8 *mac_addr
12507 )
12508#endif
12509{
12510 int status = 0;
12511
12512 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012513 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070012514 //it is observed that this is invalidating peer
12515 //key index whenever re-key is done. This is affecting data link.
12516 //It should be ok to ignore del_key.
12517#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012518 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
12519 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070012520 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
12521 tCsrRoamSetKey setKey;
12522 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012523
Jeff Johnson295189b2012-06-20 16:38:30 -070012524 ENTER();
12525
12526 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
12527 __func__,pAdapter->device_mode);
12528
12529 if (CSR_MAX_NUM_KEY <= key_index)
12530 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012531 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012532 key_index);
12533
12534 return -EINVAL;
12535 }
12536
12537 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
12538 setKey.keyId = key_index;
12539
12540 if (mac_addr)
12541 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
12542 else
12543 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
12544
12545 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
12546
12547 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012548 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012549 )
12550 {
12551
12552 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070012553 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
12554 if( pHostapdState->bssState == BSS_START)
12555 {
12556 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012557
Jeff Johnson295189b2012-06-20 16:38:30 -070012558 if ( status != eHAL_STATUS_SUCCESS )
12559 {
12560 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12561 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
12562 __LINE__, status );
12563 }
12564 }
12565 }
12566 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012567 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070012568 )
12569 {
12570 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12571
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012572 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
12573
12574 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070012575 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012576 __func__, setKey.peerMac[0], setKey.peerMac[1],
12577 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070012578 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012579 if(pAdapter->sessionCtx.station.conn_info.connState ==
12580 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070012581 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012582 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070012583 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012584
Jeff Johnson295189b2012-06-20 16:38:30 -070012585 if ( 0 != status )
12586 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012587 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012588 "%s: sme_RoamSetKey failure, returned %d",
12589 __func__, status);
12590 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
12591 return -EINVAL;
12592 }
12593 }
12594 }
12595#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070012596 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012597 return status;
12598}
12599
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012600#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12601static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
12602 struct net_device *ndev,
12603 u8 key_index,
12604 bool pairwise,
12605 const u8 *mac_addr
12606 )
12607#else
12608static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
12609 struct net_device *ndev,
12610 u8 key_index,
12611 const u8 *mac_addr
12612 )
12613#endif
12614{
12615 int ret;
12616
12617 vos_ssr_protect(__func__);
12618#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12619 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
12620 mac_addr);
12621#else
12622 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
12623#endif
12624 vos_ssr_unprotect(__func__);
12625
12626 return ret;
12627}
12628
Jeff Johnson295189b2012-06-20 16:38:30 -070012629/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012630 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070012631 * This function is used to set the default tx key index
12632 */
12633#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012634static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012635 struct net_device *ndev,
12636 u8 key_index,
12637 bool unicast, bool multicast)
12638#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012639static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012640 struct net_device *ndev,
12641 u8 key_index)
12642#endif
12643{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012644 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012645 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053012646 hdd_wext_state_t *pWextState;
12647 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012648 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012649
12650 ENTER();
12651
Gopichand Nakkala29149562013-05-10 21:43:41 +053012652 if ((NULL == pAdapter))
12653 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012654 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053012655 "invalid adapter");
12656 return -EINVAL;
12657 }
12658
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012659 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12660 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
12661 pAdapter->sessionId, key_index));
12662
Gopichand Nakkala29149562013-05-10 21:43:41 +053012663 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12664 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12665
12666 if ((NULL == pWextState) || (NULL == pHddStaCtx))
12667 {
12668 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12669 "invalid Wext state or HDD context");
12670 return -EINVAL;
12671 }
12672
Arif Hussain6d2a3322013-11-17 19:50:10 -080012673 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012674 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012675
Jeff Johnson295189b2012-06-20 16:38:30 -070012676 if (CSR_MAX_NUM_KEY <= key_index)
12677 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012678 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012679 key_index);
12680
12681 return -EINVAL;
12682 }
12683
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012684 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12685 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012686 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012687 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012688 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012689 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012690
Jeff Johnson295189b2012-06-20 16:38:30 -070012691 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070012692 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012693 )
Jeff Johnson295189b2012-06-20 16:38:30 -070012694 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053012695 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080012696 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012697 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080012698 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070012699 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012700 {
12701 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070012702 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012703
Jeff Johnson295189b2012-06-20 16:38:30 -070012704 tCsrRoamSetKey setKey;
12705 v_U32_t roamId= 0xFF;
12706 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012707
12708 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012709 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012710
Jeff Johnson295189b2012-06-20 16:38:30 -070012711 Keys->defaultIndex = (u8)key_index;
12712 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
12713 setKey.keyId = key_index;
12714 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012715
12716 vos_mem_copy(&setKey.Key[0],
12717 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070012718 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012719
Gopichand Nakkala29149562013-05-10 21:43:41 +053012720 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012721
12722 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070012723 &pHddStaCtx->conn_info.bssId[0],
12724 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012725
Gopichand Nakkala29149562013-05-10 21:43:41 +053012726 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
12727 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
12728 eCSR_ENCRYPT_TYPE_WEP104)
12729 {
12730 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
12731 even though ap is configured for WEP-40 encryption. In this canse the key length
12732 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
12733 type(104) and switching encryption type to 40*/
12734 pWextState->roamProfile.EncryptionType.encryptionType[0] =
12735 eCSR_ENCRYPT_TYPE_WEP40;
12736 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
12737 eCSR_ENCRYPT_TYPE_WEP40;
12738 }
12739
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012740 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070012741 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012742
Jeff Johnson295189b2012-06-20 16:38:30 -070012743 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012744 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070012745 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012746
Jeff Johnson295189b2012-06-20 16:38:30 -070012747 if ( 0 != status )
12748 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012749 hddLog(VOS_TRACE_LEVEL_ERROR,
12750 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012751 status);
12752 return -EINVAL;
12753 }
12754 }
12755 }
12756
12757 /* In SoftAp mode setting key direction for default mode */
12758 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
12759 {
12760 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
12761 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
12762 (eCSR_ENCRYPT_TYPE_AES !=
12763 pWextState->roamProfile.EncryptionType.encryptionType[0])
12764 )
12765 {
12766 /* Saving key direction for default key index to TX default */
12767 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
12768 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
12769 }
12770 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012771 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012772 return status;
12773}
12774
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012775#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12776static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
12777 struct net_device *ndev,
12778 u8 key_index,
12779 bool unicast, bool multicast)
12780#else
12781static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
12782 struct net_device *ndev,
12783 u8 key_index)
12784#endif
12785{
12786 int ret;
12787 vos_ssr_protect(__func__);
12788#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12789 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
12790 multicast);
12791#else
12792 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
12793#endif
12794 vos_ssr_unprotect(__func__);
12795
12796 return ret;
12797}
12798
Jeff Johnson295189b2012-06-20 16:38:30 -070012799/*
12800 * FUNCTION: wlan_hdd_cfg80211_inform_bss
12801 * This function is used to inform the BSS details to nl80211 interface.
12802 */
12803static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
12804 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
12805{
12806 struct net_device *dev = pAdapter->dev;
12807 struct wireless_dev *wdev = dev->ieee80211_ptr;
12808 struct wiphy *wiphy = wdev->wiphy;
12809 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
12810 int chan_no;
12811 int ie_length;
12812 const char *ie;
12813 unsigned int freq;
12814 struct ieee80211_channel *chan;
12815 int rssi = 0;
12816 struct cfg80211_bss *bss = NULL;
12817
Jeff Johnson295189b2012-06-20 16:38:30 -070012818 if( NULL == pBssDesc )
12819 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012820 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012821 return bss;
12822 }
12823
12824 chan_no = pBssDesc->channelId;
12825 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
12826 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
12827
12828 if( NULL == ie )
12829 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012830 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012831 return bss;
12832 }
12833
12834#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
12835 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
12836 {
12837 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
12838 }
12839 else
12840 {
12841 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
12842 }
12843#else
12844 freq = ieee80211_channel_to_frequency(chan_no);
12845#endif
12846
12847 chan = __ieee80211_get_channel(wiphy, freq);
12848
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053012849 if (!chan) {
12850 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
12851 return NULL;
12852 }
12853
Abhishek Singhaee43942014-06-16 18:55:47 +053012854 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070012855
Anand N Sunkad9f80b742015-07-30 20:05:51 +053012856 return cfg80211_inform_bss(wiphy, chan,
12857#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12858 CFG80211_BSS_FTYPE_UNKNOWN,
12859#endif
12860 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012861 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070012862 pBssDesc->capabilityInfo,
12863 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053012864 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070012865}
12866
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053012867/*
12868 * wlan_hdd_cfg80211_update_bss_list :to inform nl80211
12869 * interface that BSS might have been lost.
12870 * @pAdapter: adaptor
12871 * @bssid: bssid which might have been lost
12872 *
12873 * Return: bss which is unlinked from kernel cache
12874 */
12875struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_list(
12876 hdd_adapter_t *pAdapter, tSirMacAddr bssid)
12877{
12878 struct net_device *dev = pAdapter->dev;
12879 struct wireless_dev *wdev = dev->ieee80211_ptr;
12880 struct wiphy *wiphy = wdev->wiphy;
12881 struct cfg80211_bss *bss = NULL;
12882
Abhishek Singh5a597e62016-12-05 15:16:30 +053012883 bss = hdd_get_bss_entry(wiphy,
12884 NULL, bssid,
12885 NULL, 0);
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053012886 if (bss == NULL) {
12887 hddLog(LOGE, FL("BSS not present"));
12888 } else {
12889 hddLog(LOG1, FL("cfg80211_unlink_bss called for BSSID "
12890 MAC_ADDRESS_STR), MAC_ADDR_ARRAY(bssid));
12891 cfg80211_unlink_bss(wiphy, bss);
12892 }
12893 return bss;
12894}
Jeff Johnson295189b2012-06-20 16:38:30 -070012895
12896
12897/*
12898 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
12899 * This function is used to inform the BSS details to nl80211 interface.
12900 */
12901struct cfg80211_bss*
12902wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
12903 tSirBssDescription *bss_desc
12904 )
12905{
12906 /*
12907 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
12908 already exists in bss data base of cfg80211 for that particular BSS ID.
12909 Using cfg80211_inform_bss_frame to update the bss entry instead of
12910 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
12911 now there is no possibility to get the mgmt(probe response) frame from PE,
12912 converting bss_desc to ieee80211_mgmt(probe response) and passing to
12913 cfg80211_inform_bss_frame.
12914 */
12915 struct net_device *dev = pAdapter->dev;
12916 struct wireless_dev *wdev = dev->ieee80211_ptr;
12917 struct wiphy *wiphy = wdev->wiphy;
12918 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012919#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
12920 qcom_ie_age *qie_age = NULL;
12921 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
12922#else
Jeff Johnson295189b2012-06-20 16:38:30 -070012923 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012924#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012925 const char *ie =
12926 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
12927 unsigned int freq;
12928 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053012929 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012930 struct cfg80211_bss *bss_status = NULL;
12931 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
12932 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070012933 hdd_context_t *pHddCtx;
12934 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070012935#ifdef WLAN_OPEN_SOURCE
12936 struct timespec ts;
12937#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012938
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012939
Wilson Yangf80a0542013-10-07 13:02:37 -070012940 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12941 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070012942 if (0 != status)
12943 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070012944 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070012945 }
12946
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053012947 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070012948 if (!mgmt)
12949 {
12950 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12951 "%s: memory allocation failed ", __func__);
12952 return NULL;
12953 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070012954
Jeff Johnson295189b2012-06-20 16:38:30 -070012955 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070012956
12957#ifdef WLAN_OPEN_SOURCE
12958 /* Android does not want the timestamp from the frame.
12959 Instead it wants a monotonic increasing value */
12960 get_monotonic_boottime(&ts);
12961 mgmt->u.probe_resp.timestamp =
12962 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
12963#else
12964 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070012965 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
12966 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070012967
12968#endif
12969
Jeff Johnson295189b2012-06-20 16:38:30 -070012970 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
12971 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012972
12973#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
12974 /* GPS Requirement: need age ie per entry. Using vendor specific. */
12975 /* Assuming this is the last IE, copy at the end */
12976 ie_length -=sizeof(qcom_ie_age);
12977 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
12978 qie_age->element_id = QCOM_VENDOR_IE_ID;
12979 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
12980 qie_age->oui_1 = QCOM_OUI1;
12981 qie_age->oui_2 = QCOM_OUI2;
12982 qie_age->oui_3 = QCOM_OUI3;
12983 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
Selvaraj, Sridhar4b3a8362016-10-12 12:34:08 +053012984 /* Lowi expects the timestamp of bss in units of 1/10 ms. In driver all
12985 * bss related timestamp is in units of ms. Due to this when scan results
12986 * are sent to lowi the scan age is high.To address this, send age in units
12987 * of 1/10 ms.
12988 */
12989 qie_age->age = (vos_timer_get_system_time() -
12990 bss_desc->nReceivedTime)/10;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012991#endif
12992
Jeff Johnson295189b2012-06-20 16:38:30 -070012993 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053012994 if (bss_desc->fProbeRsp)
12995 {
12996 mgmt->frame_control |=
12997 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
12998 }
12999 else
13000 {
13001 mgmt->frame_control |=
13002 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
13003 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013004
13005#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013006 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070013007 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
13008 {
13009 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
13010 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013011 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070013012 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
13013
13014 {
13015 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
13016 }
13017 else
13018 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013019 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
13020 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070013021 kfree(mgmt);
13022 return NULL;
13023 }
13024#else
13025 freq = ieee80211_channel_to_frequency(chan_no);
13026#endif
13027 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080013028 /*when the band is changed on the fly using the GUI, three things are done
13029 * 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)
13030 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
13031 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
13032 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
13033 * and discards the channels correponding to previous band and calls back with zero bss results.
13034 * 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
13035 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
13036 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
13037 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
13038 * So drop the bss and continue to next bss.
13039 */
13040 if(chan == NULL)
13041 {
Deepthi Gowri306657b2016-04-28 17:10:41 +053013042 hddLog(VOS_TRACE_LEVEL_ERROR,
13043 FL("chan pointer is NULL, chan_no: %d freq: %d"),
13044 chan_no, freq);
Chilam Ngc4244af2013-04-01 15:37:32 -070013045 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080013046 return NULL;
13047 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053013048 /*To keep the rssi icon of the connected AP in the scan window
13049 *and the rssi icon of the wireless networks in sync
13050 * */
13051 if (( eConnectionState_Associated ==
13052 pAdapter->sessionCtx.station.conn_info.connState ) &&
13053 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
13054 pAdapter->sessionCtx.station.conn_info.bssId,
13055 WNI_CFG_BSSID_LEN)) &&
13056 (pHddCtx->hdd_wlan_suspended == FALSE))
13057 {
13058 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
13059 rssi = (pAdapter->rssi * 100);
13060 }
13061 else
13062 {
13063 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
13064 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013065
Nirav Shah20ac06f2013-12-12 18:14:06 +053013066 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053013067 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
13068 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053013069
Jeff Johnson295189b2012-06-20 16:38:30 -070013070 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
13071 frame_len, rssi, GFP_KERNEL);
13072 kfree(mgmt);
13073 return bss_status;
13074}
13075
13076/*
13077 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
13078 * This function is used to update the BSS data base of CFG8011
13079 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013080struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070013081 tCsrRoamInfo *pRoamInfo
13082 )
13083{
13084 tCsrRoamConnectedProfile roamProfile;
13085 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13086 struct cfg80211_bss *bss = NULL;
13087
13088 ENTER();
13089
13090 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
13091 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
13092
13093 if (NULL != roamProfile.pBssDesc)
13094 {
Girish Gowlif4b68022014-08-28 23:18:57 +053013095 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
13096 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070013097
13098 if (NULL == bss)
13099 {
13100 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
13101 __func__);
13102 }
13103
13104 sme_RoamFreeConnectProfile(hHal, &roamProfile);
13105 }
13106 else
13107 {
13108 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
13109 __func__);
13110 }
13111 return bss;
13112}
13113
13114/*
13115 * FUNCTION: wlan_hdd_cfg80211_update_bss
13116 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013117static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
13118 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070013119 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013120{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013121 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013122 tCsrScanResultInfo *pScanResult;
13123 eHalStatus status = 0;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013124 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013125 tScanResultHandle pResult;
13126 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070013127 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013128 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070013129 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013130
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013131 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13132 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
13133 NO_SESSION, pAdapter->sessionId));
13134
Wilson Yangf80a0542013-10-07 13:02:37 -070013135 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013136 ret = wlan_hdd_validate_context(pHddCtx);
13137 if (0 != ret)
Jeff Johnson295189b2012-06-20 16:38:30 -070013138 {
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013139 return ret;
Wilson Yangf80a0542013-10-07 13:02:37 -070013140 }
13141
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013142 if (pAdapter->request != NULL)
13143 {
13144 if ((pAdapter->request->n_ssids == 1)
13145 && (pAdapter->request->ssids != NULL)
13146 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
13147 is_p2p_scan = true;
13148 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013149 /*
13150 * start getting scan results and populate cgf80211 BSS database
13151 */
13152 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
13153
13154 /* no scan results */
13155 if (NULL == pResult)
13156 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013157 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
13158 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053013159 wlan_hdd_get_frame_logs(pAdapter,
13160 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070013161 return status;
13162 }
13163
13164 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
13165
13166 while (pScanResult)
13167 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013168 /*
13169 * cfg80211_inform_bss() is not updating ie field of bss entry, if
13170 * entry already exists in bss data base of cfg80211 for that
13171 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
13172 * bss entry instead of cfg80211_inform_bss, But this call expects
13173 * mgmt packet as input. As of now there is no possibility to get
13174 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070013175 * ieee80211_mgmt(probe response) and passing to c
13176 * fg80211_inform_bss_frame.
13177 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013178 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
13179 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
13180 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013181 pScanResult = sme_ScanResultGetNext(hHal, pResult);
13182 continue; //Skip the non p2p bss entries
13183 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013184 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
13185 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013186
Jeff Johnson295189b2012-06-20 16:38:30 -070013187
13188 if (NULL == bss_status)
13189 {
13190 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013191 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013192 }
13193 else
13194 {
Yue Maf49ba872013-08-19 12:04:25 -070013195 cfg80211_put_bss(
13196#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
13197 wiphy,
13198#endif
13199 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070013200 }
13201
13202 pScanResult = sme_ScanResultGetNext(hHal, pResult);
13203 }
13204
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013205 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013206 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013207 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013208}
13209
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013210void
13211hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
13212{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013213 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080013214 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013215} /****** end hddPrintMacAddr() ******/
13216
13217void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070013218hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013219{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013220 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013221 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070013222 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
13223 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
13224 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013225} /****** end hddPrintPmkId() ******/
13226
13227//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
13228//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
13229
13230//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
13231//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
13232
13233#define dump_bssid(bssid) \
13234 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070013235 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
13236 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013237 }
13238
13239#define dump_pmkid(pMac, pmkid) \
13240 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070013241 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
13242 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013243 }
13244
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070013245#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013246/*
13247 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
13248 * This function is used to notify the supplicant of a new PMKSA candidate.
13249 */
13250int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013251 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013252 int index, bool preauth )
13253{
Jeff Johnsone7245742012-09-05 17:12:55 -070013254#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013255 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070013256 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013257
13258 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070013259 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013260
13261 if( NULL == pRoamInfo )
13262 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013263 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013264 return -EINVAL;
13265 }
13266
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070013267 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
13268 {
13269 dump_bssid(pRoamInfo->bssid);
13270 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013271 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070013272 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013273#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013274 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013275}
13276#endif //FEATURE_WLAN_LFR
13277
Yue Maef608272013-04-08 23:09:17 -070013278#ifdef FEATURE_WLAN_LFR_METRICS
13279/*
13280 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
13281 * 802.11r/LFR metrics reporting function to report preauth initiation
13282 *
13283 */
13284#define MAX_LFR_METRICS_EVENT_LENGTH 100
13285VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
13286 tCsrRoamInfo *pRoamInfo)
13287{
13288 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
13289 union iwreq_data wrqu;
13290
13291 ENTER();
13292
13293 if (NULL == pAdapter)
13294 {
13295 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
13296 return VOS_STATUS_E_FAILURE;
13297 }
13298
13299 /* create the event */
13300 memset(&wrqu, 0, sizeof(wrqu));
13301 memset(metrics_notification, 0, sizeof(metrics_notification));
13302
13303 wrqu.data.pointer = metrics_notification;
13304 wrqu.data.length = scnprintf(metrics_notification,
13305 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
13306 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
13307
13308 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
13309
13310 EXIT();
13311
13312 return VOS_STATUS_SUCCESS;
13313}
13314
13315/*
13316 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
13317 * 802.11r/LFR metrics reporting function to report preauth completion
13318 * or failure
13319 */
13320VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
13321 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
13322{
13323 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
13324 union iwreq_data wrqu;
13325
13326 ENTER();
13327
13328 if (NULL == pAdapter)
13329 {
13330 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
13331 return VOS_STATUS_E_FAILURE;
13332 }
13333
13334 /* create the event */
13335 memset(&wrqu, 0, sizeof(wrqu));
13336 memset(metrics_notification, 0, sizeof(metrics_notification));
13337
13338 scnprintf(metrics_notification, sizeof(metrics_notification),
13339 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
13340 MAC_ADDR_ARRAY(pRoamInfo->bssid));
13341
13342 if (1 == preauth_status)
13343 strncat(metrics_notification, " TRUE", 5);
13344 else
13345 strncat(metrics_notification, " FALSE", 6);
13346
13347 wrqu.data.pointer = metrics_notification;
13348 wrqu.data.length = strlen(metrics_notification);
13349
13350 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
13351
13352 EXIT();
13353
13354 return VOS_STATUS_SUCCESS;
13355}
13356
13357/*
13358 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
13359 * 802.11r/LFR metrics reporting function to report handover initiation
13360 *
13361 */
13362VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
13363 tCsrRoamInfo *pRoamInfo)
13364{
13365 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
13366 union iwreq_data wrqu;
13367
13368 ENTER();
13369
13370 if (NULL == pAdapter)
13371 {
13372 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
13373 return VOS_STATUS_E_FAILURE;
13374 }
13375
13376 /* create the event */
13377 memset(&wrqu, 0, sizeof(wrqu));
13378 memset(metrics_notification, 0, sizeof(metrics_notification));
13379
13380 wrqu.data.pointer = metrics_notification;
13381 wrqu.data.length = scnprintf(metrics_notification,
13382 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
13383 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
13384
13385 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
13386
13387 EXIT();
13388
13389 return VOS_STATUS_SUCCESS;
13390}
13391#endif
13392
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013393
13394/**
13395 * wlan_hdd_cfg80211_validate_scan_req - validate scan request
13396 * @scan_req: scan request to be checked
13397 *
13398 * Return: true or false
13399 */
13400#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
13401static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
13402 cfg80211_scan_request
13403 *scan_req)
13404{
13405 if (!scan_req || !scan_req->wiphy) {
13406 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
13407 return false;
13408 }
13409 if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HDD, NULL)) {
13410 hddLog(VOS_TRACE_LEVEL_ERROR, "Load/Unload in progress");
13411 return false;
13412 }
13413 return true;
13414}
13415#else
13416static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
13417 cfg80211_scan_request
13418 *scan_req)
13419{
13420 if (!scan_req || !scan_req->wiphy) {
13421 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
13422 return false;
13423 }
13424 return true;
13425}
13426#endif
13427
13428
Jeff Johnson295189b2012-06-20 16:38:30 -070013429/*
13430 * FUNCTION: hdd_cfg80211_scan_done_callback
13431 * scanning callback function, called after finishing scan
13432 *
13433 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013434static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070013435 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
13436{
13437 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013438 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070013439 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013440 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070013441 struct cfg80211_scan_request *req = NULL;
13442 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053013443 bool aborted = false;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013444#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
13445 bool iface_down = false;
13446#endif
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013447 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013448 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013449 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013450
13451 ENTER();
13452
c_manjee1b4ab9a2016-10-26 11:36:55 +053013453 if (!pAdapter || pAdapter->magic != WLAN_HDD_ADAPTER_MAGIC ||
13454 !pAdapter->dev) {
13455 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Adapter is not valid"));
13456 return 0;
13457 }
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013458 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053013459 if (NULL == pHddCtx) {
13460 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013461 return 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013462 }
13463
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053013464#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
13465 if (!(pAdapter->dev->flags & IFF_UP))
13466 {
13467 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Interface is down"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013468 iface_down = true;
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053013469 }
13470#endif
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013471 pScanInfo = &pHddCtx->scan_info;
13472
Jeff Johnson295189b2012-06-20 16:38:30 -070013473 hddLog(VOS_TRACE_LEVEL_INFO,
13474 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080013475 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013476 __func__, halHandle, pContext, (int) scanId, (int) status);
13477
Kiet Lamac06e2c2013-10-23 16:25:07 +053013478 pScanInfo->mScanPendingCounter = 0;
13479
Jeff Johnson295189b2012-06-20 16:38:30 -070013480 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013481 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070013482 &pScanInfo->scan_req_completion_event,
13483 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013484 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070013485 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013486 hddLog(VOS_TRACE_LEVEL_ERROR,
13487 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070013488 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070013489 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070013490 }
13491
Yue Maef608272013-04-08 23:09:17 -070013492 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070013493 {
13494 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070013495 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070013496 }
13497
13498 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013499 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070013500 {
13501 hddLog(VOS_TRACE_LEVEL_INFO,
13502 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080013503 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070013504 (int) scanId);
13505 }
13506
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053013507#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013508 if (!iface_down)
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053013509#endif
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013510 {
13511 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
13512 pAdapter);
13513 if (0 > ret)
13514 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053013515 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013516
Jeff Johnson295189b2012-06-20 16:38:30 -070013517 /* If any client wait scan result through WEXT
13518 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013519 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070013520 {
13521 /* The other scan request waiting for current scan finish
13522 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013523 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070013524 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013525 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070013526 }
13527 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013528 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070013529 {
13530 struct net_device *dev = pAdapter->dev;
13531 union iwreq_data wrqu;
13532 int we_event;
13533 char *msg;
13534
13535 memset(&wrqu, '\0', sizeof(wrqu));
13536 we_event = SIOCGIWSCAN;
13537 msg = NULL;
13538 wireless_send_event(dev, we_event, &wrqu, msg);
13539 }
13540 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013541 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013542
13543 /* Get the Scan Req */
13544 req = pAdapter->request;
mukul sharmae7041822015-12-03 15:09:21 +053013545 pAdapter->request = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013546
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013547 /* Scan is no longer pending */
13548 pScanInfo->mScanPending = VOS_FALSE;
13549
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013550 if (!wlan_hdd_cfg80211_validate_scan_req(req))
Jeff Johnson295189b2012-06-20 16:38:30 -070013551 {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013552#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
13553 hddLog(VOS_TRACE_LEVEL_ERROR, FL("interface state %s"),
13554 iface_down ? "up" : "down");
13555#endif
13556
13557 if (pAdapter->dev) {
13558 hddLog(VOS_TRACE_LEVEL_ERROR, FL("device name %s"),
13559 pAdapter->dev->name);
13560 }
mukul sharmae7041822015-12-03 15:09:21 +053013561 complete(&pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -070013562 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070013563 }
13564
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013565 /* last_scan_timestamp is used to decide if new scan
13566 * is needed or not on station interface. If last station
13567 * scan time and new station scan time is less then
13568 * last_scan_timestamp ; driver will return cached scan.
13569 */
13570 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
13571 {
13572 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
13573
13574 if ( req->n_channels )
13575 {
13576 for (i = 0; i < req->n_channels ; i++ )
13577 {
13578 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
13579 }
13580 /* store no of channel scanned */
13581 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
13582 }
13583
13584 }
13585
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070013586 /*
13587 * cfg80211_scan_done informing NL80211 about completion
13588 * of scanning
13589 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053013590 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
13591 {
13592 aborted = true;
13593 }
mukul sharmae7041822015-12-03 15:09:21 +053013594
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013595#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
13596 if (!iface_down)
13597#endif
13598 cfg80211_scan_done(req, aborted);
mukul sharmae7041822015-12-03 15:09:21 +053013599
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080013600 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070013601
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013602allow_suspend:
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053013603 if ((pHddCtx->cfg_ini->enableMacSpoofing == MAC_ADDR_SPOOFING_FW_HOST_ENABLE
13604 ) && (pHddCtx->spoofMacAddr.isEnabled
13605 || pHddCtx->spoofMacAddr.isReqDeferred)) {
Siddharth Bhal76972212014-10-15 16:22:51 +053013606 /* Generate new random mac addr for next scan */
13607 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +053013608
13609 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
13610 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhal76972212014-10-15 16:22:51 +053013611 }
13612
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070013613 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013614 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070013615
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070013616 /* Acquire wakelock to handle the case where APP's tries to suspend
13617 * immediatly after the driver gets connect request(i.e after scan)
13618 * from supplicant, this result in app's is suspending and not able
13619 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013620 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070013621
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013622#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
13623 if (!iface_down)
13624#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070013625#ifdef FEATURE_WLAN_TDLS
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013626 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070013627#endif
13628
Jeff Johnson295189b2012-06-20 16:38:30 -070013629 EXIT();
13630 return 0;
13631}
13632
13633/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053013634 * FUNCTION: hdd_isConnectionInProgress
13635 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013636 *
13637 */
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013638v_BOOL_t hdd_isConnectionInProgress(hdd_context_t *pHddCtx, v_U8_t *session_id,
13639 scan_reject_states *reason)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013640{
13641 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
13642 hdd_station_ctx_t *pHddStaCtx = NULL;
13643 hdd_adapter_t *pAdapter = NULL;
13644 VOS_STATUS status = 0;
13645 v_U8_t staId = 0;
13646 v_U8_t *staMac = NULL;
13647
13648 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
13649
13650 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
13651 {
13652 pAdapter = pAdapterNode->pAdapter;
13653
13654 if( pAdapter )
13655 {
13656 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013657 "%s: Adapter with device mode %s (%d) exists",
13658 __func__, hdd_device_modetoString(pAdapter->device_mode),
13659 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013660 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053013661 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
13662 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
13663 (eConnectionState_Connecting ==
13664 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
13665 {
13666 hddLog(VOS_TRACE_LEVEL_ERROR,
13667 "%s: %p(%d) Connection is in progress", __func__,
13668 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013669 if (session_id && reason)
13670 {
13671 *session_id = pAdapter->sessionId;
13672 *reason = eHDD_CONNECTION_IN_PROGRESS;
13673 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053013674 return VOS_TRUE;
13675 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013676 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053013677 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013678 {
13679 hddLog(VOS_TRACE_LEVEL_ERROR,
13680 "%s: %p(%d) Reassociation is in progress", __func__,
13681 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013682 if (session_id && reason)
13683 {
13684 *session_id = pAdapter->sessionId;
13685 *reason = eHDD_REASSOC_IN_PROGRESS;
13686 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013687 return VOS_TRUE;
13688 }
13689 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013690 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
13691 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013692 {
13693 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13694 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013695 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013696 {
13697 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
13698 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080013699 "%s: client " MAC_ADDRESS_STR
13700 " is in the middle of WPS/EAPOL exchange.", __func__,
13701 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013702 if (session_id && reason)
13703 {
13704 *session_id = pAdapter->sessionId;
13705 *reason = eHDD_EAPOL_IN_PROGRESS;
13706 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053013707 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013708 }
13709 }
13710 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
13711 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
13712 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013713 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
13714 ptSapContext pSapCtx = NULL;
13715 pSapCtx = VOS_GET_SAP_CB(pVosContext);
13716 if(pSapCtx == NULL){
13717 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13718 FL("psapCtx is NULL"));
13719 return VOS_FALSE;
13720 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013721 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
13722 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013723 if ((pSapCtx->aStaInfo[staId].isUsed) &&
13724 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013725 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013726 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013727
13728 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080013729 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
13730 "middle of WPS/EAPOL exchange.", __func__,
13731 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013732 if (session_id && reason)
13733 {
13734 *session_id = pAdapter->sessionId;
13735 *reason = eHDD_SAP_EAPOL_IN_PROGRESS;
13736 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053013737 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013738 }
13739 }
13740 }
13741 }
13742 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13743 pAdapterNode = pNext;
13744 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053013745 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013746}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013747
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053013748/**
13749 * csr_scan_request_assign_bssid() - Set the BSSID received from Supplicant
13750 * to the Scan request
13751 * @scanRequest: Pointer to the csr scan request
13752 * @request: Pointer to the scan request from supplicant
13753 *
13754 * Return: None
13755 */
13756#ifdef CFG80211_SCAN_BSSID
13757static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
13758 struct cfg80211_scan_request *request)
13759{
13760 vos_mem_copy(scanRequest->bssid, request->bssid, VOS_MAC_ADDR_SIZE);
13761}
13762#else
13763static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
13764 struct cfg80211_scan_request *request)
13765{
13766}
13767#endif
13768
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013769/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013770 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070013771 * this scan respond to scan trigger and update cfg80211 scan database
13772 * later, scan dump command can be used to recieve scan results
13773 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013774int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080013775#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13776 struct net_device *dev,
13777#endif
13778 struct cfg80211_scan_request *request)
13779{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013780 hdd_adapter_t *pAdapter = NULL;
13781 hdd_context_t *pHddCtx = NULL;
13782 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013783 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013784 tCsrScanRequest scanRequest;
13785 tANI_U8 *channelList = NULL, i;
13786 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013787 int status;
13788 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013789 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013790 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053013791 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013792 bool is_p2p_scan = false;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013793 v_U8_t curr_session_id;
13794 scan_reject_states curr_reason;
Jeff Johnson295189b2012-06-20 16:38:30 -070013795
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013796#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
13797 struct net_device *dev = NULL;
13798 if (NULL == request)
13799 {
13800 hddLog(VOS_TRACE_LEVEL_ERROR,
13801 "%s: scan req param null", __func__);
13802 return -EINVAL;
13803 }
13804 dev = request->wdev->netdev;
13805#endif
13806
13807 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
13808 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
13809 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13810
Jeff Johnson295189b2012-06-20 16:38:30 -070013811 ENTER();
13812
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013813 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13814 __func__, hdd_device_modetoString(pAdapter->device_mode),
13815 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013816
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013817 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013818 if (0 != status)
13819 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013820 return status;
13821 }
13822
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013823 if (NULL == pwextBuf)
13824 {
13825 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
13826 __func__);
13827 return -EIO;
13828 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013829 cfg_param = pHddCtx->cfg_ini;
13830 pScanInfo = &pHddCtx->scan_info;
13831
Jeff Johnson295189b2012-06-20 16:38:30 -070013832#ifdef WLAN_BTAMP_FEATURE
13833 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013834 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070013835 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080013836 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013837 "%s: No scanning when AMP is on", __func__);
13838 return -EOPNOTSUPP;
13839 }
13840#endif
13841 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013842 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070013843 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013844 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013845 "%s: Not scanning on device_mode = %s (%d)",
13846 __func__, hdd_device_modetoString(pAdapter->device_mode),
13847 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013848 return -EOPNOTSUPP;
13849 }
13850
13851 if (TRUE == pScanInfo->mScanPending)
13852 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053013853 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
13854 {
13855 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
13856 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013857 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070013858 }
13859
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053013860 // Don't allow scan if PNO scan is going on.
13861 if (pHddCtx->isPnoEnable)
13862 {
13863 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13864 FL("pno scan in progress"));
13865 return -EBUSY;
13866 }
13867
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013868 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070013869 //Channel and action frame is pending
13870 //Otherwise Cancel Remain On Channel and allow Scan
13871 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013872 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070013873 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053013874 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070013875 return -EBUSY;
13876 }
13877
Jeff Johnson295189b2012-06-20 16:38:30 -070013878 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
13879 {
13880 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080013881 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013882 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013883 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013884 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
13885 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013886 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013887 "%s: MAX TM Level Scan not allowed", __func__);
13888 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013889 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070013890 }
13891 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
13892
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013893 /* Check if scan is allowed at this point of time.
13894 */
Hanumanth Reddy Pothulaec960842016-09-14 19:04:26 +053013895 if (TRUE == pHddCtx->btCoexModeSet)
13896 {
13897 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13898 FL("BTCoex Mode operation in progress"));
13899 return -EBUSY;
13900 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013901 if (hdd_isConnectionInProgress(pHddCtx, &curr_session_id, &curr_reason))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013902 {
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053013903 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Scan not allowed"));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013904 if (pHddCtx->last_scan_reject_session_id != curr_session_id ||
13905 pHddCtx->last_scan_reject_reason != curr_reason ||
13906 !pHddCtx->last_scan_reject_timestamp)
13907 {
13908 pHddCtx->last_scan_reject_session_id = curr_session_id;
13909 pHddCtx->last_scan_reject_reason = curr_reason;
Sreelakshmi Konamkif0646d52016-12-09 12:35:31 +053013910 pHddCtx->last_scan_reject_timestamp = jiffies_to_msecs(jiffies);
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053013911 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013912 else {
Sreelakshmi Konamkif0646d52016-12-09 12:35:31 +053013913 if ((jiffies_to_msecs(jiffies) -
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013914 pHddCtx->last_scan_reject_timestamp) >=
13915 SCAN_REJECT_THRESHOLD_TIME)
13916 {
13917 pHddCtx->last_scan_reject_timestamp = 0;
13918 if (pHddCtx->cfg_ini->enableFatalEvent)
13919 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
13920 WLAN_LOG_INDICATOR_HOST_DRIVER,
13921 WLAN_LOG_REASON_SCAN_NOT_ALLOWED,
13922 FALSE, FALSE);
13923 else
13924 {
13925 hddLog(LOGE, FL("Triggering SSR"));
13926 vos_wlanRestart();
13927 }
13928 }
13929 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013930 return -EBUSY;
13931 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013932 pHddCtx->last_scan_reject_timestamp = 0;
13933 pHddCtx->last_scan_reject_session_id = 0xFF;
13934 pHddCtx->last_scan_reject_reason = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013935
Jeff Johnson295189b2012-06-20 16:38:30 -070013936 vos_mem_zero( &scanRequest, sizeof(scanRequest));
13937
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013938 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
13939 * Becasue of this, driver is assuming that this is not wildcard scan and so
13940 * is not aging out the scan results.
13941 */
13942 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070013943 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013944 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013945 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013946
13947 if ((request->ssids) && (0 < request->n_ssids))
13948 {
13949 tCsrSSIDInfo *SsidInfo;
13950 int j;
13951 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
13952 /* Allocate num_ssid tCsrSSIDInfo structure */
13953 SsidInfo = scanRequest.SSIDs.SSIDList =
13954 ( tCsrSSIDInfo *)vos_mem_malloc(
13955 request->n_ssids*sizeof(tCsrSSIDInfo));
13956
13957 if(NULL == scanRequest.SSIDs.SSIDList)
13958 {
13959 hddLog(VOS_TRACE_LEVEL_ERROR,
13960 "%s: memory alloc failed SSIDInfo buffer", __func__);
13961 return -ENOMEM;
13962 }
13963
13964 /* copy all the ssid's and their length */
13965 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
13966 {
13967 /* get the ssid length */
13968 SsidInfo->SSID.length = request->ssids[j].ssid_len;
13969 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
13970 SsidInfo->SSID.length);
13971 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
13972 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
13973 j, SsidInfo->SSID.ssId);
13974 }
13975 /* set the scan type to active */
13976 scanRequest.scanType = eSIR_ACTIVE_SCAN;
13977 }
13978 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070013979 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013980 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13981 TRACE_CODE_HDD_CFG80211_SCAN,
13982 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070013983 /* set the scan type to active */
13984 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070013985 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013986 else
13987 {
13988 /*Set the scan type to default type, in this case it is ACTIVE*/
13989 scanRequest.scanType = pScanInfo->scan_mode;
13990 }
13991 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
13992 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070013993
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053013994 csr_scan_request_assign_bssid(&scanRequest, request);
13995
Jeff Johnson295189b2012-06-20 16:38:30 -070013996 /* set BSSType to default type */
13997 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
13998
13999 /*TODO: scan the requested channels only*/
14000
14001 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014002 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070014003 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014004 hddLog(VOS_TRACE_LEVEL_WARN,
14005 "No of Scan Channels exceeded limit: %d", request->n_channels);
14006 request->n_channels = MAX_CHANNEL;
14007 }
14008
14009 hddLog(VOS_TRACE_LEVEL_INFO,
14010 "No of Scan Channels: %d", request->n_channels);
14011
14012
14013 if( request->n_channels )
14014 {
14015 char chList [(request->n_channels*5)+1];
14016 int len;
14017 channelList = vos_mem_malloc( request->n_channels );
14018 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053014019 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014020 hddLog(VOS_TRACE_LEVEL_ERROR,
14021 "%s: memory alloc failed channelList", __func__);
14022 status = -ENOMEM;
14023 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053014024 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014025
14026 for( i = 0, len = 0; i < request->n_channels ; i++ )
14027 {
14028 channelList[i] = request->channels[i]->hw_value;
14029 len += snprintf(chList+len, 5, "%d ", channelList[i]);
14030 }
14031
Nirav Shah20ac06f2013-12-12 18:14:06 +053014032 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014033 "Channel-List: %s ", chList);
14034 }
c_hpothu53512302014-04-15 18:49:53 +053014035
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014036 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
14037 scanRequest.ChannelInfo.ChannelList = channelList;
14038
14039 /* set requestType to full scan */
14040 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
14041
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014042 /* if there is back to back scan happening in driver with in
14043 * nDeferScanTimeInterval interval driver should defer new scan request
14044 * and should provide last cached scan results instead of new channel list.
14045 * This rule is not applicable if scan is p2p scan.
14046 * This condition will work only in case when last request no of channels
14047 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053014048 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053014049 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014050 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014051
Sushant Kaushik86592172015-04-27 16:35:03 +053014052 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
14053 /* if wps ie is NULL , then only defer scan */
14054 if ( pWpsIe == NULL &&
14055 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053014056 {
14057 if ( pScanInfo->last_scan_timestamp !=0 &&
14058 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
14059 {
14060 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
14061 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
14062 vos_mem_compare(pScanInfo->last_scan_channelList,
14063 channelList, pScanInfo->last_scan_numChannels))
14064 {
14065 hddLog(VOS_TRACE_LEVEL_WARN,
14066 " New and old station scan time differ is less then %u",
14067 pHddCtx->cfg_ini->nDeferScanTimeInterval);
14068
14069 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014070 pAdapter);
14071
Agarwal Ashish57e84372014-12-05 18:26:53 +053014072 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053014073 "Return old cached scan as all channels and no of channels are same");
14074
Agarwal Ashish57e84372014-12-05 18:26:53 +053014075 if (0 > ret)
14076 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014077
Agarwal Ashish57e84372014-12-05 18:26:53 +053014078 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053014079
14080 status = eHAL_STATUS_SUCCESS;
14081 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053014082 }
14083 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014084 }
14085
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014086 /* Flush the scan results(only p2p beacons) for STA scan and P2P
14087 * search (Flush on both full scan and social scan but not on single
14088 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
14089 */
14090
14091 /* Supplicant does single channel scan after 8-way handshake
14092 * and in that case driver shoudnt flush scan results. If
14093 * driver flushes the scan results here and unfortunately if
14094 * the AP doesnt respond to our probe req then association
14095 * fails which is not desired
14096 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053014097 if ((request->n_ssids == 1)
14098 && (request->ssids != NULL)
14099 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
14100 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014101
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053014102 if( is_p2p_scan ||
14103 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014104 {
14105 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
14106 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
14107 pAdapter->sessionId );
14108 }
14109
14110 if( request->ie_len )
14111 {
14112 /* save this for future association (join requires this) */
14113 /*TODO: Array needs to be converted to dynamic allocation,
14114 * as multiple ie.s can be sent in cfg80211_scan_request structure
14115 * CR 597966
14116 */
14117 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
14118 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
14119 pScanInfo->scanAddIE.length = request->ie_len;
14120
14121 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
14122 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
14123 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070014124 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014125 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070014126 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014127 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
14128 memcpy( pwextBuf->roamProfile.addIEScan,
14129 request->ie, request->ie_len);
14130 }
14131 else
14132 {
14133 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
14134 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070014135 }
14136
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014137 }
14138 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
14139 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
14140
14141 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
14142 request->ie_len);
14143 if (pP2pIe != NULL)
14144 {
14145#ifdef WLAN_FEATURE_P2P_DEBUG
14146 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
14147 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
14148 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053014149 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014150 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
14151 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
14152 "Go nego completed to Connection is started");
14153 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
14154 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053014155 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014156 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
14157 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070014158 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014159 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
14160 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
14161 "Disconnected state to Connection is started");
14162 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
14163 "for 4way Handshake");
14164 }
14165#endif
14166
14167 /* no_cck will be set during p2p find to disable 11b rates */
14168 if(TRUE == request->no_cck)
14169 {
14170 hddLog(VOS_TRACE_LEVEL_INFO,
14171 "%s: This is a P2P Search", __func__);
14172 scanRequest.p2pSearch = 1;
14173
14174 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053014175 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014176 /* set requestType to P2P Discovery */
14177 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
14178 }
14179
14180 /*
14181 Skip Dfs Channel in case of P2P Search
14182 if it is set in ini file
14183 */
14184 if(cfg_param->skipDfsChnlInP2pSearch)
14185 {
14186 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053014187 }
14188 else
14189 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014190 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053014191 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014192
Agarwal Ashish4f616132013-12-30 23:32:50 +053014193 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014194 }
14195 }
14196
14197 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
14198
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014199#ifdef FEATURE_WLAN_TDLS
14200 /* if tdls disagree scan right now, return immediately.
14201 tdls will schedule the scan when scan is allowed. (return SUCCESS)
14202 or will reject the scan if any TDLS is in progress. (return -EBUSY)
14203 */
14204 status = wlan_hdd_tdls_scan_callback (pAdapter,
14205 wiphy,
14206#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
14207 dev,
14208#endif
14209 request);
Abhishek Singhe2b63952016-01-05 18:27:29 +053014210 if (status <= 0)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014211 {
Abhishek Singhe2b63952016-01-05 18:27:29 +053014212 if (!status)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014213 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
14214 "scan rejected %d", __func__, status);
14215 else
14216 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
14217 __func__, status);
Abhishek Singhe2b63952016-01-05 18:27:29 +053014218 hdd_wlan_block_scan_by_tdls();
Gupta, Kapil2ebf3e02016-03-17 19:45:19 +053014219 goto free_mem;
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014220 }
14221#endif
14222
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070014223 /* acquire the wakelock to avoid the apps suspend during the scan. To
14224 * address the following issues.
14225 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
14226 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
14227 * for long time, this result in apps running at full power for long time.
14228 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
14229 * be stuck in full power because of resume BMPS
14230 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014231 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070014232
Nirav Shah20ac06f2013-12-12 18:14:06 +053014233 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
14234 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014235 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
14236 scanRequest.requestType, scanRequest.scanType,
14237 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053014238 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
14239
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053014240 if (pHddCtx->spoofMacAddr.isEnabled &&
14241 pHddCtx->cfg_ini->enableMacSpoofing == 1)
Siddharth Bhal76972212014-10-15 16:22:51 +053014242 {
14243 hddLog(VOS_TRACE_LEVEL_INFO,
14244 "%s: MAC Spoofing enabled for current scan", __func__);
14245 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
14246 * to fill TxBds for probe request during current scan
14247 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053014248 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053014249 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053014250
14251 if(status != VOS_STATUS_SUCCESS)
14252 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014253 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053014254 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053014255#ifdef FEATURE_WLAN_TDLS
14256 wlan_hdd_tdls_scan_done_callback(pAdapter);
14257#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053014258 goto free_mem;
14259 }
Siddharth Bhal76972212014-10-15 16:22:51 +053014260 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053014261 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070014262 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070014263 pAdapter->sessionId, &scanRequest, &scanId,
14264 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070014265
Jeff Johnson295189b2012-06-20 16:38:30 -070014266 if (eHAL_STATUS_SUCCESS != status)
14267 {
14268 hddLog(VOS_TRACE_LEVEL_ERROR,
14269 "%s: sme_ScanRequest returned error %d", __func__, status);
14270 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070014271 if(eHAL_STATUS_RESOURCES == status)
14272 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014273 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
14274 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070014275 status = -EBUSY;
14276 } else {
14277 status = -EIO;
14278 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014279 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014280
14281#ifdef FEATURE_WLAN_TDLS
14282 wlan_hdd_tdls_scan_done_callback(pAdapter);
14283#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014284 goto free_mem;
14285 }
14286
14287 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053014288 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070014289 pAdapter->request = request;
14290 pScanInfo->scanId = scanId;
14291
14292 complete(&pScanInfo->scan_req_completion_event);
14293
14294free_mem:
14295 if( scanRequest.SSIDs.SSIDList )
14296 {
14297 vos_mem_free(scanRequest.SSIDs.SSIDList);
14298 }
14299
14300 if( channelList )
14301 vos_mem_free( channelList );
14302
14303 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014304 return status;
14305}
14306
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014307int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
14308#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
14309 struct net_device *dev,
14310#endif
14311 struct cfg80211_scan_request *request)
14312{
14313 int ret;
14314
14315 vos_ssr_protect(__func__);
14316 ret = __wlan_hdd_cfg80211_scan(wiphy,
14317#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
14318 dev,
14319#endif
14320 request);
14321 vos_ssr_unprotect(__func__);
14322
14323 return ret;
14324}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014325
14326void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
14327{
14328 v_U8_t iniDot11Mode =
14329 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
14330 eHddDot11Mode hddDot11Mode = iniDot11Mode;
14331
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014332 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
14333 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014334 switch ( iniDot11Mode )
14335 {
14336 case eHDD_DOT11_MODE_AUTO:
14337 case eHDD_DOT11_MODE_11ac:
14338 case eHDD_DOT11_MODE_11ac_ONLY:
14339#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053014340 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
14341 sme_IsFeatureSupportedByFW(DOT11AC) )
14342 hddDot11Mode = eHDD_DOT11_MODE_11ac;
14343 else
14344 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014345#else
14346 hddDot11Mode = eHDD_DOT11_MODE_11n;
14347#endif
14348 break;
14349 case eHDD_DOT11_MODE_11n:
14350 case eHDD_DOT11_MODE_11n_ONLY:
14351 hddDot11Mode = eHDD_DOT11_MODE_11n;
14352 break;
14353 default:
14354 hddDot11Mode = iniDot11Mode;
14355 break;
14356 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053014357#ifdef WLAN_FEATURE_AP_HT40_24G
14358 if (operationChannel > SIR_11B_CHANNEL_END)
14359#endif
14360 {
14361 /* This call decides required channel bonding mode */
14362 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014363 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
14364 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053014365 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014366}
14367
Jeff Johnson295189b2012-06-20 16:38:30 -070014368/*
14369 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014370 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070014371 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014372int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053014373 const u8 *ssid, size_t ssid_len, const u8 *bssid,
14374 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070014375{
14376 int status = 0;
14377 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080014378 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014379 v_U32_t roamId;
14380 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070014381 eCsrAuthType RSNAuthType;
14382
14383 ENTER();
14384
14385 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080014386 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14387
14388 status = wlan_hdd_validate_context(pHddCtx);
14389 if (status)
14390 {
Yue Mae36e3552014-03-05 17:06:20 -080014391 return status;
14392 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014393
Jeff Johnson295189b2012-06-20 16:38:30 -070014394 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
14395 {
14396 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
14397 return -EINVAL;
14398 }
14399
14400 pRoamProfile = &pWextState->roamProfile;
14401
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014402 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070014403 {
Jeff Johnsone7245742012-09-05 17:12:55 -070014404 hdd_station_ctx_t *pHddStaCtx;
14405 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014406
Siddharth Bhalda0d1622015-04-24 15:47:49 +053014407 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
14408
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014409 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070014410 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
14411 {
14412 /*QoS not enabled in cfg file*/
14413 pRoamProfile->uapsd_mask = 0;
14414 }
14415 else
14416 {
14417 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014418 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070014419 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
14420 }
14421
14422 pRoamProfile->SSIDs.numOfSSIDs = 1;
14423 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
14424 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014425 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070014426 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
14427 ssid, ssid_len);
14428
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014429 vos_mem_zero(pRoamProfile->BSSIDs.bssid, WNI_CFG_BSSID_LEN);
14430 vos_mem_zero(pRoamProfile->bssid_hint, WNI_CFG_BSSID_LEN);
14431
Jeff Johnson295189b2012-06-20 16:38:30 -070014432 if (bssid)
14433 {
14434 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014435 vos_mem_copy(pRoamProfile->BSSIDs.bssid, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070014436 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014437 /* Save BSSID in seperate variable as well, as RoamProfile
14438 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070014439 case of join failure we should send valid BSSID to supplicant
14440 */
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014441 vos_mem_copy(pWextState->req_bssId, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070014442 WNI_CFG_BSSID_LEN);
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014443
Jeff Johnson295189b2012-06-20 16:38:30 -070014444 }
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014445 else if (bssid_hint)
Dhanashri Atre51981c62013-06-13 11:47:57 -070014446 {
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014447 /* Store bssid_hint to use in the scan filter. */
14448 vos_mem_copy(pRoamProfile->bssid_hint, bssid_hint,
14449 WNI_CFG_BSSID_LEN);
14450 /*
14451 * Save BSSID in seperate variable as well, as RoamProfile
14452 * BSSID is getting zeroed out in the association process. And in
14453 * case of join failure we should send valid BSSID to supplicant
14454 */
14455 vos_mem_copy(pWextState->req_bssId, bssid_hint,
14456 WNI_CFG_BSSID_LEN);
14457 hddLog(LOG1, FL(" bssid_hint: "MAC_ADDRESS_STR),
14458 MAC_ADDR_ARRAY(pRoamProfile->bssid_hint));
Dhanashri Atre51981c62013-06-13 11:47:57 -070014459 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014460
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014461
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014462 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
14463 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070014464 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
14465 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014466 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014467 /*set gen ie*/
14468 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
14469 /*set auth*/
14470 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
14471 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014472#ifdef FEATURE_WLAN_WAPI
14473 if (pAdapter->wapi_info.nWapiMode)
14474 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014475 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014476 switch (pAdapter->wapi_info.wapiAuthMode)
14477 {
14478 case WAPI_AUTH_MODE_PSK:
14479 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014480 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014481 pAdapter->wapi_info.wapiAuthMode);
14482 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
14483 break;
14484 }
14485 case WAPI_AUTH_MODE_CERT:
14486 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014487 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014488 pAdapter->wapi_info.wapiAuthMode);
14489 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
14490 break;
14491 }
14492 } // End of switch
14493 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
14494 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
14495 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014496 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014497 pRoamProfile->AuthType.numEntries = 1;
14498 pRoamProfile->EncryptionType.numEntries = 1;
14499 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
14500 pRoamProfile->mcEncryptionType.numEntries = 1;
14501 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
14502 }
14503 }
14504#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014505#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014506 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014507 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
14508 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
14509 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014510 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
14511 sizeof (tSirGtkOffloadParams));
14512 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014513 }
14514#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014515 pRoamProfile->csrPersona = pAdapter->device_mode;
14516
Jeff Johnson32d95a32012-09-10 13:15:23 -070014517 if( operatingChannel )
14518 {
14519 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
14520 pRoamProfile->ChannelInfo.numOfChannels = 1;
14521 }
Chet Lanctot186b5732013-03-18 10:26:30 -070014522 else
14523 {
14524 pRoamProfile->ChannelInfo.ChannelList = NULL;
14525 pRoamProfile->ChannelInfo.numOfChannels = 0;
14526 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014527 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
14528 {
14529 hdd_select_cbmode(pAdapter,operatingChannel);
14530 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014531
Agarwal Ashish40f9b872015-09-01 16:17:35 +053014532 /*
14533 * Change conn_state to connecting before sme_RoamConnect(),
14534 * because sme_RoamConnect() has a direct path to call
14535 * hdd_smeRoamCallback(), which will change the conn_state
14536 * If direct path, conn_state will be accordingly changed
14537 * to NotConnected or Associated by either
14538 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
14539 * in sme_RoamCallback()
14540 * if sme_RomConnect is to be queued,
14541 * Connecting state will remain until it is completed.
14542 * If connection state is not changed,
14543 * connection state will remain in eConnectionState_NotConnected state.
14544 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
14545 * if conn state is eConnectionState_NotConnected.
14546 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
14547 * informed of connect result indication which is an issue.
14548 */
14549
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053014550 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
14551 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053014552 {
14553 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053014554 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080014555 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
14556 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053014557 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014558 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070014559 pAdapter->sessionId, pRoamProfile, &roamId);
14560
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053014561 if ((eHAL_STATUS_SUCCESS != status) &&
14562 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
14563 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053014564
14565 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053014566 hddLog(VOS_TRACE_LEVEL_ERROR,
14567 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
14568 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080014569 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053014570 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080014571 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053014572 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080014573
14574 pRoamProfile->ChannelInfo.ChannelList = NULL;
14575 pRoamProfile->ChannelInfo.numOfChannels = 0;
14576
Jeff Johnson295189b2012-06-20 16:38:30 -070014577 }
14578 else
14579 {
14580 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
14581 return -EINVAL;
14582 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080014583 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014584 return status;
14585}
14586
14587/*
14588 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
14589 * This function is used to set the authentication type (OPEN/SHARED).
14590 *
14591 */
14592static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
14593 enum nl80211_auth_type auth_type)
14594{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014595 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014596 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14597
14598 ENTER();
14599
14600 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014601 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070014602 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014603 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053014604 hddLog(VOS_TRACE_LEVEL_INFO,
14605 "%s: set authentication type to AUTOSWITCH", __func__);
14606 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
14607 break;
14608
14609 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014610#ifdef WLAN_FEATURE_VOWIFI_11R
14611 case NL80211_AUTHTYPE_FT:
14612#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014613 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070014614 "%s: set authentication type to OPEN", __func__);
14615 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
14616 break;
14617
14618 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014619 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070014620 "%s: set authentication type to SHARED", __func__);
14621 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
14622 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080014623#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070014624 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014625 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070014626 "%s: set authentication type to CCKM WPA", __func__);
14627 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
14628 break;
14629#endif
14630
14631
14632 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014633 hddLog(VOS_TRACE_LEVEL_ERROR,
14634 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014635 auth_type);
14636 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
14637 return -EINVAL;
14638 }
14639
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014640 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070014641 pHddStaCtx->conn_info.authType;
14642 return 0;
14643}
14644
14645/*
14646 * FUNCTION: wlan_hdd_set_akm_suite
14647 * This function is used to set the key mgmt type(PSK/8021x).
14648 *
14649 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014650static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014651 u32 key_mgmt
14652 )
14653{
14654 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
14655 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053014656 /* Should be in ieee802_11_defs.h */
14657#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
14658#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070014659 /*set key mgmt type*/
14660 switch(key_mgmt)
14661 {
14662 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053014663 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053014664#ifdef WLAN_FEATURE_VOWIFI_11R
14665 case WLAN_AKM_SUITE_FT_PSK:
14666#endif
14667 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070014668 __func__);
14669 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
14670 break;
14671
14672 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053014673 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053014674#ifdef WLAN_FEATURE_VOWIFI_11R
14675 case WLAN_AKM_SUITE_FT_8021X:
14676#endif
14677 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070014678 __func__);
14679 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
14680 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080014681#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070014682#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
14683#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
14684 case WLAN_AKM_SUITE_CCKM:
14685 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
14686 __func__);
14687 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
14688 break;
14689#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070014690#ifndef WLAN_AKM_SUITE_OSEN
14691#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
14692 case WLAN_AKM_SUITE_OSEN:
14693 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
14694 __func__);
14695 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
14696 break;
14697#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014698
14699 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014700 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014701 __func__, key_mgmt);
14702 return -EINVAL;
14703
14704 }
14705 return 0;
14706}
14707
14708/*
14709 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014710 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070014711 * (NONE/WEP40/WEP104/TKIP/CCMP).
14712 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014713static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
14714 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070014715 bool ucast
14716 )
14717{
14718 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014719 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014720 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14721
14722 ENTER();
14723
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014724 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070014725 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053014726 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070014727 __func__, cipher);
14728 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
14729 }
14730 else
14731 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014732
Jeff Johnson295189b2012-06-20 16:38:30 -070014733 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014734 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070014735 {
14736 case IW_AUTH_CIPHER_NONE:
14737 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
14738 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014739
Jeff Johnson295189b2012-06-20 16:38:30 -070014740 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053014741 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070014742 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014743
Jeff Johnson295189b2012-06-20 16:38:30 -070014744 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053014745 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070014746 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014747
Jeff Johnson295189b2012-06-20 16:38:30 -070014748 case WLAN_CIPHER_SUITE_TKIP:
14749 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
14750 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014751
Jeff Johnson295189b2012-06-20 16:38:30 -070014752 case WLAN_CIPHER_SUITE_CCMP:
14753 encryptionType = eCSR_ENCRYPT_TYPE_AES;
14754 break;
14755#ifdef FEATURE_WLAN_WAPI
14756 case WLAN_CIPHER_SUITE_SMS4:
14757 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
14758 break;
14759#endif
14760
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080014761#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070014762 case WLAN_CIPHER_SUITE_KRK:
14763 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
14764 break;
14765#endif
14766 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014767 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014768 __func__, cipher);
14769 return -EOPNOTSUPP;
14770 }
14771 }
14772
14773 if (ucast)
14774 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014775 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014776 __func__, encryptionType);
14777 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
14778 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014779 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070014780 encryptionType;
14781 }
14782 else
14783 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014784 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014785 __func__, encryptionType);
14786 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
14787 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
14788 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
14789 }
14790
14791 return 0;
14792}
14793
14794
14795/*
14796 * FUNCTION: wlan_hdd_cfg80211_set_ie
14797 * This function is used to parse WPA/RSN IE's.
14798 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014799int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014800#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14801 const u8 *ie,
14802#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014803 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014804#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014805 size_t ie_len
14806 )
14807{
14808 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014809#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14810 const u8 *genie = ie;
14811#else
Jeff Johnson295189b2012-06-20 16:38:30 -070014812 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014813#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014814 v_U16_t remLen = ie_len;
14815#ifdef FEATURE_WLAN_WAPI
14816 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
14817 u16 *tmp;
14818 v_U16_t akmsuiteCount;
14819 int *akmlist;
14820#endif
14821 ENTER();
14822
14823 /* clear previous assocAddIE */
14824 pWextState->assocAddIE.length = 0;
14825 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070014826 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014827
14828 while (remLen >= 2)
14829 {
14830 v_U16_t eLen = 0;
14831 v_U8_t elementId;
14832 elementId = *genie++;
14833 eLen = *genie++;
14834 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014835
Arif Hussain6d2a3322013-11-17 19:50:10 -080014836 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070014837 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014838
14839 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070014840 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014841 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014842 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 -070014843 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014844 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014845 "%s: Invalid WPA IE", __func__);
14846 return -EINVAL;
14847 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014848 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070014849 {
14850 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014851 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070014852 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014853
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014854 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070014855 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014856 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
14857 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070014858 VOS_ASSERT(0);
14859 return -ENOMEM;
14860 }
14861 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
14862 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14863 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014864
Jeff Johnson295189b2012-06-20 16:38:30 -070014865 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
14866 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14867 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14868 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014869 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
14870 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014871 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
14872 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
14873 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
14874 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
14875 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
14876 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014877 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053014878 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070014879 {
14880 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014881 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070014882 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014883
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014884 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070014885 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014886 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14887 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070014888 VOS_ASSERT(0);
14889 return -ENOMEM;
14890 }
14891 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
14892 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14893 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014894
Jeff Johnson295189b2012-06-20 16:38:30 -070014895 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14896 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14897 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014898#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014899 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
14900 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070014901 /*Consider WFD IE, only for P2P Client */
14902 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
14903 {
14904 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014905 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070014906 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014907
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014908 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070014909 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014910 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14911 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070014912 VOS_ASSERT(0);
14913 return -ENOMEM;
14914 }
14915 // WFD IE is saved to Additional IE ; it should be accumulated to handle
14916 // WPS IE + P2P IE + WFD IE
14917 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14918 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014919
Jeff Johnson295189b2012-06-20 16:38:30 -070014920 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14921 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14922 }
14923#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014924 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014925 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014926 HS20_OUI_TYPE_SIZE)) )
14927 {
14928 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014929 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014930 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014931
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014932 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014933 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014934 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14935 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014936 VOS_ASSERT(0);
14937 return -ENOMEM;
14938 }
14939 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14940 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014941
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014942 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14943 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14944 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070014945 /* Appending OSEN Information Element in Assiciation Request */
14946 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
14947 OSEN_OUI_TYPE_SIZE)) )
14948 {
14949 v_U16_t curAddIELen = pWextState->assocAddIE.length;
14950 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
14951 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014952
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014953 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070014954 {
14955 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14956 "Need bigger buffer space");
14957 VOS_ASSERT(0);
14958 return -ENOMEM;
14959 }
14960 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14961 pWextState->assocAddIE.length += eLen + 2;
14962
14963 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
14964 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14965 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14966 }
14967
Abhishek Singh4322e622015-06-10 15:42:54 +053014968 /* Update only for WPA IE */
14969 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
14970 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070014971
14972 /* populating as ADDIE in beacon frames */
14973 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014974 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070014975 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
14976 {
14977 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
14978 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
14979 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
14980 {
14981 hddLog(LOGE,
14982 "Coldn't pass "
14983 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
14984 }
14985 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
14986 else
14987 hddLog(LOGE,
14988 "Could not pass on "
14989 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
14990
14991 /* IBSS mode doesn't contain params->proberesp_ies still
14992 beaconIE's need to be populated in probe response frames */
14993 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
14994 {
14995 u16 rem_probe_resp_ie_len = eLen + 2;
14996 u8 probe_rsp_ie_len[3] = {0};
14997 u8 counter = 0;
14998
14999 /* Check Probe Resp Length if it is greater then 255 then
15000 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
15001 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
15002 not able Store More then 255 bytes into One Variable */
15003
15004 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
15005 {
15006 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
15007 {
15008 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
15009 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
15010 }
15011 else
15012 {
15013 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
15014 rem_probe_resp_ie_len = 0;
15015 }
15016 }
15017
15018 rem_probe_resp_ie_len = 0;
15019
15020 if (probe_rsp_ie_len[0] > 0)
15021 {
15022 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
15023 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
15024 (tANI_U8*)(genie - 2),
15025 probe_rsp_ie_len[0], NULL,
15026 eANI_BOOLEAN_FALSE)
15027 == eHAL_STATUS_FAILURE)
15028 {
15029 hddLog(LOGE,
15030 "Could not pass"
15031 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
15032 }
15033 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
15034 }
15035
15036 if (probe_rsp_ie_len[1] > 0)
15037 {
15038 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
15039 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
15040 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
15041 probe_rsp_ie_len[1], NULL,
15042 eANI_BOOLEAN_FALSE)
15043 == eHAL_STATUS_FAILURE)
15044 {
15045 hddLog(LOGE,
15046 "Could not pass"
15047 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
15048 }
15049 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
15050 }
15051
15052 if (probe_rsp_ie_len[2] > 0)
15053 {
15054 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
15055 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
15056 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
15057 probe_rsp_ie_len[2], NULL,
15058 eANI_BOOLEAN_FALSE)
15059 == eHAL_STATUS_FAILURE)
15060 {
15061 hddLog(LOGE,
15062 "Could not pass"
15063 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
15064 }
15065 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
15066 }
15067
15068 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
15069 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
15070 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
15071 {
15072 hddLog(LOGE,
15073 "Could not pass"
15074 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
15075 }
15076 }
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070015077 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070015078 break;
15079 case DOT11F_EID_RSN:
15080 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
15081 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
15082 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
15083 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
15084 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
15085 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053015086
Abhishek Singhb16f3562016-01-20 11:08:32 +053015087 /* Appending extended capabilities with Interworking or
15088 * bsstransition bit set in Assoc Req.
Abhishek Singh15d95602015-03-24 15:52:57 +053015089 *
15090 * In assoc req this EXT Cap will only be taken into account if
Abhishek Singhb16f3562016-01-20 11:08:32 +053015091 * interworkingService or bsstransition bit is set to 1.
15092 * Driver is only interested in interworkingService and
15093 * bsstransition capability from supplicant.
15094 * If in future any other EXT Cap info is
Abhishek Singh15d95602015-03-24 15:52:57 +053015095 * required from supplicat, it needs to be handled while
15096 * sending Assoc Req in LIM.
15097 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015098 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015099 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015100 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015101 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015102 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015103
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015104 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015105 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015106 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15107 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015108 VOS_ASSERT(0);
15109 return -ENOMEM;
15110 }
15111 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15112 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015113
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015114 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15115 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15116 break;
15117 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015118#ifdef FEATURE_WLAN_WAPI
15119 case WLAN_EID_WAPI:
15120 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070015121 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070015122 pAdapter->wapi_info.nWapiMode);
15123 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015124 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070015125 akmsuiteCount = WPA_GET_LE16(tmp);
15126 tmp = tmp + 1;
15127 akmlist = (int *)(tmp);
15128 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
15129 {
15130 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
15131 }
15132 else
15133 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015134 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070015135 VOS_ASSERT(0);
15136 return -EINVAL;
15137 }
15138
15139 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
15140 {
15141 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015142 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015143 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015144 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015145 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015146 {
Jeff Johnson295189b2012-06-20 16:38:30 -070015147 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015148 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015149 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
15150 }
15151 break;
15152#endif
15153 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015154 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015155 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015156 /* when Unknown IE is received we should break and continue
15157 * to the next IE in the buffer instead we were returning
15158 * so changing this to break */
15159 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070015160 }
15161 genie += eLen;
15162 remLen -= eLen;
15163 }
15164 EXIT();
15165 return 0;
15166}
15167
15168/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053015169 * FUNCTION: hdd_isWPAIEPresent
15170 * Parse the received IE to find the WPA IE
15171 *
15172 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015173static bool hdd_isWPAIEPresent(
15174#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
15175 const u8 *ie,
15176#else
15177 u8 *ie,
15178#endif
15179 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053015180{
15181 v_U8_t eLen = 0;
15182 v_U16_t remLen = ie_len;
15183 v_U8_t elementId = 0;
15184
15185 while (remLen >= 2)
15186 {
15187 elementId = *ie++;
15188 eLen = *ie++;
15189 remLen -= 2;
15190 if (eLen > remLen)
15191 {
15192 hddLog(VOS_TRACE_LEVEL_ERROR,
15193 "%s: IE length is wrong %d", __func__, eLen);
15194 return FALSE;
15195 }
15196 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
15197 {
15198 /* OUI - 0x00 0X50 0XF2
15199 WPA Information Element - 0x01
15200 WPA version - 0x01*/
15201 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
15202 return TRUE;
15203 }
15204 ie += eLen;
15205 remLen -= eLen;
15206 }
15207 return FALSE;
15208}
15209
15210/*
Jeff Johnson295189b2012-06-20 16:38:30 -070015211 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015212 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070015213 * parameters during connect operation.
15214 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015215int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070015216 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015217 )
Jeff Johnson295189b2012-06-20 16:38:30 -070015218{
15219 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015220 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070015221 ENTER();
15222
15223 /*set wpa version*/
15224 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
15225
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015226 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070015227 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053015228 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070015229 {
15230 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
15231 }
15232 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
15233 {
15234 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
15235 }
15236 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015237
15238 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015239 pWextState->wpaVersion);
15240
15241 /*set authentication type*/
15242 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
15243
15244 if (0 > status)
15245 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015246 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015247 "%s: failed to set authentication type ", __func__);
15248 return status;
15249 }
15250
15251 /*set key mgmt type*/
15252 if (req->crypto.n_akm_suites)
15253 {
15254 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
15255 if (0 > status)
15256 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015257 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070015258 __func__);
15259 return status;
15260 }
15261 }
15262
15263 /*set pairwise cipher type*/
15264 if (req->crypto.n_ciphers_pairwise)
15265 {
15266 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
15267 req->crypto.ciphers_pairwise[0], true);
15268 if (0 > status)
15269 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015270 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015271 "%s: failed to set unicast cipher type", __func__);
15272 return status;
15273 }
15274 }
15275 else
15276 {
15277 /*Reset previous cipher suite to none*/
15278 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
15279 if (0 > status)
15280 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015281 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015282 "%s: failed to set unicast cipher type", __func__);
15283 return status;
15284 }
15285 }
15286
15287 /*set group cipher type*/
15288 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
15289 false);
15290
15291 if (0 > status)
15292 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015293 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070015294 __func__);
15295 return status;
15296 }
15297
Chet Lanctot186b5732013-03-18 10:26:30 -070015298#ifdef WLAN_FEATURE_11W
15299 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
15300#endif
15301
Jeff Johnson295189b2012-06-20 16:38:30 -070015302 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
15303 if (req->ie_len)
15304 {
15305 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
15306 if ( 0 > status)
15307 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015308 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070015309 __func__);
15310 return status;
15311 }
15312 }
15313
15314 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015315 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070015316 {
15317 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
15318 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
15319 )
15320 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015321 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070015322 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
15323 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015324 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070015325 __func__);
15326 return -EOPNOTSUPP;
15327 }
15328 else
15329 {
15330 u8 key_len = req->key_len;
15331 u8 key_idx = req->key_idx;
15332
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015333 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070015334 && (CSR_MAX_NUM_KEY > key_idx)
15335 )
15336 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015337 hddLog(VOS_TRACE_LEVEL_INFO,
15338 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015339 __func__, key_idx, key_len);
15340 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015341 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070015342 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015343 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070015344 (u8)key_len;
15345 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
15346 }
15347 }
15348 }
15349 }
15350
15351 return status;
15352}
15353
15354/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015355 * FUNCTION: wlan_hdd_try_disconnect
15356 * This function is used to disconnect from previous
15357 * connection
15358 */
Agrawal Ashishc407f192017-01-23 17:18:35 +053015359int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015360{
15361 long ret = 0;
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015362 int status, result = 0;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015363 hdd_station_ctx_t *pHddStaCtx;
15364 eMib_dot11DesiredBssType connectedBssType;
Abhishek Singh19a7dd92015-12-30 16:31:51 +053015365 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015366
Abhishek Singh19a7dd92015-12-30 16:31:51 +053015367 ret = wlan_hdd_validate_context(pHddCtx);
15368 if (0 != ret)
15369 {
15370 return ret;
15371 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015372 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15373
15374 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
15375
15376 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
15377 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
Abhishek Singh630ff592016-01-07 18:15:53 +053015378 (eConnectionState_Connecting == pHddStaCtx->conn_info.connState) ||
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015379 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
15380 {
Abhishek Singh19a7dd92015-12-30 16:31:51 +053015381 spin_lock_bh(&pAdapter->lock_for_active_session);
15382 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
15383 {
15384 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
15385 }
15386 spin_unlock_bh(&pAdapter->lock_for_active_session);
Abhishek Singhf7962582015-10-23 10:54:06 +053015387 hdd_connSetConnectionState(pHddStaCtx,
15388 eConnectionState_Disconnecting);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015389 /* Issue disconnect to CSR */
15390 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015391 status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015392 pAdapter->sessionId,
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015393 eCSR_DISCONNECT_REASON_UNSPECIFIED);
15394 if(eHAL_STATUS_CMD_NOT_QUEUED == status) {
15395 hddLog(LOG1,
15396 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
15397 } else if ( 0 != status ) {
15398 hddLog(LOGE,
15399 FL("csrRoamDisconnect failure, returned %d"),
15400 (int)status );
15401 result = -EINVAL;
15402 goto disconnected;
15403 }
15404 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015405 &pAdapter->disconnect_comp_var,
15406 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015407 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status)) {
15408 hddLog(LOGE,
15409 "%s: Failed to disconnect, timed out", __func__);
15410 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015411 }
15412 }
15413 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
15414 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015415 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015416 &pAdapter->disconnect_comp_var,
15417 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015418 if (!ret)
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015419 {
15420 hddLog(LOGE, FL("Failed to receive disconnect event"));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015421 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015422 }
15423 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015424disconnected:
15425 hddLog(LOG1,
15426 FL("Set HDD connState to eConnectionState_NotConnected"));
15427 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
15428 return result;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015429}
15430
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053015431/**
15432 * wlan_hdd_reassoc_bssid_hint() - Start reassociation if bssid is present
15433 * @adapter: Pointer to the HDD adapter
15434 * @req: Pointer to the structure cfg_connect_params receieved from user space
15435 *
15436 * This function will start reassociation if bssid hint, channel hint and
15437 * previous bssid parameters are present in the connect request
15438 *
15439 * Return: success if reassociation is happening
15440 * Error code if reassociation is not permitted or not happening
15441 */
15442#ifdef CFG80211_CONNECT_PREV_BSSID
15443static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
15444 struct cfg80211_connect_params *req)
15445{
15446 int status = -EPERM;
15447 if (req->bssid_hint && req->channel_hint && req->prev_bssid) {
15448 hddLog(VOS_TRACE_LEVEL_INFO,
15449 FL("REASSOC Attempt on channel %d to "MAC_ADDRESS_STR),
15450 req->channel_hint->hw_value,
15451 MAC_ADDR_ARRAY(req->bssid_hint));
15452 status = hdd_reassoc(adapter, req->bssid_hint,
15453 req->channel_hint->hw_value,
15454 CONNECT_CMD_USERSPACE);
15455 }
15456 return status;
15457}
15458#else
15459static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
15460 struct cfg80211_connect_params *req)
15461{
15462 return -EPERM;
15463}
15464#endif
15465
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015466/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053015467 * FUNCTION: __wlan_hdd_cfg80211_connect
15468 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070015469 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015470static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015471 struct net_device *ndev,
15472 struct cfg80211_connect_params *req
15473 )
15474{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015475 int status;
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053015476 u16 channel;
Edhar, Mahesh Kumar496c7f72016-03-18 12:47:44 +053015477#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) || \
15478 defined(CFG80211_BSSID_HINT_BACKPORT)
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053015479 const u8 *bssid_hint = req->bssid_hint;
15480#else
15481 const u8 *bssid_hint = NULL;
15482#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015483 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070015484 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053015485 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015486
15487 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015488
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015489 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15490 TRACE_CODE_HDD_CFG80211_CONNECT,
15491 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015492 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015493 "%s: device_mode = %s (%d)", __func__,
15494 hdd_device_modetoString(pAdapter->device_mode),
15495 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015496
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015497 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080015498 if (!pHddCtx)
15499 {
15500 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15501 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053015502 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080015503 }
15504
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015505 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015506 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070015507 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015508 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015509 }
15510
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053015511 status = wlan_hdd_reassoc_bssid_hint(pAdapter, req);
15512 if (0 == status)
15513 return status;
15514
Agarwal Ashish51325b52014-06-16 16:50:49 +053015515
Jeff Johnson295189b2012-06-20 16:38:30 -070015516#ifdef WLAN_BTAMP_FEATURE
15517 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015518 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070015519 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015520 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015521 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080015522 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070015523 }
15524#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015525
15526 //If Device Mode is Station Concurrent Sessions Exit BMps
15527 //P2P Mode will be taken care in Open/close adapter
15528 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053015529 (vos_concurrent_open_sessions_running())) {
15530 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
15531 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015532 }
15533
15534 /*Try disconnecting if already in connected state*/
15535 status = wlan_hdd_try_disconnect(pAdapter);
15536 if ( 0 > status)
15537 {
15538 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
15539 " connection"));
15540 return -EALREADY;
15541 }
Agrawal Ashish559530c2015-12-01 18:04:20 +053015542 /* Check for max concurrent connections after doing disconnect if any*/
15543 if (vos_max_concurrent_connections_reached()) {
15544 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
15545 return -ECONNREFUSED;
15546 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015547
Jeff Johnson295189b2012-06-20 16:38:30 -070015548 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015549 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070015550
15551 if ( 0 > status)
15552 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015553 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070015554 __func__);
15555 return status;
15556 }
Sravan Kumar Kairam589c5722016-01-27 20:28:53 +053015557
15558 if (pHddCtx->spoofMacAddr.isEnabled)
15559 {
15560 hddLog(VOS_TRACE_LEVEL_INFO,
15561 "%s: MAC Spoofing enabled ", __func__);
15562 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
15563 * to fill TxBds for probe request during SSID scan which may happen
15564 * as part of connect command
15565 */
15566 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
15567 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
15568 if (status != VOS_STATUS_SUCCESS)
15569 return -ECONNREFUSED;
15570 }
15571
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053015572 if (req->channel)
15573 channel = req->channel->hw_value;
Mohit Khanna765234a2012-09-11 15:08:35 -070015574 else
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053015575 channel = 0;
Kapil Gupta312028a2016-10-25 14:15:20 +053015576
15577 /* Abort if any scan is going on */
15578 status = wlan_hdd_scan_abort(pAdapter);
15579 if (0 != status)
15580 hddLog(VOS_TRACE_LEVEL_ERROR, FL("scan abort failed"));
15581
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053015582 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
15583 req->ssid_len, req->bssid,
15584 bssid_hint, channel);
Jeff Johnson295189b2012-06-20 16:38:30 -070015585
Sushant Kaushikd7083982015-03-18 14:33:24 +053015586 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070015587 {
15588 //ReEnable BMPS if disabled
15589 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
15590 (NULL != pHddCtx))
15591 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053015592 if (pHddCtx->hdd_wlan_suspended)
15593 {
15594 hdd_set_pwrparams(pHddCtx);
15595 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015596 //ReEnable Bmps and Imps back
15597 hdd_enable_bmps_imps(pHddCtx);
15598 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053015599 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070015600 return status;
15601 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015602 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015603 EXIT();
15604 return status;
15605}
15606
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015607static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
15608 struct net_device *ndev,
15609 struct cfg80211_connect_params *req)
15610{
15611 int ret;
15612 vos_ssr_protect(__func__);
15613 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
15614 vos_ssr_unprotect(__func__);
15615
15616 return ret;
15617}
Jeff Johnson295189b2012-06-20 16:38:30 -070015618
15619/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015620 * FUNCTION: wlan_hdd_disconnect
15621 * This function is used to issue a disconnect request to SME
15622 */
15623int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
15624{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015625 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015626 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015627 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053015628 long ret;
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053015629 eConnectionState prev_conn_state;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015630
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015631 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015632
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015633 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015634 if (0 != status)
15635 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015636 return status;
15637 }
Abhishek Singh07e4a892015-11-23 11:29:57 +053015638 /* Indicate sme of disconnect so that in progress connection or preauth
15639 * can be aborted
15640 */
15641 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
Sushant Kaushikb4834d22015-07-15 15:29:05 +053015642 pAdapter->sessionId);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015643 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053015644
Agarwal Ashish47d18112014-08-04 19:55:07 +053015645 /* Need to apply spin lock before decreasing active sessions
15646 * as there can be chance for double decrement if context switch
15647 * Calls hdd_DisConnectHandler.
15648 */
15649
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053015650 prev_conn_state = pHddStaCtx->conn_info.connState;
15651
Agarwal Ashish47d18112014-08-04 19:55:07 +053015652 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053015653 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
15654 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053015655 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
15656 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053015657 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
15658 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053015659
Abhishek Singhf4669da2014-05-26 15:07:49 +053015660 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053015661 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
15662
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015663 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015664
Mihir Shete182a0b22014-08-18 16:08:48 +053015665 /*
15666 * stop tx queues before deleting STA/BSS context from the firmware.
15667 * tx has to be disabled because the firmware can get busy dropping
15668 * the tx frames after BSS/STA has been deleted and will not send
15669 * back a response resulting in WDI timeout
15670 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053015671 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053015672 netif_tx_disable(pAdapter->dev);
15673 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015674
Mihir Shete182a0b22014-08-18 16:08:48 +053015675 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015676 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
15677 pAdapter->sessionId, reason);
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053015678 if((eHAL_STATUS_CMD_NOT_QUEUED == status) &&
15679 prev_conn_state != eConnectionState_Connecting)
15680 {
15681 hddLog(LOG1,
15682 FL("status = %d, already disconnected"), status);
15683 result = 0;
15684 goto disconnected;
15685 }
15686 /*
15687 * Wait here instead of returning directly, this will block the next
15688 * connect command and allow processing of the scan for ssid and
15689 * the previous connect command in CSR. Else we might hit some
15690 * race conditions leading to SME and HDD out of sync.
15691 */
15692 else if(eHAL_STATUS_CMD_NOT_QUEUED == status)
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015693 {
15694 hddLog(LOG1,
15695 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053015696 }
15697 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015698 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015699 hddLog(LOGE,
15700 FL("csrRoamDisconnect failure, returned %d"),
15701 (int)status);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015702 result = -EINVAL;
15703 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015704 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015705 ret = wait_for_completion_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015706 &pAdapter->disconnect_comp_var,
15707 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015708 if (!ret && (eHAL_STATUS_CMD_NOT_QUEUED != status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015709 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015710 hddLog(LOGE,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053015711 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015712 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053015713 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015714disconnected:
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015715 hddLog(LOG1,
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053015716 FL("Set HDD connState to eConnectionState_NotConnected"));
15717 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Mahesh A Saptasagar936ffc32016-05-25 11:27:43 +053015718#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
15719 /* Sending disconnect event to userspace for kernel version < 3.11
15720 * is handled by __cfg80211_disconnect call to __cfg80211_disconnected
15721 */
15722 hddLog(LOG1, FL("Send disconnected event to userspace"));
15723
Mahesh A Saptasagarf5859b12016-06-01 17:17:50 +053015724 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, true,
Mahesh A Saptasagar936ffc32016-05-25 11:27:43 +053015725 WLAN_REASON_UNSPECIFIED);
15726#endif
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053015727
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015728 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015729 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015730}
15731
15732
15733/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015734 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070015735 * This function is used to issue a disconnect request to SME
15736 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015737static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015738 struct net_device *dev,
15739 u16 reason
15740 )
15741{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015742 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015743 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053015744 tCsrRoamProfile *pRoamProfile;
15745 hdd_station_ctx_t *pHddStaCtx;
15746 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015747#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015748 tANI_U8 staIdx;
15749#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015750
Jeff Johnson295189b2012-06-20 16:38:30 -070015751 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015752
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053015753 if (!pAdapter) {
15754 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
15755 return -EINVAL;
15756 }
15757
15758 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15759 if (!pHddStaCtx) {
15760 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
15761 return -EINVAL;
15762 }
15763
15764 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15765 status = wlan_hdd_validate_context(pHddCtx);
15766 if (0 != status)
15767 {
15768 return status;
15769 }
15770
15771 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
15772
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015773 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15774 TRACE_CODE_HDD_CFG80211_DISCONNECT,
15775 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015776 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
15777 __func__, hdd_device_modetoString(pAdapter->device_mode),
15778 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015779
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015780 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
15781 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070015782
Jeff Johnson295189b2012-06-20 16:38:30 -070015783 if (NULL != pRoamProfile)
15784 {
15785 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053015786 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
15787 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070015788 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015789 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070015790 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015791 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070015792 switch(reason)
15793 {
15794 case WLAN_REASON_MIC_FAILURE:
15795 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
15796 break;
15797
15798 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
15799 case WLAN_REASON_DISASSOC_AP_BUSY:
15800 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
15801 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
15802 break;
15803
15804 case WLAN_REASON_PREV_AUTH_NOT_VALID:
15805 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053015806 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070015807 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
15808 break;
15809
Jeff Johnson295189b2012-06-20 16:38:30 -070015810 default:
15811 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
15812 break;
15813 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015814 pScanInfo = &pHddCtx->scan_info;
15815 if (pScanInfo->mScanPending)
15816 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053015817 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015818 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053015819 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053015820 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015821 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053015822 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015823#ifdef FEATURE_WLAN_TDLS
15824 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080015825 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015826 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080015827 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
15828 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015829 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015830 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080015831 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015832 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015833 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080015834 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015835 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015836 status = sme_DeleteTdlsPeerSta(
15837 WLAN_HDD_GET_HAL_CTX(pAdapter),
15838 pAdapter->sessionId,
15839 mac);
15840 if (status != eHAL_STATUS_SUCCESS) {
15841 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
15842 return -EPERM;
15843 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015844 }
15845 }
15846#endif
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053015847
15848 hddLog(LOG1, FL("Disconnecting with reasoncode:%u connState %d"),
15849 reasonCode,
15850 pHddStaCtx->conn_info.connState);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015851 status = wlan_hdd_disconnect(pAdapter, reasonCode);
15852 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070015853 {
15854 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080015855 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015856 __func__, (int)status );
15857 return -EINVAL;
15858 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015859 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053015860 else
15861 {
15862 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
15863 "called while in %d state", __func__,
15864 pHddStaCtx->conn_info.connState);
15865 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015866 }
15867 else
15868 {
15869 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
15870 }
15871
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015872 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015873 return status;
15874}
15875
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015876static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
15877 struct net_device *dev,
15878 u16 reason
15879 )
15880{
15881 int ret;
15882 vos_ssr_protect(__func__);
15883 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
15884 vos_ssr_unprotect(__func__);
15885
15886 return ret;
15887}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015888
Jeff Johnson295189b2012-06-20 16:38:30 -070015889/*
15890 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015891 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070015892 * settings in IBSS mode.
15893 */
15894static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015895 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070015896 struct cfg80211_ibss_params *params
15897 )
15898{
15899 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015900 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070015901 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
15902 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015903
Jeff Johnson295189b2012-06-20 16:38:30 -070015904 ENTER();
15905
15906 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070015907 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070015908
15909 if (params->ie_len && ( NULL != params->ie) )
15910 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015911 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
15912 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070015913 {
15914 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
15915 encryptionType = eCSR_ENCRYPT_TYPE_AES;
15916 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015917 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070015918 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070015919 tDot11fIEWPA dot11WPAIE;
15920 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015921 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070015922
Wilson Yang00256342013-10-10 23:13:38 -070015923 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015924 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
15925 params->ie_len, DOT11F_EID_WPA);
15926 if ( NULL != ie )
15927 {
15928 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
15929 // Unpack the WPA IE
15930 //Skip past the EID byte and length byte - and four byte WiFi OUI
15931 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
15932 &ie[2+4],
15933 ie[1] - 4,
15934 &dot11WPAIE);
15935 /*Extract the multicast cipher, the encType for unicast
15936 cipher for wpa-none is none*/
15937 encryptionType =
15938 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
15939 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015940 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015941
Jeff Johnson295189b2012-06-20 16:38:30 -070015942 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
15943
15944 if (0 > status)
15945 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015946 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070015947 __func__);
15948 return status;
15949 }
15950 }
15951
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015952 pWextState->roamProfile.AuthType.authType[0] =
15953 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070015954 eCSR_AUTH_TYPE_OPEN_SYSTEM;
15955
15956 if (params->privacy)
15957 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015958 /* Security enabled IBSS, At this time there is no information available
15959 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070015960 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015961 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070015962 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015963 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070015964 *enable privacy bit in beacons */
15965
15966 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
15967 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070015968 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
15969 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070015970 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
15971 pWextState->roamProfile.EncryptionType.numEntries = 1;
15972 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070015973 return status;
15974}
15975
15976/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015977 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015978 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070015979 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015980static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015981 struct net_device *dev,
15982 struct cfg80211_ibss_params *params
15983 )
15984{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015985 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070015986 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15987 tCsrRoamProfile *pRoamProfile;
15988 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015989 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15990 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015991 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070015992
15993 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015994
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015995 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15996 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
15997 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015998 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015999 "%s: device_mode = %s (%d)", __func__,
16000 hdd_device_modetoString(pAdapter->device_mode),
16001 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070016002
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016003 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016004 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070016005 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016006 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016007 }
16008
16009 if (NULL == pWextState)
16010 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016011 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070016012 __func__);
16013 return -EIO;
16014 }
16015
Agarwal Ashish51325b52014-06-16 16:50:49 +053016016 if (vos_max_concurrent_connections_reached()) {
16017 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
16018 return -ECONNREFUSED;
16019 }
16020
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016021 /*Try disconnecting if already in connected state*/
16022 status = wlan_hdd_try_disconnect(pAdapter);
16023 if ( 0 > status)
16024 {
16025 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
16026 " IBSS connection"));
16027 return -EALREADY;
16028 }
16029
Jeff Johnson295189b2012-06-20 16:38:30 -070016030 pRoamProfile = &pWextState->roamProfile;
16031
16032 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
16033 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016034 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080016035 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016036 return -EINVAL;
16037 }
16038
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070016039 /* BSSID is provided by upper layers hence no need to AUTO generate */
16040 if (NULL != params->bssid) {
16041 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
16042 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
16043 hddLog (VOS_TRACE_LEVEL_ERROR,
16044 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
16045 return -EIO;
16046 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016047 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070016048 }
krunal sonie9002db2013-11-25 14:24:17 -080016049 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
16050 {
16051 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
16052 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
16053 {
16054 hddLog (VOS_TRACE_LEVEL_ERROR,
16055 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
16056 return -EIO;
16057 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016058
16059 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080016060 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016061 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080016062 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070016063
Jeff Johnson295189b2012-06-20 16:38:30 -070016064 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070016065 if (NULL !=
16066#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
16067 params->chandef.chan)
16068#else
16069 params->channel)
16070#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016071 {
16072 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016073 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
16074 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
16075 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
16076 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070016077
16078 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016079 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070016080 ieee80211_frequency_to_channel(
16081#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
16082 params->chandef.chan->center_freq);
16083#else
16084 params->channel->center_freq);
16085#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016086
16087 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
16088 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070016089 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016090 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
16091 __func__);
16092 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070016093 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016094
16095 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070016096 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016097 if (channelNum == validChan[indx])
16098 {
16099 break;
16100 }
16101 }
16102 if (indx >= numChans)
16103 {
16104 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016105 __func__, channelNum);
16106 return -EINVAL;
16107 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016108 /* Set the Operational Channel */
16109 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
16110 channelNum);
16111 pRoamProfile->ChannelInfo.numOfChannels = 1;
16112 pHddStaCtx->conn_info.operationChannel = channelNum;
16113 pRoamProfile->ChannelInfo.ChannelList =
16114 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070016115 }
16116
16117 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016118 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070016119 if (status < 0)
16120 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016121 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070016122 __func__);
16123 return status;
16124 }
16125
16126 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016127 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Abhishek Singh4d924682015-11-17 15:23:06 +053016128 params->ssid_len, (const u8 *)&bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016129 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070016130
16131 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070016132 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016133
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016134 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016135 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016136}
16137
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016138static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
16139 struct net_device *dev,
16140 struct cfg80211_ibss_params *params
16141 )
16142{
16143 int ret = 0;
16144
16145 vos_ssr_protect(__func__);
16146 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
16147 vos_ssr_unprotect(__func__);
16148
16149 return ret;
16150}
16151
Jeff Johnson295189b2012-06-20 16:38:30 -070016152/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016153 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016154 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070016155 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016156static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016157 struct net_device *dev
16158 )
16159{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016160 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016161 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
16162 tCsrRoamProfile *pRoamProfile;
16163 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016164 int status;
Abhishek Singh69de3302016-11-11 16:44:32 +053016165 eHalStatus hal_status;
Abhishek Singh7cd040e2016-01-07 10:51:04 +053016166#ifdef WLAN_FEATURE_RMC
16167 tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN] = {0};
16168#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016169
16170 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016171
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016172 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16173 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
16174 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016175 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016176 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016177 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016178 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016179 }
16180
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016181 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
16182 hdd_device_modetoString(pAdapter->device_mode),
16183 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070016184 if (NULL == pWextState)
16185 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016186 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070016187 __func__);
16188 return -EIO;
16189 }
16190
16191 pRoamProfile = &pWextState->roamProfile;
16192
16193 /* Issue disconnect only if interface type is set to IBSS */
16194 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
16195 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016196 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070016197 __func__);
16198 return -EINVAL;
16199 }
16200
Abhishek Singh7cd040e2016-01-07 10:51:04 +053016201#ifdef WLAN_FEATURE_RMC
16202 /* Clearing add IE of beacon */
16203 if (ccmCfgSetStr(pHddCtx->hHal,
16204 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0],
16205 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN,
16206 NULL, eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
16207 {
16208 hddLog (VOS_TRACE_LEVEL_ERROR,
16209 "%s: unable to clear PROBE_RSP_BCN_ADDNIE_DATA", __func__);
16210 return -EINVAL;
16211 }
16212 if (ccmCfgSetInt(pHddCtx->hHal,
16213 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0, NULL,
16214 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
16215 {
16216 hddLog (VOS_TRACE_LEVEL_ERROR,
16217 "%s: unable to clear WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
16218 __func__);
16219 return -EINVAL;
16220 }
16221
16222 // Reset WNI_CFG_PROBE_RSP Flags
16223 wlan_hdd_reset_prob_rspies(pAdapter);
16224
16225 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
16226 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 0,NULL,
16227 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
16228 {
16229 hddLog (VOS_TRACE_LEVEL_ERROR,
16230 "%s: unable to clear WNI_CFG_PROBE_RSP_ADDNIE_FLAG",
16231 __func__);
16232 return -EINVAL;
16233 }
16234#endif
16235
Jeff Johnson295189b2012-06-20 16:38:30 -070016236 /* Issue Disconnect request */
16237 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singh69de3302016-11-11 16:44:32 +053016238 hal_status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
16239 pAdapter->sessionId,
16240 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
16241 if (!HAL_STATUS_SUCCESS(hal_status)) {
16242 hddLog(LOGE,
16243 FL("sme_RoamDisconnect failed hal_status(%d)"),
16244 hal_status);
16245 return -EAGAIN;
16246 }
16247 status = wait_for_completion_timeout(
16248 &pAdapter->disconnect_comp_var,
16249 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
16250 if (!status) {
16251 hddLog(LOGE,
16252 FL("wait on disconnect_comp_var failed"));
16253 return -ETIMEDOUT;
16254 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016255
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016256 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016257 return 0;
16258}
16259
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016260static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
16261 struct net_device *dev
16262 )
16263{
16264 int ret = 0;
16265
16266 vos_ssr_protect(__func__);
16267 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
16268 vos_ssr_unprotect(__func__);
16269
16270 return ret;
16271}
16272
Jeff Johnson295189b2012-06-20 16:38:30 -070016273/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016274 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070016275 * This function is used to set the phy parameters
16276 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
16277 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016278static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016279 u32 changed)
16280{
16281 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
16282 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016283 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016284
16285 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016286
16287 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016288 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
16289 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016290
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +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
Jeff Johnson295189b2012-06-20 16:38:30 -070016297 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
16298 {
16299 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
16300 WNI_CFG_RTS_THRESHOLD_STAMAX :
16301 wiphy->rts_threshold;
16302
16303 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016304 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070016305 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016306 hddLog(VOS_TRACE_LEVEL_ERROR,
16307 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016308 __func__, rts_threshold);
16309 return -EINVAL;
16310 }
16311
16312 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
16313 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016314 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016315 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016316 hddLog(VOS_TRACE_LEVEL_ERROR,
16317 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016318 __func__, rts_threshold);
16319 return -EIO;
16320 }
16321
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016322 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016323 rts_threshold);
16324 }
16325
16326 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
16327 {
16328 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
16329 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
16330 wiphy->frag_threshold;
16331
16332 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016333 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016334 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016335 hddLog(VOS_TRACE_LEVEL_ERROR,
16336 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016337 frag_threshold);
16338 return -EINVAL;
16339 }
16340
16341 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
16342 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016343 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016344 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016345 hddLog(VOS_TRACE_LEVEL_ERROR,
16346 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016347 __func__, frag_threshold);
16348 return -EIO;
16349 }
16350
16351 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
16352 frag_threshold);
16353 }
16354
16355 if ((changed & WIPHY_PARAM_RETRY_SHORT)
16356 || (changed & WIPHY_PARAM_RETRY_LONG))
16357 {
16358 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
16359 wiphy->retry_short :
16360 wiphy->retry_long;
16361
16362 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
16363 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
16364 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016365 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016366 __func__, retry_value);
16367 return -EINVAL;
16368 }
16369
16370 if (changed & WIPHY_PARAM_RETRY_SHORT)
16371 {
16372 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
16373 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016374 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016375 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016376 hddLog(VOS_TRACE_LEVEL_ERROR,
16377 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016378 __func__, retry_value);
16379 return -EIO;
16380 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016381 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016382 __func__, retry_value);
16383 }
16384 else if (changed & WIPHY_PARAM_RETRY_SHORT)
16385 {
16386 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
16387 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016388 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016389 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016390 hddLog(VOS_TRACE_LEVEL_ERROR,
16391 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016392 __func__, retry_value);
16393 return -EIO;
16394 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016395 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016396 __func__, retry_value);
16397 }
16398 }
16399
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016400 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016401 return 0;
16402}
16403
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016404static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
16405 u32 changed)
16406{
16407 int ret;
16408
16409 vos_ssr_protect(__func__);
16410 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
16411 vos_ssr_unprotect(__func__);
16412
16413 return ret;
16414}
16415
Jeff Johnson295189b2012-06-20 16:38:30 -070016416/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016417 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070016418 * This function is used to set the txpower
16419 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016420static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070016421#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16422 struct wireless_dev *wdev,
16423#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016424#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016425 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070016426#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016427 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070016428#endif
16429 int dbm)
16430{
16431 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016432 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070016433 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
16434 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016435 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016436
16437 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016438
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016439 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16440 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
16441 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016442 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016443 if (0 != status)
16444 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016445 return status;
16446 }
16447
16448 hHal = pHddCtx->hHal;
16449
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016450 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
16451 dbm, ccmCfgSetCallback,
16452 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016453 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016454 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016455 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
16456 return -EIO;
16457 }
16458
16459 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
16460 dbm);
16461
16462 switch(type)
16463 {
16464 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
16465 /* Fall through */
16466 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
16467 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
16468 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016469 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
16470 __func__);
16471 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070016472 }
16473 break;
16474 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016475 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070016476 __func__);
16477 return -EOPNOTSUPP;
16478 break;
16479 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016480 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
16481 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070016482 return -EIO;
16483 }
16484
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016485 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016486 return 0;
16487}
16488
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016489static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
16490#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16491 struct wireless_dev *wdev,
16492#endif
16493#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
16494 enum tx_power_setting type,
16495#else
16496 enum nl80211_tx_power_setting type,
16497#endif
16498 int dbm)
16499{
16500 int ret;
16501 vos_ssr_protect(__func__);
16502 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
16503#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16504 wdev,
16505#endif
16506#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
16507 type,
16508#else
16509 type,
16510#endif
16511 dbm);
16512 vos_ssr_unprotect(__func__);
16513
16514 return ret;
16515}
16516
Jeff Johnson295189b2012-06-20 16:38:30 -070016517/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016518 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070016519 * This function is used to read the txpower
16520 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016521static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070016522#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16523 struct wireless_dev *wdev,
16524#endif
16525 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070016526{
16527
16528 hdd_adapter_t *pAdapter;
16529 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016530 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016531
Jeff Johnsone7245742012-09-05 17:12:55 -070016532 ENTER();
16533
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016534 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016535 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016536 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016537 *dbm = 0;
16538 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016539 }
16540
Jeff Johnson295189b2012-06-20 16:38:30 -070016541 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
16542 if (NULL == pAdapter)
16543 {
16544 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
16545 return -ENOENT;
16546 }
16547
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016548 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16549 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
16550 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070016551 wlan_hdd_get_classAstats(pAdapter);
16552 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
16553
Jeff Johnsone7245742012-09-05 17:12:55 -070016554 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016555 return 0;
16556}
16557
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016558static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
16559#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16560 struct wireless_dev *wdev,
16561#endif
16562 int *dbm)
16563{
16564 int ret;
16565
16566 vos_ssr_protect(__func__);
16567 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
16568#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16569 wdev,
16570#endif
16571 dbm);
16572 vos_ssr_unprotect(__func__);
16573
16574 return ret;
16575}
16576
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016577static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016578#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16579 const u8* mac,
16580#else
16581 u8* mac,
16582#endif
16583 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070016584{
16585 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
16586 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16587 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053016588 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070016589
16590 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
16591 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070016592
16593 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
16594 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
16595 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
16596 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
16597 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
16598 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
16599 tANI_U16 maxRate = 0;
16600 tANI_U16 myRate;
16601 tANI_U16 currentRate = 0;
16602 tANI_U8 maxSpeedMCS = 0;
16603 tANI_U8 maxMCSIdx = 0;
16604 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053016605 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070016606 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016607 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016608
Leo Chang6f8870f2013-03-26 18:11:36 -070016609#ifdef WLAN_FEATURE_11AC
16610 tANI_U32 vht_mcs_map;
16611 eDataRate11ACMaxMcs vhtMaxMcs;
16612#endif /* WLAN_FEATURE_11AC */
16613
Jeff Johnsone7245742012-09-05 17:12:55 -070016614 ENTER();
16615
Jeff Johnson295189b2012-06-20 16:38:30 -070016616 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
16617 (0 == ssidlen))
16618 {
16619 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
16620 " Invalid ssidlen, %d", __func__, ssidlen);
16621 /*To keep GUI happy*/
16622 return 0;
16623 }
16624
Mukul Sharma811205f2014-07-09 21:07:30 +053016625 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
16626 {
16627 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16628 "%s: Roaming in progress, so unable to proceed this request", __func__);
Sachin Ahuja81ab1812016-08-19 21:35:58 +053016629 /* return a cached value */
16630 sinfo->signal = pAdapter->rssi;
Mukul Sharma811205f2014-07-09 21:07:30 +053016631 return 0;
16632 }
16633
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016634 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016635 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016636 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016637 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016638 }
16639
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053016640 wlan_hdd_get_station_stats(pAdapter);
16641 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070016642
Kiet Lam3b17fc82013-09-27 05:24:08 +053016643 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
16644 sinfo->filled |= STATION_INFO_SIGNAL;
16645
c_hpothu09f19542014-05-30 21:53:31 +053016646 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053016647 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
16648 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053016649 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053016650 {
16651 rate_flags = pAdapter->maxRateFlags;
16652 }
c_hpothu44ff4e02014-05-08 00:13:57 +053016653
Jeff Johnson295189b2012-06-20 16:38:30 -070016654 //convert to the UI units of 100kbps
16655 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
16656
16657#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070016658 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 -070016659 sinfo->signal,
16660 pCfg->reportMaxLinkSpeed,
16661 myRate,
16662 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070016663 (int) pCfg->linkSpeedRssiMid,
16664 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070016665 (int) rate_flags,
16666 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070016667#endif //LINKSPEED_DEBUG_ENABLED
16668
16669 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
16670 {
16671 // we do not want to necessarily report the current speed
16672 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
16673 {
16674 // report the max possible speed
16675 rssidx = 0;
16676 }
16677 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
16678 {
16679 // report the max possible speed with RSSI scaling
16680 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
16681 {
16682 // report the max possible speed
16683 rssidx = 0;
16684 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070016685 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070016686 {
16687 // report middle speed
16688 rssidx = 1;
16689 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070016690 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
16691 {
16692 // report middle speed
16693 rssidx = 2;
16694 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016695 else
16696 {
16697 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070016698 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070016699 }
16700 }
16701 else
16702 {
16703 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
16704 hddLog(VOS_TRACE_LEVEL_ERROR,
16705 "%s: Invalid value for reportMaxLinkSpeed: %u",
16706 __func__, pCfg->reportMaxLinkSpeed);
16707 rssidx = 0;
16708 }
16709
16710 maxRate = 0;
16711
16712 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053016713 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
16714 OperationalRates, &ORLeng))
16715 {
16716 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
16717 /*To keep GUI happy*/
16718 return 0;
16719 }
16720
Jeff Johnson295189b2012-06-20 16:38:30 -070016721 for (i = 0; i < ORLeng; i++)
16722 {
Jeff Johnsone7245742012-09-05 17:12:55 -070016723 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070016724 {
16725 /* Validate Rate Set */
16726 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
16727 {
16728 currentRate = supported_data_rate[j].supported_rate[rssidx];
16729 break;
16730 }
16731 }
16732 /* Update MAX rate */
16733 maxRate = (currentRate > maxRate)?currentRate:maxRate;
16734 }
16735
16736 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053016737 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
16738 ExtendedRates, &ERLeng))
16739 {
16740 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
16741 /*To keep GUI happy*/
16742 return 0;
16743 }
16744
Jeff Johnson295189b2012-06-20 16:38:30 -070016745 for (i = 0; i < ERLeng; i++)
16746 {
Jeff Johnsone7245742012-09-05 17:12:55 -070016747 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070016748 {
16749 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
16750 {
16751 currentRate = supported_data_rate[j].supported_rate[rssidx];
16752 break;
16753 }
16754 }
16755 /* Update MAX rate */
16756 maxRate = (currentRate > maxRate)?currentRate:maxRate;
16757 }
c_hpothu79aab322014-07-14 21:11:01 +053016758
Kiet Lamb69f8dc2013-11-15 15:34:27 +053016759 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053016760 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053016761 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053016762 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070016763 {
c_hpothu79aab322014-07-14 21:11:01 +053016764 if (rate_flags & eHAL_TX_RATE_VHT80)
16765 mode = 2;
16766 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
16767 mode = 1;
16768 else
16769 mode = 0;
16770
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053016771 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
16772 MCSRates, &MCSLeng))
16773 {
16774 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
16775 /*To keep GUI happy*/
16776 return 0;
16777 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016778 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070016779#ifdef WLAN_FEATURE_11AC
16780 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016781 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070016782 {
Leo Chang6f8870f2013-03-26 18:11:36 -070016783 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016784 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070016785 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070016786 {
Leo Chang6f8870f2013-03-26 18:11:36 -070016787 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070016788 }
Leo Chang6f8870f2013-03-26 18:11:36 -070016789 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070016790 {
Leo Chang6f8870f2013-03-26 18:11:36 -070016791 maxMCSIdx = 7;
16792 }
16793 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
16794 {
16795 maxMCSIdx = 8;
16796 }
16797 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
16798 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016799 //VHT20 is supporting 0~8
16800 if (rate_flags & eHAL_TX_RATE_VHT20)
16801 maxMCSIdx = 8;
16802 else
16803 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070016804 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016805
c_hpothu79aab322014-07-14 21:11:01 +053016806 if (0 != rssidx)/*check for scaled */
16807 {
16808 //get middle rate MCS index if rssi=1/2
16809 for (i=0; i <= maxMCSIdx; i++)
16810 {
16811 if (sinfo->signal <= rssiMcsTbl[mode][i])
16812 {
16813 maxMCSIdx = i;
16814 break;
16815 }
16816 }
16817 }
16818
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016819 if (rate_flags & eHAL_TX_RATE_VHT80)
16820 {
16821 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
16822 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
16823 }
16824 else if (rate_flags & eHAL_TX_RATE_VHT40)
16825 {
16826 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
16827 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
16828 }
16829 else if (rate_flags & eHAL_TX_RATE_VHT20)
16830 {
16831 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
16832 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
16833 }
16834
Leo Chang6f8870f2013-03-26 18:11:36 -070016835 maxSpeedMCS = 1;
16836 if (currentRate > maxRate)
16837 {
16838 maxRate = currentRate;
16839 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016840
Leo Chang6f8870f2013-03-26 18:11:36 -070016841 }
16842 else
16843#endif /* WLAN_FEATURE_11AC */
16844 {
16845 if (rate_flags & eHAL_TX_RATE_HT40)
16846 {
16847 rateFlag |= 1;
16848 }
16849 if (rate_flags & eHAL_TX_RATE_SGI)
16850 {
16851 rateFlag |= 2;
16852 }
16853
Girish Gowli01abcee2014-07-31 20:18:55 +053016854 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053016855 if (rssidx == 1 || rssidx == 2)
16856 {
16857 //get middle rate MCS index if rssi=1/2
16858 for (i=0; i <= 7; i++)
16859 {
16860 if (sinfo->signal <= rssiMcsTbl[mode][i])
16861 {
16862 temp = i+1;
16863 break;
16864 }
16865 }
16866 }
c_hpothu79aab322014-07-14 21:11:01 +053016867
16868 for (i = 0; i < MCSLeng; i++)
16869 {
Leo Chang6f8870f2013-03-26 18:11:36 -070016870 for (j = 0; j < temp; j++)
16871 {
16872 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
16873 {
16874 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053016875 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070016876 break;
16877 }
16878 }
16879 if ((j < temp) && (currentRate > maxRate))
16880 {
16881 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070016882 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016883 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053016884 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070016885 }
16886 }
16887
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016888 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
16889 {
16890 maxRate = myRate;
16891 maxSpeedMCS = 1;
16892 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
16893 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016894 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053016895 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070016896 {
16897 maxRate = myRate;
16898 if (rate_flags & eHAL_TX_RATE_LEGACY)
16899 {
16900 maxSpeedMCS = 0;
16901 }
16902 else
16903 {
16904 maxSpeedMCS = 1;
16905 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
16906 }
16907 }
16908
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016909 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070016910 {
16911 sinfo->txrate.legacy = maxRate;
16912#ifdef LINKSPEED_DEBUG_ENABLED
16913 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
16914#endif //LINKSPEED_DEBUG_ENABLED
16915 }
16916 else
16917 {
16918 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070016919#ifdef WLAN_FEATURE_11AC
16920 sinfo->txrate.nss = 1;
16921 if (rate_flags & eHAL_TX_RATE_VHT80)
16922 {
16923 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016924 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070016925 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016926 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070016927 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016928 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
16929 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
16930 }
16931 else if (rate_flags & eHAL_TX_RATE_VHT20)
16932 {
16933 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
16934 }
16935#endif /* WLAN_FEATURE_11AC */
16936 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
16937 {
16938 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
16939 if (rate_flags & eHAL_TX_RATE_HT40)
16940 {
16941 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
16942 }
Leo Chang6f8870f2013-03-26 18:11:36 -070016943 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016944 if (rate_flags & eHAL_TX_RATE_SGI)
16945 {
16946 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
16947 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016948
Jeff Johnson295189b2012-06-20 16:38:30 -070016949#ifdef LINKSPEED_DEBUG_ENABLED
16950 pr_info("Reporting MCS rate %d flags %x\n",
16951 sinfo->txrate.mcs,
16952 sinfo->txrate.flags );
16953#endif //LINKSPEED_DEBUG_ENABLED
16954 }
16955 }
16956 else
16957 {
16958 // report current rate instead of max rate
16959
16960 if (rate_flags & eHAL_TX_RATE_LEGACY)
16961 {
16962 //provide to the UI in units of 100kbps
16963 sinfo->txrate.legacy = myRate;
16964#ifdef LINKSPEED_DEBUG_ENABLED
16965 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
16966#endif //LINKSPEED_DEBUG_ENABLED
16967 }
16968 else
16969 {
16970 //must be MCS
16971 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070016972#ifdef WLAN_FEATURE_11AC
16973 sinfo->txrate.nss = 1;
16974 if (rate_flags & eHAL_TX_RATE_VHT80)
16975 {
16976 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
16977 }
16978 else
16979#endif /* WLAN_FEATURE_11AC */
16980 {
16981 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
16982 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016983 if (rate_flags & eHAL_TX_RATE_SGI)
16984 {
16985 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
16986 }
16987 if (rate_flags & eHAL_TX_RATE_HT40)
16988 {
16989 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
16990 }
Leo Chang6f8870f2013-03-26 18:11:36 -070016991#ifdef WLAN_FEATURE_11AC
16992 else if (rate_flags & eHAL_TX_RATE_VHT80)
16993 {
16994 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
16995 }
16996#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070016997#ifdef LINKSPEED_DEBUG_ENABLED
16998 pr_info("Reporting actual MCS rate %d flags %x\n",
16999 sinfo->txrate.mcs,
17000 sinfo->txrate.flags );
17001#endif //LINKSPEED_DEBUG_ENABLED
17002 }
17003 }
17004 sinfo->filled |= STATION_INFO_TX_BITRATE;
17005
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070017006 sinfo->tx_packets =
17007 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
17008 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
17009 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
17010 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
17011
17012 sinfo->tx_retries =
17013 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
17014 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
17015 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
17016 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
17017
17018 sinfo->tx_failed =
17019 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
17020 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
17021 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
17022 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
17023
17024 sinfo->filled |=
17025 STATION_INFO_TX_PACKETS |
17026 STATION_INFO_TX_RETRIES |
17027 STATION_INFO_TX_FAILED;
17028
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053017029 sinfo->rx_packets = pAdapter->hdd_stats.summary_stat.rx_frm_cnt;
17030 sinfo->filled |= STATION_INFO_RX_PACKETS;
17031
17032 if (rate_flags & eHAL_TX_RATE_LEGACY)
17033 hddLog(LOG1, FL("Reporting RSSI:%d legacy rate %d pkt cnt tx %d rx %d"),
17034 sinfo->signal, sinfo->txrate.legacy, sinfo->tx_packets,
17035 sinfo->rx_packets);
17036 else
17037 hddLog(LOG1,
17038 FL("Reporting RSSI:%d MCS rate %d flags 0x%x pkt cnt tx %d rx %d"),
17039 sinfo->signal, sinfo->txrate.mcs, sinfo->txrate.flags,
17040 sinfo->tx_packets, sinfo->rx_packets);
17041
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017042 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17043 TRACE_CODE_HDD_CFG80211_GET_STA,
17044 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070017045 EXIT();
17046 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070017047}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017048#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
17049static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
17050 const u8* mac, struct station_info *sinfo)
17051#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017052static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
17053 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017054#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017055{
17056 int ret;
17057
17058 vos_ssr_protect(__func__);
17059 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
17060 vos_ssr_unprotect(__func__);
17061
17062 return ret;
17063}
17064
17065static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070017066 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070017067{
17068 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017069 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070017070 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017071 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017072
Jeff Johnsone7245742012-09-05 17:12:55 -070017073 ENTER();
17074
Jeff Johnson295189b2012-06-20 16:38:30 -070017075 if (NULL == pAdapter)
17076 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017077 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017078 return -ENODEV;
17079 }
17080
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017081 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17082 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
17083 pAdapter->sessionId, timeout));
17084
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017085 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017086 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017087 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017088 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017089 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017090 }
17091
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017092 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
17093 (TRUE == pHddCtx->hdd_wlan_suspended) &&
17094 (pHddCtx->cfg_ini->fhostArpOffload) &&
17095 (eConnectionState_Associated ==
17096 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
17097 {
Amar Singhald53568e2013-09-26 11:03:45 -070017098
17099 hddLog(VOS_TRACE_LEVEL_INFO,
17100 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053017101 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017102 if (!VOS_IS_STATUS_SUCCESS(vos_status))
17103 {
17104 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017105 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017106 __func__, vos_status);
17107 }
17108 }
17109
Jeff Johnson295189b2012-06-20 16:38:30 -070017110 /**The get power cmd from the supplicant gets updated by the nl only
17111 *on successful execution of the function call
17112 *we are oppositely mapped w.r.t mode in the driver
17113 **/
17114 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
17115
17116 if (VOS_STATUS_E_FAILURE == vos_status)
17117 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053017118 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17119 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017120 return -EINVAL;
17121 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017122 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017123 return 0;
17124}
17125
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017126static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
17127 struct net_device *dev, bool mode, int timeout)
17128{
17129 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070017130
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017131 vos_ssr_protect(__func__);
17132 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
17133 vos_ssr_unprotect(__func__);
17134
17135 return ret;
17136}
Sushant Kaushik084f6592015-09-10 13:11:56 +053017137
Jeff Johnson295189b2012-06-20 16:38:30 -070017138#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017139static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
17140 struct net_device *netdev,
17141 u8 key_index)
17142{
17143 ENTER();
17144 return 0;
17145}
17146
Jeff Johnson295189b2012-06-20 16:38:30 -070017147static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017148 struct net_device *netdev,
17149 u8 key_index)
17150{
17151 int ret;
17152 vos_ssr_protect(__func__);
17153 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
17154 vos_ssr_unprotect(__func__);
17155 return ret;
17156}
17157#endif //LINUX_VERSION_CODE
17158
17159#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
17160static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
17161 struct net_device *dev,
17162 struct ieee80211_txq_params *params)
17163{
17164 ENTER();
17165 return 0;
17166}
17167#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
17168static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
17169 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070017170{
Jeff Johnsone7245742012-09-05 17:12:55 -070017171 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070017172 return 0;
17173}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017174#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070017175
17176#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
17177static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017178 struct net_device *dev,
17179 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070017180{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017181 int ret;
17182
17183 vos_ssr_protect(__func__);
17184 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
17185 vos_ssr_unprotect(__func__);
17186 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070017187}
17188#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
17189static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
17190 struct ieee80211_txq_params *params)
17191{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017192 int ret;
17193
17194 vos_ssr_protect(__func__);
17195 ret = __wlan_hdd_set_txq_params(wiphy, params);
17196 vos_ssr_unprotect(__func__);
17197 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070017198}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017199#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017200
Naresh Jayaram69e3f282014-10-14 12:29:12 +053017201static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017202 struct net_device *dev,
17203 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070017204{
17205 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017206 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017207 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017208 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017209 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017210 v_CONTEXT_t pVosContext = NULL;
17211 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017212
Jeff Johnsone7245742012-09-05 17:12:55 -070017213 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017214
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017215 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070017216 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017217 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017218 return -EINVAL;
17219 }
17220
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017221 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17222 TRACE_CODE_HDD_CFG80211_DEL_STA,
17223 pAdapter->sessionId, pAdapter->device_mode));
17224
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017225 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17226 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017227 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017228 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017229 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017230 }
17231
Jeff Johnson295189b2012-06-20 16:38:30 -070017232 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070017233 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070017234 )
17235 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017236 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
17237 pSapCtx = VOS_GET_SAP_CB(pVosContext);
17238 if(pSapCtx == NULL){
17239 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17240 FL("psapCtx is NULL"));
17241 return -ENOENT;
17242 }
Agrawal Ashish306b75f2017-01-11 19:16:25 +053017243 if (pHddCtx->cfg_ini->enable_sap_auth_offload)
17244 {
17245 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
17246 "Change reason code to eSIR_MAC_DISASSOC_LEAVING_BSS_REASON in sap auth offload");
17247 pDelStaParams->reason_code = eSIR_MAC_DISASSOC_LEAVING_BSS_REASON;
17248 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017249 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070017250 {
17251 v_U16_t i;
17252 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
17253 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017254 if ((pSapCtx->aStaInfo[i].isUsed) &&
17255 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070017256 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017257 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017258 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017259 ETHER_ADDR_LEN);
17260
Jeff Johnson295189b2012-06-20 16:38:30 -070017261 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080017262 "%s: Delete STA with MAC::"
17263 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017264 __func__,
17265 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
17266 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070017267 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017268 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070017269 }
17270 }
17271 }
17272 else
17273 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017274
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017275 vos_status = hdd_softap_GetStaId(pAdapter,
17276 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017277 if (!VOS_IS_STATUS_SUCCESS(vos_status))
17278 {
17279 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080017280 "%s: Skip this DEL STA as this is not used::"
17281 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017282 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017283 return -ENOENT;
17284 }
17285
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017286 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017287 {
17288 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080017289 "%s: Skip this DEL STA as deauth is in progress::"
17290 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017291 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017292 return -ENOENT;
17293 }
17294
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017295 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017296
Jeff Johnson295189b2012-06-20 16:38:30 -070017297 hddLog(VOS_TRACE_LEVEL_INFO,
17298 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080017299 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070017300 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017301 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017302
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017303 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017304 if (!VOS_IS_STATUS_SUCCESS(vos_status))
17305 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017306 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017307 hddLog(VOS_TRACE_LEVEL_INFO,
17308 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080017309 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017310 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017311 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017312 return -ENOENT;
17313 }
17314
Jeff Johnson295189b2012-06-20 16:38:30 -070017315 }
17316 }
17317
17318 EXIT();
17319
17320 return 0;
17321}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053017322
17323#ifdef CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053017324int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Naresh Jayaram69e3f282014-10-14 12:29:12 +053017325 struct net_device *dev,
17326 struct station_del_parameters *param)
17327#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017328#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
Kapil Gupta137ef892016-12-13 19:38:00 +053017329int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017330 struct net_device *dev, const u8 *mac)
17331#else
Kapil Gupta137ef892016-12-13 19:38:00 +053017332int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017333 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053017334#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017335#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017336{
17337 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017338 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070017339
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017340 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017341
Naresh Jayaram69e3f282014-10-14 12:29:12 +053017342#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017343 if (NULL == param) {
17344 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017345 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017346 return -EINVAL;
17347 }
17348
17349 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
17350 param->subtype, &delStaParams);
17351
Naresh Jayaram69e3f282014-10-14 12:29:12 +053017352#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053017353 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017354 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053017355#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017356 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
17357
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017358 vos_ssr_unprotect(__func__);
17359
17360 return ret;
17361}
17362
17363static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017364 struct net_device *dev,
17365#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17366 const u8 *mac,
17367#else
17368 u8 *mac,
17369#endif
17370 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017371{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017372 hdd_adapter_t *pAdapter;
17373 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017374 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017375#ifdef FEATURE_WLAN_TDLS
17376 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017377
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017378 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017379
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017380 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17381 if (NULL == pAdapter)
17382 {
17383 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17384 "%s: Adapter is NULL",__func__);
17385 return -EINVAL;
17386 }
17387 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17388 status = wlan_hdd_validate_context(pHddCtx);
17389 if (0 != status)
17390 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017391 return status;
17392 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017393
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017394 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17395 TRACE_CODE_HDD_CFG80211_ADD_STA,
17396 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017397 mask = params->sta_flags_mask;
17398
17399 set = params->sta_flags_set;
17400
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017401 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017402 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
17403 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017404
17405 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
17406 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080017407 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017408 }
17409 }
17410#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017411 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017412 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017413}
17414
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017415#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
17416static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
17417 struct net_device *dev, const u8 *mac,
17418 struct station_parameters *params)
17419#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017420static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
17421 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017422#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017423{
17424 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017425
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017426 vos_ssr_protect(__func__);
17427 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
17428 vos_ssr_unprotect(__func__);
17429
17430 return ret;
17431}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017432#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070017433
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017434static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070017435 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017436{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017437 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17438 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017439 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017440 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017441 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017442 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070017443
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017444 ENTER();
17445
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017446 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017447 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017448 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017449 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017450 return -EINVAL;
17451 }
17452
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017453 if (!pmksa) {
17454 hddLog(LOGE, FL("pmksa is NULL"));
17455 return -EINVAL;
17456 }
17457
17458 if (!pmksa->bssid || !pmksa->pmkid) {
17459 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
17460 pmksa->bssid, pmksa->pmkid);
17461 return -EINVAL;
17462 }
17463
17464 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
17465 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
17466
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017467 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17468 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017469 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017470 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017471 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017472 }
17473
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017474 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017475 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
17476
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017477 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
17478 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017479
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017480 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017481 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017482 &pmk_id, 1, FALSE);
17483
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017484 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17485 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
17486 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017487
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017488 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017489 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017490}
17491
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017492static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
17493 struct cfg80211_pmksa *pmksa)
17494{
17495 int ret;
17496
17497 vos_ssr_protect(__func__);
17498 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
17499 vos_ssr_unprotect(__func__);
17500
17501 return ret;
17502}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017503
Wilson Yang6507c4e2013-10-01 20:11:19 -070017504
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017505static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070017506 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017507{
Wilson Yang6507c4e2013-10-01 20:11:19 -070017508 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17509 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017510 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080017511 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017512
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017513 ENTER();
17514
Wilson Yang6507c4e2013-10-01 20:11:19 -070017515 /* Validate pAdapter */
17516 if (NULL == pAdapter)
17517 {
17518 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
17519 return -EINVAL;
17520 }
17521
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017522 if (!pmksa) {
17523 hddLog(LOGE, FL("pmksa is NULL"));
17524 return -EINVAL;
17525 }
17526
17527 if (!pmksa->bssid) {
17528 hddLog(LOGE, FL("pmksa->bssid is NULL"));
17529 return -EINVAL;
17530 }
17531
Kiet Lam98c46a12014-10-31 15:34:57 -070017532 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
17533 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
17534
Wilson Yang6507c4e2013-10-01 20:11:19 -070017535 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17536 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070017537 if (0 != status)
17538 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070017539 return status;
17540 }
17541
17542 /*Retrieve halHandle*/
17543 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
17544
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017545 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17546 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
17547 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017548 /* Delete the PMKID CSR cache */
17549 if (eHAL_STATUS_SUCCESS !=
17550 sme_RoamDelPMKIDfromCache(halHandle,
17551 pAdapter->sessionId, pmksa->bssid, FALSE)) {
17552 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
17553 MAC_ADDR_ARRAY(pmksa->bssid));
17554 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017555 }
17556
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017557 EXIT();
17558 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017559}
17560
Wilson Yang6507c4e2013-10-01 20:11:19 -070017561
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017562static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
17563 struct cfg80211_pmksa *pmksa)
17564{
17565 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017566
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017567 vos_ssr_protect(__func__);
17568 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
17569 vos_ssr_unprotect(__func__);
17570
17571 return ret;
17572
17573}
17574
17575static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017576{
Wilson Yang6507c4e2013-10-01 20:11:19 -070017577 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17578 tHalHandle halHandle;
17579 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080017580 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017581
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017582 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070017583
17584 /* Validate pAdapter */
17585 if (NULL == pAdapter)
17586 {
17587 hddLog(VOS_TRACE_LEVEL_ERROR,
17588 "%s: Invalid Adapter" ,__func__);
17589 return -EINVAL;
17590 }
17591
17592 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17593 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070017594 if (0 != status)
17595 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070017596 return status;
17597 }
17598
17599 /*Retrieve halHandle*/
17600 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
17601
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017602 /* Flush the PMKID cache in CSR */
17603 if (eHAL_STATUS_SUCCESS !=
17604 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
17605 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
17606 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017607 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017608 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080017609 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017610}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017611
17612static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
17613{
17614 int ret;
17615
17616 vos_ssr_protect(__func__);
17617 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
17618 vos_ssr_unprotect(__func__);
17619
17620 return ret;
17621}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017622#endif
17623
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017624#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017625static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
17626 struct net_device *dev,
17627 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017628{
17629 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17630 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017631 hdd_context_t *pHddCtx;
17632 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017633
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017634 ENTER();
17635
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017636 if (NULL == pAdapter)
17637 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017638 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017639 return -ENODEV;
17640 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017641 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17642 ret = wlan_hdd_validate_context(pHddCtx);
17643 if (0 != ret)
17644 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017645 return ret;
17646 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017647 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017648 if (NULL == pHddStaCtx)
17649 {
17650 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
17651 return -EINVAL;
17652 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017653
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017654 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17655 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
17656 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017657 // Added for debug on reception of Re-assoc Req.
17658 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
17659 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017660 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017661 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080017662 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017663 }
17664
17665#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080017666 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017667 ftie->ie_len);
17668#endif
17669
17670 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053017671 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
17672 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017673 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017674
17675 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017676 return 0;
17677}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017678
17679static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
17680 struct net_device *dev,
17681 struct cfg80211_update_ft_ies_params *ftie)
17682{
17683 int ret;
17684
17685 vos_ssr_protect(__func__);
17686 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
17687 vos_ssr_unprotect(__func__);
17688
17689 return ret;
17690}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017691#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017692
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017693#ifdef FEATURE_WLAN_SCAN_PNO
17694
17695void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
17696 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
17697{
17698 int ret;
17699 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
17700 hdd_context_t *pHddCtx;
17701
Nirav Shah80830bf2013-12-31 16:35:12 +053017702 ENTER();
17703
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017704 if (NULL == pAdapter)
17705 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053017706 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017707 "%s: HDD adapter is Null", __func__);
17708 return ;
17709 }
17710
17711 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17712 if (NULL == pHddCtx)
17713 {
17714 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17715 "%s: HDD context is Null!!!", __func__);
17716 return ;
17717 }
17718
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017719 spin_lock(&pHddCtx->schedScan_lock);
17720 if (TRUE == pHddCtx->isWiphySuspended)
17721 {
17722 pHddCtx->isSchedScanUpdatePending = TRUE;
17723 spin_unlock(&pHddCtx->schedScan_lock);
17724 hddLog(VOS_TRACE_LEVEL_INFO,
17725 "%s: Update cfg80211 scan database after it resume", __func__);
17726 return ;
17727 }
17728 spin_unlock(&pHddCtx->schedScan_lock);
17729
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017730 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
17731
17732 if (0 > ret)
17733 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagarfb49cdd2015-10-16 18:41:59 +053017734 else
17735 {
17736 /* Acquire wakelock to handle the case where APP's tries to suspend
17737 * immediatly after the driver gets connect request(i.e after pno)
17738 * from supplicant, this result in app's is suspending and not able
17739 * to process the connect request to AP */
17740 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
17741 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017742 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017743 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17744 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017745}
17746
17747/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017748 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053017749 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017750 */
17751static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
17752{
17753 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
17754 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017755 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017756 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17757 int status = 0;
Agrawal Ashishcff31692016-12-16 17:17:50 +053017758
17759 if (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
17760 {
17761 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17762 "%s: PNO is allowed only in STA interface", __func__);
17763 return eHAL_STATUS_FAILURE;
17764 }
17765
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017766 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
17767
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053017768 /* The current firmware design does not allow PNO during any
Agrawal Ashishcff31692016-12-16 17:17:50 +053017769 * active sessions. PNO is allowed only in case when sap session
17770 * is present and sapo auth offload feature enabled in firmare.
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053017771 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017772 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
17773 {
17774 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017775 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017776
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017777 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
17778 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
17779 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
17780 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
Agrawal Ashishcff31692016-12-16 17:17:50 +053017781 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode &&
17782 !pHddCtx->cfg_ini->enable_sap_auth_offload)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053017783 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017784 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017785 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017786 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017787 }
17788 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
17789 pAdapterNode = pNext;
17790 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017791 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017792}
17793
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017794void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
17795{
17796 hdd_adapter_t *pAdapter = callbackContext;
17797 hdd_context_t *pHddCtx;
17798
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017799 ENTER();
17800
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017801 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
17802 {
17803 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17804 FL("Invalid adapter or adapter has invalid magic"));
17805 return;
17806 }
17807
17808 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17809 if (0 != wlan_hdd_validate_context(pHddCtx))
17810 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017811 return;
17812 }
17813
c_hpothub53c45d2014-08-18 16:53:14 +053017814 if (VOS_STATUS_SUCCESS != status)
17815 {
17816 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017817 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053017818 pHddCtx->isPnoEnable = FALSE;
17819 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017820
17821 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
17822 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017823 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017824}
17825
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017826#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) || \
17827 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
17828/**
17829 * hdd_config_sched_scan_plan() - configures the sched scan plans
17830 * from the framework.
17831 * @pno_req: pointer to PNO scan request
17832 * @request: pointer to scan request from framework
17833 *
17834 * Return: None
17835 */
17836static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
17837 struct cfg80211_sched_scan_request *request,
17838 hdd_context_t *hdd_ctx)
17839{
17840 v_U32_t i = 0;
17841
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053017842 pno_req->scanTimers.ucScanTimersCount = request->n_scan_plans;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017843 for (i = 0; i < request->n_scan_plans; i++)
17844 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053017845 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
17846 request->scan_plans[i].iterations;
17847 pno_req->scanTimers.aTimerValues[i].uTimerValue =
17848 request->scan_plans[i].interval;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017849 }
17850}
17851#else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053017852static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017853 struct cfg80211_sched_scan_request *request,
17854 hdd_context_t *hdd_ctx)
17855{
17856 v_U32_t i, temp_int;
17857 /* Driver gets only one time interval which is hardcoded in
17858 * supplicant for 10000ms. Taking power consumption into account 6
17859 * timers will be used, Timervalue is increased exponentially
17860 * i.e 10,20,40, 80,160,320 secs. And number of scan cycle for each
17861 * timer is configurable through INI param gPNOScanTimerRepeatValue.
17862 * If it is set to 0 only one timer will be used and PNO scan cycle
17863 * will be repeated after each interval specified by supplicant
17864 * till PNO is disabled.
17865 */
17866 if (0 == hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue)
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053017867 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017868 HDD_PNO_SCAN_TIMERS_SET_ONE;
17869 else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053017870 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017871 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
17872
17873 temp_int = (request->interval)/1000;
17874 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17875 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
17876 temp_int, hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue);
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053017877 for ( i = 0; i < pno_req->scanTimers.ucScanTimersCount; i++)
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017878 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053017879 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017880 hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue;
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053017881 pno_req->scanTimers.aTimerValues[i].uTimerValue = temp_int;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017882 temp_int *= 2;
17883 }
17884 //Repeat last timer until pno disabled.
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053017885 pno_req->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017886}
17887#endif
17888
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017889/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017890 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
17891 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017892 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017893static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017894 struct net_device *dev, struct cfg80211_sched_scan_request *request)
17895{
17896 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017897 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017898 hdd_context_t *pHddCtx;
17899 tHalHandle hHal;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017900 v_U32_t i, indx, num_ch, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053017901 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
17902 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017903 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
17904 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017905 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053017906 hdd_config_t *pConfig = NULL;
17907 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017908
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017909 ENTER();
17910
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017911 if (NULL == pAdapter)
17912 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017913 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017914 "%s: HDD adapter is Null", __func__);
17915 return -ENODEV;
17916 }
17917
17918 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017919 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017920
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017921 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017922 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017923 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017924 }
17925
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053017926 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017927 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
17928 if (NULL == hHal)
17929 {
17930 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17931 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017932 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017933 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017934 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17935 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
17936 pAdapter->sessionId, pAdapter->device_mode));
Sushant Kaushik2fe89932014-09-03 10:58:09 +053017937 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053017938 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053017939 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053017940 {
17941 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17942 "%s: aborting the existing scan is unsuccessfull", __func__);
17943 return -EBUSY;
17944 }
17945
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017946 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017947 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053017948 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017949 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017950 return -EBUSY;
17951 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017952
c_hpothu37f21312014-04-09 21:49:54 +053017953 if (TRUE == pHddCtx->isPnoEnable)
17954 {
17955 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
17956 FL("already PNO is enabled"));
17957 return -EBUSY;
17958 }
c_hpothu225aa7c2014-10-22 17:45:13 +053017959
17960 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
17961 {
17962 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17963 "%s: abort ROC failed ", __func__);
17964 return -EBUSY;
17965 }
17966
c_hpothu37f21312014-04-09 21:49:54 +053017967 pHddCtx->isPnoEnable = TRUE;
17968
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017969 pnoRequest.enable = 1; /*Enable PNO */
17970 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017971
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017972 if (( !pnoRequest.ucNetworksCount ) ||
17973 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017974 {
17975 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053017976 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017977 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053017978 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017979 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017980 goto error;
17981 }
17982
17983 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
17984 {
17985 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053017986 "%s: Incorrect number of channels %d",
17987 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017988 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017989 goto error;
17990 }
17991
17992 /* Framework provides one set of channels(all)
17993 * common for all saved profile */
17994 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
17995 channels_allowed, &num_channels_allowed))
17996 {
17997 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17998 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017999 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018000 goto error;
18001 }
18002 /* Checking each channel against allowed channel list */
18003 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053018004 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018005 {
Nirav Shah80830bf2013-12-31 16:35:12 +053018006 char chList [(request->n_channels*5)+1];
18007 int len;
18008 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018009 {
Nirav Shah80830bf2013-12-31 16:35:12 +053018010 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018011 {
Nirav Shah80830bf2013-12-31 16:35:12 +053018012 if (request->channels[i]->hw_value == channels_allowed[indx])
18013 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053018014 if ((!pConfig->enableDFSPnoChnlScan) &&
18015 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
18016 {
18017 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18018 "%s : Dropping DFS channel : %d",
18019 __func__,channels_allowed[indx]);
18020 num_ignore_dfs_ch++;
18021 break;
18022 }
18023
Nirav Shah80830bf2013-12-31 16:35:12 +053018024 valid_ch[num_ch++] = request->channels[i]->hw_value;
18025 len += snprintf(chList+len, 5, "%d ",
18026 request->channels[i]->hw_value);
18027 break ;
18028 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018029 }
18030 }
Nirav Shah80830bf2013-12-31 16:35:12 +053018031 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018032
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053018033 /*If all channels are DFS and dropped, then ignore the PNO request*/
18034 if (num_ignore_dfs_ch == request->n_channels)
18035 {
18036 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18037 "%s : All requested channels are DFS channels", __func__);
18038 ret = -EINVAL;
18039 goto error;
18040 }
18041 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018042
18043 pnoRequest.aNetworks =
18044 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
18045 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018046 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018047 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
18048 FL("failed to allocate memory aNetworks %u"),
18049 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
18050 goto error;
18051 }
18052 vos_mem_zero(pnoRequest.aNetworks,
18053 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
18054
18055 /* Filling per profile params */
18056 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
18057 {
18058 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018059 request->match_sets[i].ssid.ssid_len;
18060
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018061 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
18062 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018063 {
18064 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053018065 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018066 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018067 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018068 goto error;
18069 }
18070
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018071 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018072 request->match_sets[i].ssid.ssid,
18073 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053018074 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18075 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018076 i, pnoRequest.aNetworks[i].ssId.ssId);
18077 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
18078 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
18079 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018080
18081 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018082 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
18083 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018084
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018085 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018086 }
18087
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018088 for (i = 0; i < request->n_ssids; i++)
18089 {
18090 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018091 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018092 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018093 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018094 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018095 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018096 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018097 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018098 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018099 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018100 break;
18101 }
18102 j++;
18103 }
18104 }
18105 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18106 "Number of hidden networks being Configured = %d",
18107 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053018108 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080018109 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018110
18111 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
18112 if (pnoRequest.p24GProbeTemplate == NULL)
18113 {
18114 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
18115 FL("failed to allocate memory p24GProbeTemplate %u"),
18116 SIR_PNO_MAX_PB_REQ_SIZE);
18117 goto error;
18118 }
18119
18120 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
18121 if (pnoRequest.p5GProbeTemplate == NULL)
18122 {
18123 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
18124 FL("failed to allocate memory p5GProbeTemplate %u"),
18125 SIR_PNO_MAX_PB_REQ_SIZE);
18126 goto error;
18127 }
18128
18129 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
18130 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
18131
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053018132 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
18133 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053018134 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018135 pnoRequest.us24GProbeTemplateLen = request->ie_len;
18136 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
18137 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053018138
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018139 pnoRequest.us5GProbeTemplateLen = request->ie_len;
18140 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
18141 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053018142 }
18143
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018144 hdd_config_sched_scan_plan(&pnoRequest, request, pHddCtx);
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053018145
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018146 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018147
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018148 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018149 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
18150 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018151 pAdapter->pno_req_status = 0;
18152
Nirav Shah80830bf2013-12-31 16:35:12 +053018153 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18154 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018155 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
18156 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053018157
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018158 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018159 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018160 hdd_cfg80211_sched_scan_done_callback, pAdapter);
18161 if (eHAL_STATUS_SUCCESS != status)
18162 {
18163 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053018164 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018165 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018166 goto error;
18167 }
18168
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018169 ret = wait_for_completion_timeout(
18170 &pAdapter->pno_comp_var,
18171 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
18172 if (0 >= ret)
18173 {
18174 // Did not receive the response for PNO enable in time.
18175 // Assuming the PNO enable was success.
18176 // Returning error from here, because we timeout, results
18177 // in side effect of Wifi (Wifi Setting) not to work.
18178 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18179 FL("Timed out waiting for PNO to be Enabled"));
18180 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018181 }
18182
18183 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053018184 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018185
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018186error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018187 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18188 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053018189 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018190 if (pnoRequest.aNetworks)
18191 vos_mem_free(pnoRequest.aNetworks);
18192 if (pnoRequest.p24GProbeTemplate)
18193 vos_mem_free(pnoRequest.p24GProbeTemplate);
18194 if (pnoRequest.p5GProbeTemplate)
18195 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018196
18197 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018198 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018199}
18200
18201/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018202 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
18203 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018204 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018205static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
18206 struct net_device *dev, struct cfg80211_sched_scan_request *request)
18207{
18208 int ret;
18209
18210 vos_ssr_protect(__func__);
18211 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
18212 vos_ssr_unprotect(__func__);
18213
18214 return ret;
18215}
18216
18217/*
18218 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
18219 * Function to disable PNO
18220 */
18221static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018222 struct net_device *dev)
18223{
18224 eHalStatus status = eHAL_STATUS_FAILURE;
18225 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18226 hdd_context_t *pHddCtx;
18227 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018228 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018229 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018230
18231 ENTER();
18232
18233 if (NULL == pAdapter)
18234 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018235 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018236 "%s: HDD adapter is Null", __func__);
18237 return -ENODEV;
18238 }
18239
18240 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018241
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018242 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018243 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018244 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018245 "%s: HDD context is Null", __func__);
18246 return -ENODEV;
18247 }
18248
18249 /* The return 0 is intentional when isLogpInProgress and
18250 * isLoadUnloadInProgress. We did observe a crash due to a return of
18251 * failure in sched_scan_stop , especially for a case where the unload
18252 * of the happens at the same time. The function __cfg80211_stop_sched_scan
18253 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
18254 * success. If it returns a failure , then its next invocation due to the
18255 * clean up of the second interface will have the dev pointer corresponding
18256 * to the first one leading to a crash.
18257 */
18258 if (pHddCtx->isLogpInProgress)
18259 {
18260 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18261 "%s: LOGP in Progress. Ignore!!!", __func__);
Mahesh A Saptasagar0c11d822015-10-08 19:54:08 +053018262 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018263 return ret;
18264 }
18265
Mihir Shete18156292014-03-11 15:38:30 +053018266 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018267 {
18268 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18269 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
18270 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018271 }
18272
18273 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
18274 if (NULL == hHal)
18275 {
18276 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18277 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018278 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018279 }
18280
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018281 pnoRequest.enable = 0; /* Disable PNO */
18282 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018283
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018284 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18285 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
18286 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053018287
18288 INIT_COMPLETION(pAdapter->pno_comp_var);
18289 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
18290 pnoRequest.callbackContext = pAdapter;
18291 pAdapter->pno_req_status = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018292 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018293 pAdapter->sessionId,
18294 NULL, pAdapter);
18295 if (eHAL_STATUS_SUCCESS != status)
18296 {
18297 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18298 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018299 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018300 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018301 }
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053018302 ret = wait_for_completion_timeout(
18303 &pAdapter->pno_comp_var,
18304 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
18305 if (0 >= ret)
18306 {
18307 // Did not receive the response for PNO disable in time.
18308 // Assuming the PNO disable was success.
18309 // Returning error from here, because we timeout, results
18310 // in side effect of Wifi (Wifi Setting) not to work.
Anurag Chouhan96b41cb2016-09-28 18:54:47 +053018311 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053018312 FL("Timed out waiting for PNO to be disabled"));
18313 ret = 0;
18314 }
18315
18316 ret = pAdapter->pno_req_status;
18317 pHddCtx->isPnoEnable = (ret == 0) ? FALSE : TRUE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018318
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018319error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018320 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018321 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018322
18323 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018324 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018325}
18326
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018327/*
18328 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
18329 * NL interface to disable PNO
18330 */
18331static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
18332 struct net_device *dev)
18333{
18334 int ret;
18335
18336 vos_ssr_protect(__func__);
18337 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
18338 vos_ssr_unprotect(__func__);
18339
18340 return ret;
18341}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018342#endif /*FEATURE_WLAN_SCAN_PNO*/
18343
18344
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018345#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018346#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018347static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18348 struct net_device *dev,
18349 u8 *peer, u8 action_code,
18350 u8 dialog_token,
18351 u16 status_code, u32 peer_capability,
18352 const u8 *buf, size_t len)
18353#else /* TDLS_MGMT_VERSION2 */
18354#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
18355static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18356 struct net_device *dev,
18357 const u8 *peer, u8 action_code,
18358 u8 dialog_token, u16 status_code,
18359 u32 peer_capability, bool initiator,
18360 const u8 *buf, size_t len)
18361#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
18362static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18363 struct net_device *dev,
18364 const u8 *peer, u8 action_code,
18365 u8 dialog_token, u16 status_code,
18366 u32 peer_capability, const u8 *buf,
18367 size_t len)
18368#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
18369static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18370 struct net_device *dev,
18371 u8 *peer, u8 action_code,
18372 u8 dialog_token,
18373 u16 status_code, u32 peer_capability,
18374 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018375#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018376static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18377 struct net_device *dev,
18378 u8 *peer, u8 action_code,
18379 u8 dialog_token,
18380 u16 status_code, const u8 *buf,
18381 size_t len)
18382#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018383#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018384{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018385 hdd_adapter_t *pAdapter;
18386 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018387 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070018388 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080018389 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070018390 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018391 int ret;
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053018392 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018393#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018394 u32 peer_capability = 0;
18395#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053018396 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018397 hdd_station_ctx_t *pHddStaCtx = NULL;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018398
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018399 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18400 if (NULL == pAdapter)
18401 {
18402 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18403 "%s: Adapter is NULL",__func__);
18404 return -EINVAL;
18405 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018406 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18407 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
18408 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018409
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018410 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018411 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018412 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018413 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018414 "Invalid arguments");
18415 return -EINVAL;
18416 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018417
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080018418 if (pHddCtx->isLogpInProgress)
18419 {
18420 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18421 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053018422 wlan_hdd_tdls_set_link_status(pAdapter,
18423 peer,
18424 eTDLS_LINK_IDLE,
18425 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080018426 return -EBUSY;
18427 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018428
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018429 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
18430 {
18431 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18432 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
18433 return -EAGAIN;
18434 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018435
Hoonki Lee27511902013-03-14 18:19:06 -070018436 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018437 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018438 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070018439 "%s: TDLS mode is disabled OR not enabled in FW."
18440 MAC_ADDRESS_STR " action %d declined.",
18441 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018442 return -ENOTSUPP;
18443 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018444
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018445 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18446
18447 if( NULL == pHddStaCtx )
18448 {
18449 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18450 "%s: HDD station context NULL ",__func__);
18451 return -EINVAL;
18452 }
18453
18454 /* STA should be connected and authenticated
18455 * before sending any TDLS frames
18456 */
18457 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
18458 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
18459 {
18460 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18461 "STA is not connected or unauthenticated. "
18462 "connState %u, uIsAuthenticated %u",
18463 pHddStaCtx->conn_info.connState,
18464 pHddStaCtx->conn_info.uIsAuthenticated);
18465 return -EAGAIN;
18466 }
18467
Hoonki Lee27511902013-03-14 18:19:06 -070018468 /* other than teardown frame, other mgmt frames are not sent if disabled */
18469 if (SIR_MAC_TDLS_TEARDOWN != action_code)
18470 {
18471 /* if tdls_mode is disabled to respond to peer's request */
18472 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
18473 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018474 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070018475 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070018476 " TDLS mode is disabled. action %d declined.",
18477 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070018478
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018479 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070018480 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053018481
18482 if (vos_max_concurrent_connections_reached())
18483 {
18484 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
18485 return -EINVAL;
18486 }
Hoonki Lee27511902013-03-14 18:19:06 -070018487 }
18488
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018489 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
18490 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053018491 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018492 {
18493 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018494 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070018495 " TDLS setup is ongoing. action %d declined.",
18496 __func__, MAC_ADDR_ARRAY(peer), action_code);
18497 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018498 }
18499 }
18500
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018501 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
18502 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080018503 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053018504 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
18505 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080018506 {
18507 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
18508 we return error code at 'add_station()'. Hence we have this
18509 check again in addtion to add_station().
18510 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018511 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080018512 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018513 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18514 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053018515 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
18516 __func__, MAC_ADDR_ARRAY(peer), action_code,
18517 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053018518 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080018519 }
18520 else
18521 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018522 /* maximum reached. tweak to send error code to peer and return
18523 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080018524 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018525 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18526 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053018527 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
18528 __func__, MAC_ADDR_ARRAY(peer), status_code,
18529 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070018530 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018531 /* fall through to send setup resp with failure status
18532 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080018533 }
18534 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018535 else
18536 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018537 mutex_lock(&pHddCtx->tdls_lock);
18538 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018539 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018540 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018541 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018542 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070018543 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
18544 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018545 return -EPERM;
18546 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018547 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018548 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018549 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018550
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018551 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053018552 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018553 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
18554 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018555
Hoonki Leea34dd892013-02-05 22:56:02 -080018556 /*Except teardown responder will not be used so just make 0*/
18557 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018558 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080018559 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070018560
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018561 mutex_lock(&pHddCtx->tdls_lock);
18562 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070018563
18564 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
18565 responder = pTdlsPeer->is_responder;
18566 else
Hoonki Leea34dd892013-02-05 22:56:02 -080018567 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070018568 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053018569 "%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 -070018570 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
18571 dialog_token, status_code, len);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018572 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070018573 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080018574 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018575 mutex_unlock(&pHddCtx->tdls_lock);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018576 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018577
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053018578 /* Discard TDLS setup if peer is removed by user app */
18579 if ((pHddCtx->cfg_ini->fTDLSExternalControl) &&
18580 ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
18581 (SIR_MAC_TDLS_SETUP_CNF == action_code) ||
18582 (SIR_MAC_TDLS_DIS_REQ == action_code))) {
18583
18584 mutex_lock(&pHddCtx->tdls_lock);
18585 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18586 if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) {
18587 mutex_unlock(&pHddCtx->tdls_lock);
18588 hddLog(LOGE, FL("TDLS External Control enabled, but peer "
18589 MAC_ADDRESS_STR " is not forced, so reject the action code %d"),
18590 MAC_ADDR_ARRAY(peer), action_code);
18591 return -EINVAL;
18592 }
18593 mutex_unlock(&pHddCtx->tdls_lock);
18594 }
18595
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053018596 /* For explicit trigger of DIS_REQ come out of BMPS for
18597 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070018598 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Deepthi Gowrif78f1f72016-03-21 13:13:28 +053018599 (SIR_MAC_TDLS_SETUP_CNF== action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053018600 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
18601 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070018602 {
18603 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
18604 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018605 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053018606 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018607 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
18608 if (status != VOS_STATUS_SUCCESS) {
18609 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
18610 }
Hoonki Lee14621352013-04-16 17:51:19 -070018611 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018612 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018613 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018614 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
18615 }
18616 }
Hoonki Lee14621352013-04-16 17:51:19 -070018617 }
18618
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018619 /* make sure doesn't call send_mgmt() while it is pending */
18620 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
18621 {
18622 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080018623 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018624 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018625 ret = -EBUSY;
18626 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018627 }
18628
18629 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018630 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
18631
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018632 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
18633 pAdapter->sessionId, peer, action_code, dialog_token,
18634 status_code, peer_capability, (tANI_U8 *)buf, len,
18635 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018636
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018637 if (VOS_STATUS_SUCCESS != status)
18638 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018639 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18640 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018641 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018642 ret = -EINVAL;
18643 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018644 }
18645
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018646 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18647 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
18648 WAIT_TIME_TDLS_MGMT);
18649
Hoonki Leed37cbb32013-04-20 00:31:14 -070018650 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
18651 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
18652
18653 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018654 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070018655 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070018656 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070018657 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018658 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080018659
18660 if (pHddCtx->isLogpInProgress)
18661 {
18662 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18663 "%s: LOGP in Progress. Ignore!!!", __func__);
18664 return -EAGAIN;
18665 }
Abhishek Singh837adf22015-10-01 17:37:37 +053018666 if (rc <= 0)
18667 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
18668 WLAN_LOG_INDICATOR_HOST_DRIVER,
18669 WLAN_LOG_REASON_HDD_TIME_OUT,
18670 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080018671
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018672 ret = -EINVAL;
18673 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018674 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018675 else
18676 {
18677 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18678 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
18679 __func__, rc, pAdapter->mgmtTxCompletionStatus);
18680 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018681
Gopichand Nakkala05922802013-03-14 12:23:19 -070018682 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070018683 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018684 ret = max_sta_failed;
18685 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070018686 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018687
Hoonki Leea34dd892013-02-05 22:56:02 -080018688 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
18689 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018690 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018691 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
18692 }
Hoonki Leea34dd892013-02-05 22:56:02 -080018693 }
18694 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
18695 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018696 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018697 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
18698 }
Hoonki Leea34dd892013-02-05 22:56:02 -080018699 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018700
18701 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018702
18703tx_failed:
18704 /* add_station will be called before sending TDLS_SETUP_REQ and
18705 * TDLS_SETUP_RSP and as part of add_station driver will enable
18706 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
18707 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
18708 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
18709 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
18710 */
18711
18712 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
18713 (SIR_MAC_TDLS_SETUP_RSP == action_code))
18714 wlan_hdd_tdls_check_bmps(pAdapter);
18715 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018716}
18717
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018718#if TDLS_MGMT_VERSION2
18719static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
18720 u8 *peer, u8 action_code, u8 dialog_token,
18721 u16 status_code, u32 peer_capability,
18722 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018723#else /* TDLS_MGMT_VERSION2 */
18724#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
18725static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18726 struct net_device *dev,
18727 const u8 *peer, u8 action_code,
18728 u8 dialog_token, u16 status_code,
18729 u32 peer_capability, bool initiator,
18730 const u8 *buf, size_t len)
18731#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18732static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18733 struct net_device *dev,
18734 const u8 *peer, u8 action_code,
18735 u8 dialog_token, u16 status_code,
18736 u32 peer_capability, const u8 *buf,
18737 size_t len)
18738#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
18739static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18740 struct net_device *dev,
18741 u8 *peer, u8 action_code,
18742 u8 dialog_token,
18743 u16 status_code, u32 peer_capability,
18744 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018745#else
18746static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
18747 u8 *peer, u8 action_code, u8 dialog_token,
18748 u16 status_code, const u8 *buf, size_t len)
18749#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018750#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018751{
18752 int ret;
18753
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018754 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018755#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018756 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
18757 dialog_token, status_code,
18758 peer_capability, buf, len);
18759#else /* TDLS_MGMT_VERSION2 */
18760#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
18761 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
18762 dialog_token, status_code,
18763 peer_capability, initiator,
18764 buf, len);
18765#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
18766 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
18767 dialog_token, status_code,
18768 peer_capability, buf, len);
18769#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
18770 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
18771 dialog_token, status_code,
18772 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018773#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018774 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
18775 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018776#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018777#endif
18778 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018779
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018780 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018781}
Atul Mittal115287b2014-07-08 13:26:33 +053018782
18783int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018784#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18785 const u8 *peer,
18786#else
Atul Mittal115287b2014-07-08 13:26:33 +053018787 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018788#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018789 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053018790 cfg80211_exttdls_callback callback)
18791{
18792
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018793 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053018794 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053018795 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053018796 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18797 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
18798 __func__, MAC_ADDR_ARRAY(peer));
18799
18800 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
18801 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
18802
18803 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018804 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
18805 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
18806 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053018807 return -ENOTSUPP;
18808 }
18809
18810 /* To cater the requirement of establishing the TDLS link
18811 * irrespective of the data traffic , get an entry of TDLS peer.
18812 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053018813 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053018814 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
18815 if (pTdlsPeer == NULL) {
18816 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18817 "%s: peer " MAC_ADDRESS_STR " not existing",
18818 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053018819 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053018820 return -EINVAL;
18821 }
18822
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053018823 /* check FW TDLS Off Channel capability */
18824 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053018825 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053018826 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018827 {
18828 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
18829 pTdlsPeer->peerParams.global_operating_class =
18830 tdls_peer_params->global_operating_class;
18831 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
18832 pTdlsPeer->peerParams.min_bandwidth_kbps =
18833 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053018834 /* check configured channel is valid, non dfs and
18835 * not current operating channel */
18836 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
18837 tdls_peer_params->channel)) &&
18838 (pHddStaCtx) &&
18839 (tdls_peer_params->channel !=
18840 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018841 {
18842 pTdlsPeer->isOffChannelConfigured = TRUE;
18843 }
18844 else
18845 {
18846 pTdlsPeer->isOffChannelConfigured = FALSE;
18847 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18848 "%s: Configured Tdls Off Channel is not valid", __func__);
18849
18850 }
18851 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053018852 "%s: tdls_off_channel %d isOffChannelConfigured %d "
18853 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018854 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053018855 pTdlsPeer->isOffChannelConfigured,
18856 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018857 }
18858 else
18859 {
18860 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053018861 "%s: TDLS off channel FW capability %d, "
18862 "host capab %d or Invalid TDLS Peer Params", __func__,
18863 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
18864 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018865 }
18866
Atul Mittal115287b2014-07-08 13:26:33 +053018867 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
18868
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018869 mutex_unlock(&pHddCtx->tdls_lock);
18870
Atul Mittal115287b2014-07-08 13:26:33 +053018871 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18872 " %s TDLS Add Force Peer Failed",
18873 __func__);
18874 return -EINVAL;
18875 }
18876 /*EXT TDLS*/
18877
18878 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018879 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053018880 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18881 " %s TDLS set callback Failed",
18882 __func__);
18883 return -EINVAL;
18884 }
18885
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018886 mutex_unlock(&pHddCtx->tdls_lock);
18887
Atul Mittal115287b2014-07-08 13:26:33 +053018888 return(0);
18889
18890}
18891
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018892int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
18893#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18894 const u8 *peer
18895#else
18896 u8 *peer
18897#endif
18898)
Atul Mittal115287b2014-07-08 13:26:33 +053018899{
18900
18901 hddTdlsPeer_t *pTdlsPeer;
18902 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053018903
Atul Mittal115287b2014-07-08 13:26:33 +053018904 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18905 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
18906 __func__, MAC_ADDR_ARRAY(peer));
18907
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053018908 if (0 != wlan_hdd_validate_context(pHddCtx)) {
18909 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
18910 return -EINVAL;
18911 }
18912
Atul Mittal115287b2014-07-08 13:26:33 +053018913 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
18914 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
18915
18916 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018917 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
18918 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
18919 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053018920 return -ENOTSUPP;
18921 }
18922
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018923 mutex_lock(&pHddCtx->tdls_lock);
18924 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Atul Mittal115287b2014-07-08 13:26:33 +053018925
18926 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018927 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053018928 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018929 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053018930 __func__, MAC_ADDR_ARRAY(peer));
18931 return -EINVAL;
18932 }
18933 else {
18934 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
18935 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053018936 hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_EXT_CTRL,
18937 pTdlsPeer->peerMac);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018938 /* if channel switch is configured, reset
18939 the channel for this peer */
18940 if (TRUE == pTdlsPeer->isOffChannelConfigured)
18941 {
18942 pTdlsPeer->peerParams.channel = 0;
18943 pTdlsPeer->isOffChannelConfigured = FALSE;
18944 }
Atul Mittal115287b2014-07-08 13:26:33 +053018945 }
18946
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018947 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018948 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018949 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053018950 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018951 }
Atul Mittal115287b2014-07-08 13:26:33 +053018952
18953 /*EXT TDLS*/
18954
18955 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018956 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053018957 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18958 " %s TDLS set callback Failed",
18959 __func__);
18960 return -EINVAL;
18961 }
Atul Mittal115287b2014-07-08 13:26:33 +053018962
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018963 mutex_unlock(&pHddCtx->tdls_lock);
18964
18965 return(0);
Atul Mittal115287b2014-07-08 13:26:33 +053018966}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018967static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018968#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18969 const u8 *peer,
18970#else
18971 u8 *peer,
18972#endif
18973 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018974{
18975 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18976 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018977 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018978 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018979
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018980 ENTER();
18981
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053018982 if (!pAdapter) {
18983 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
18984 return -EINVAL;
18985 }
18986
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018987 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18988 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
18989 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018990 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018991 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018992 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070018993 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018994 return -EINVAL;
18995 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080018996
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018997 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018998 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080018999 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019000 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080019001 }
19002
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019003
19004 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080019005 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019006 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080019007 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019008 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
19009 "Cannot process TDLS commands",
19010 pHddCtx->cfg_ini->fEnableTDLSSupport,
19011 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019012 return -ENOTSUPP;
19013 }
19014
19015 switch (oper) {
19016 case NL80211_TDLS_ENABLE_LINK:
19017 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019018 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019019 long ret;
Hanumantha Reddy Pothulada389492016-02-11 17:29:27 +053019020 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams = { {0}, 0,
19021 0, 0, 0, 0, 0, 0, {0}, 0, {0} };
Agarwal Ashish16020c42014-12-29 22:01:11 +053019022 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019023 tANI_U16 numCurrTdlsPeers = 0;
19024 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053019025 tANI_U8 suppChannelLen = 0;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019026 tSirMacAddr peerMac;
19027 int channel;
19028 tTDLSLinkStatus peer_status = eTDLS_LINK_IDLE;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019029
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019030 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19031 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
19032 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019033
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019034 mutex_lock(&pHddCtx->tdls_lock);
19035 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053019036 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053019037 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019038 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053019039 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
19040 " (oper %d) not exsting. ignored",
19041 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
19042 return -EINVAL;
19043 }
19044
19045 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19046 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
19047 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
19048 "NL80211_TDLS_ENABLE_LINK");
19049
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070019050 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
19051 {
19052 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
19053 MAC_ADDRESS_STR " failed",
19054 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019055 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070019056 return -EINVAL;
19057 }
19058
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053019059 /* before starting tdls connection, set tdls
19060 * off channel established status to default value */
19061 pTdlsPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019062
19063 mutex_unlock(&pHddCtx->tdls_lock);
19064
Deepthi Gowri2d85bbf2016-07-25 15:43:31 +053019065 wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019066 /* TDLS Off Channel, Disable tdls channel switch,
19067 when there are more than one tdls link */
19068 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053019069 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019070 {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019071 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019072 /* get connected peer and send disable tdls off chan */
19073 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019074 if ((connPeer) &&
19075 (connPeer->isOffChannelSupported == TRUE) &&
19076 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019077 {
19078 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19079 "%s: More then one peer connected, Disable "
19080 "TDLS channel switch", __func__);
19081
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053019082 connPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019083 vos_mem_copy(peerMac, connPeer->peerMac, sizeof (tSirMacAddr));
19084 channel = connPeer->peerParams.channel;
19085
19086 mutex_unlock(&pHddCtx->tdls_lock);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019087
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019088 ret = sme_SendTdlsChanSwitchReq(
19089 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019090 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019091 peerMac,
19092 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019093 TDLS_OFF_CHANNEL_BW_OFFSET,
19094 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019095 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019096 hddLog(VOS_TRACE_LEVEL_ERROR,
19097 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019098 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019099 }
19100 else
19101 {
19102 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19103 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019104 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019105 "isOffChannelConfigured %d",
19106 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019107 (connPeer ? (connPeer->isOffChannelSupported)
19108 : -1),
19109 (connPeer ? (connPeer->isOffChannelConfigured)
19110 : -1));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019111 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019112 }
19113 }
19114
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019115 mutex_lock(&pHddCtx->tdls_lock);
19116 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
19117 if ( NULL == pTdlsPeer ) {
19118 mutex_unlock(&pHddCtx->tdls_lock);
19119 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19120 "%s: " MAC_ADDRESS_STR
19121 " (oper %d) peer got freed in other context. ignored",
19122 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
19123 return -EINVAL;
19124 }
19125 peer_status = pTdlsPeer->link_status;
19126 mutex_unlock(&pHddCtx->tdls_lock);
19127
19128 if (eTDLS_LINK_CONNECTED != peer_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019129 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019130 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053019131
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019132 if (0 != wlan_hdd_tdls_get_link_establish_params(
19133 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019134 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019135 return -EINVAL;
19136 }
19137 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053019138
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019139 ret = sme_SendTdlsLinkEstablishParams(
19140 WLAN_HDD_GET_HAL_CTX(pAdapter),
19141 pAdapter->sessionId, peer,
19142 &tdlsLinkEstablishParams);
19143 if (ret != VOS_STATUS_SUCCESS) {
19144 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
19145 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019146 /* Send TDLS peer UAPSD capabilities to the firmware and
19147 * register with the TL on after the response for this operation
19148 * is received .
19149 */
19150 ret = wait_for_completion_interruptible_timeout(
19151 &pAdapter->tdls_link_establish_req_comp,
19152 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
Masti, Narayanraddie1892a52015-12-15 15:01:01 +053019153
19154 mutex_lock(&pHddCtx->tdls_lock);
19155 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
19156 if ( NULL == pTdlsPeer ) {
19157 mutex_unlock(&pHddCtx->tdls_lock);
19158 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19159 "%s %d: " MAC_ADDRESS_STR
19160 " (oper %d) peer got freed in other context. ignored",
19161 __func__, __LINE__, MAC_ADDR_ARRAY(peer),
19162 (int)oper);
19163 return -EINVAL;
19164 }
19165 peer_status = pTdlsPeer->link_status;
19166 mutex_unlock(&pHddCtx->tdls_lock);
19167
19168 if (ret <= 0 || (peer_status == eTDLS_LINK_TEARING))
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019169 {
19170 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019171 FL("Link Establish Request Failed Status %ld"),
19172 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019173 return -EINVAL;
19174 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053019175 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019176
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019177 mutex_lock(&pHddCtx->tdls_lock);
19178 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
19179 if ( NULL == pTdlsPeer ) {
19180 mutex_unlock(&pHddCtx->tdls_lock);
19181 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19182 "%s: " MAC_ADDRESS_STR
19183 " (oper %d) peer got freed in other context. ignored",
19184 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
19185 return -EINVAL;
19186 }
19187
Atul Mittal115287b2014-07-08 13:26:33 +053019188 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
19189 eTDLS_LINK_CONNECTED,
19190 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053019191 staDesc.ucSTAId = pTdlsPeer->staId;
19192 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053019193
19194 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19195 "%s: tdlsLinkEstablishParams of peer "
19196 MAC_ADDRESS_STR "uapsdQueues: %d"
19197 "qos: %d maxSp: %d isBufSta: %d isOffChannelSupported: %d"
19198 "isResponder: %d peerstaId: %d",
19199 __func__,
19200 MAC_ADDR_ARRAY(tdlsLinkEstablishParams.peerMac),
19201 tdlsLinkEstablishParams.uapsdQueues,
19202 tdlsLinkEstablishParams.qos,
19203 tdlsLinkEstablishParams.maxSp,
19204 tdlsLinkEstablishParams.isBufSta,
19205 tdlsLinkEstablishParams.isOffChannelSupported,
19206 tdlsLinkEstablishParams.isResponder,
19207 pTdlsPeer->staId);
19208
19209 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19210 "%s: StaDesc ucSTAId: %d ucQosEnabled: %d",
19211 __func__,
19212 staDesc.ucSTAId,
19213 staDesc.ucQosEnabled);
19214
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019215 ret = WLANTL_UpdateTdlsSTAClient(
19216 pHddCtx->pvosContext,
19217 &staDesc);
19218 if (ret != VOS_STATUS_SUCCESS) {
19219 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
19220 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053019221
Gopichand Nakkala471708b2013-06-04 20:03:01 +053019222 /* Mark TDLS client Authenticated .*/
19223 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
19224 pTdlsPeer->staId,
19225 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070019226 if (VOS_STATUS_SUCCESS == status)
19227 {
Hoonki Lee14621352013-04-16 17:51:19 -070019228 if (pTdlsPeer->is_responder == 0)
19229 {
19230 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053019231 tdlsConnInfo_t *tdlsInfo;
19232
19233 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
19234
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053019235 if (!vos_timer_is_initialized(
19236 &pTdlsPeer->initiatorWaitTimeoutTimer))
19237 {
19238 /* Initialize initiator wait callback */
19239 vos_timer_init(
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053019240 &pTdlsPeer->initiatorWaitTimeoutTimer,
19241 VOS_TIMER_TYPE_SW,
19242 wlan_hdd_tdls_initiator_wait_cb,
19243 tdlsInfo);
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053019244 }
Hoonki Lee14621352013-04-16 17:51:19 -070019245 wlan_hdd_tdls_timer_restart(pAdapter,
19246 &pTdlsPeer->initiatorWaitTimeoutTimer,
19247 WAIT_TIME_TDLS_INITIATOR);
19248 /* suspend initiator TX until it receives direct packet from the
19249 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019250 ret = WLANTL_SuspendDataTx(
19251 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
19252 &staId, NULL);
19253 if (ret != VOS_STATUS_SUCCESS) {
19254 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
19255 }
Hoonki Lee14621352013-04-16 17:51:19 -070019256 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019257
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053019258 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019259 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053019260 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019261 suppChannelLen =
19262 tdlsLinkEstablishParams.supportedChannelsLen;
19263
19264 if ((suppChannelLen > 0) &&
19265 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
19266 {
19267 tANI_U8 suppPeerChannel = 0;
19268 int i = 0;
19269 for (i = 0U; i < suppChannelLen; i++)
19270 {
19271 suppPeerChannel =
19272 tdlsLinkEstablishParams.supportedChannels[i];
19273
19274 pTdlsPeer->isOffChannelSupported = FALSE;
19275 if (suppPeerChannel ==
19276 pTdlsPeer->peerParams.channel)
19277 {
19278 pTdlsPeer->isOffChannelSupported = TRUE;
19279 break;
19280 }
19281 }
19282 }
19283 else
19284 {
19285 pTdlsPeer->isOffChannelSupported = FALSE;
19286 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053019287 }
19288 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19289 "%s: TDLS channel switch request for channel "
19290 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019291 "%d isOffChannelSupported %d", __func__,
19292 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053019293 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019294 suppChannelLen,
19295 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053019296
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019297 /* TDLS Off Channel, Enable tdls channel switch,
19298 when their is only one tdls link and it supports */
19299 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
19300 if ((numCurrTdlsPeers == 1) &&
19301 (TRUE == pTdlsPeer->isOffChannelSupported) &&
19302 (TRUE == pTdlsPeer->isOffChannelConfigured))
19303 {
19304 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19305 "%s: Send TDLS channel switch request for channel %d",
19306 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053019307
19308 pTdlsPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019309 vos_mem_copy(peerMac, pTdlsPeer->peerMac, sizeof (tSirMacAddr));
19310 channel = pTdlsPeer->peerParams.channel;
19311
19312 mutex_unlock(&pHddCtx->tdls_lock);
19313
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019314 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
19315 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019316 peerMac,
19317 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019318 TDLS_OFF_CHANNEL_BW_OFFSET,
19319 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019320 if (ret != VOS_STATUS_SUCCESS) {
19321 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
19322 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019323 }
19324 else
19325 {
19326 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19327 "%s: TDLS channel switch request not sent"
19328 " numCurrTdlsPeers %d "
19329 "isOffChannelSupported %d "
19330 "isOffChannelConfigured %d",
19331 __func__, numCurrTdlsPeers,
19332 pTdlsPeer->isOffChannelSupported,
19333 pTdlsPeer->isOffChannelConfigured);
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019334 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019335 }
19336
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070019337 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019338 else
19339 mutex_unlock(&pHddCtx->tdls_lock);
19340
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019341 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053019342
19343 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053019344 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
19345 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053019346 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053019347 int ac;
19348 uint8 ucAc[4] = { WLANTL_AC_VO,
19349 WLANTL_AC_VI,
19350 WLANTL_AC_BK,
19351 WLANTL_AC_BE };
19352 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
19353 for(ac=0; ac < 4; ac++)
19354 {
19355 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
19356 pTdlsPeer->staId, ucAc[ac],
19357 tlTid[ac], tlTid[ac], 0, 0,
19358 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019359 if (status != VOS_STATUS_SUCCESS) {
19360 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
19361 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053019362 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053019363 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019364 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019365
Bhargav Shah66896792015-10-01 18:17:37 +053019366 /* stop TCP delack timer if TDLS is enable */
19367 set_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
19368 hdd_manage_delack_timer(pHddCtx);
Abhishek Singh67fa6bc2016-01-05 15:57:19 +053019369 hdd_wlan_tdls_enable_link_event(peer,
19370 pTdlsPeer->isOffChannelSupported,
19371 pTdlsPeer->isOffChannelConfigured,
19372 pTdlsPeer->isOffChannelEstablished);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019373 }
19374 break;
19375 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080019376 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019377 tANI_U16 numCurrTdlsPeers = 0;
19378 hddTdlsPeer_t *connPeer = NULL;
19379
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019380 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19381 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
19382 __func__, MAC_ADDR_ARRAY(peer));
19383
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019384 mutex_lock(&pHddCtx->tdls_lock);
19385 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Sunil Dutt41de4e22013-11-14 18:09:02 +053019386
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019387
Sunil Dutt41de4e22013-11-14 18:09:02 +053019388 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019389 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053019390 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
19391 " (oper %d) not exsting. ignored",
19392 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
19393 return -EINVAL;
19394 }
19395
19396 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19397 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
19398 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
19399 "NL80211_TDLS_DISABLE_LINK");
19400
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019401 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080019402 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019403 long status;
19404
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053019405 /* set tdls off channel status to false for this peer */
19406 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053019407 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
19408 eTDLS_LINK_TEARING,
19409 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
19410 eTDLS_LINK_UNSPECIFIED:
19411 eTDLS_LINK_DROPPED_BY_REMOTE);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019412 mutex_unlock(&pHddCtx->tdls_lock);
19413
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019414 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
19415
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019416 status = sme_DeleteTdlsPeerSta(
19417 WLAN_HDD_GET_HAL_CTX(pAdapter),
19418 pAdapter->sessionId, peer );
19419 if (status != VOS_STATUS_SUCCESS) {
19420 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
19421 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019422
19423 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
19424 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019425
19426 mutex_lock(&pHddCtx->tdls_lock);
19427 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
19428 if ( NULL == pTdlsPeer ) {
19429 mutex_unlock(&pHddCtx->tdls_lock);
19430 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
19431 " peer was freed in other context",
19432 __func__, MAC_ADDR_ARRAY(peer));
19433 return -EINVAL;
19434 }
19435
Atul Mittal271a7652014-09-12 13:18:22 +053019436 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053019437 eTDLS_LINK_IDLE,
19438 eTDLS_LINK_UNSPECIFIED);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019439 mutex_unlock(&pHddCtx->tdls_lock);
19440
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019441 if (status <= 0)
19442 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019443 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19444 "%s: Del station failed status %ld",
19445 __func__, status);
19446 return -EPERM;
19447 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019448
19449 /* TDLS Off Channel, Enable tdls channel switch,
19450 when their is only one tdls link and it supports */
19451 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
19452 if (numCurrTdlsPeers == 1)
19453 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019454 tSirMacAddr peerMac;
19455 int channel;
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053019456
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019457 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019458 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053019459
19460 if (connPeer == NULL) {
19461 mutex_unlock(&pHddCtx->tdls_lock);
19462 hddLog(VOS_TRACE_LEVEL_ERROR,
19463 "%s connPeer is NULL", __func__);
19464 return -EINVAL;
19465 }
19466
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019467 vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr));
19468 channel = connPeer->peerParams.channel;
19469
19470 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19471 "%s: TDLS channel switch "
19472 "isOffChannelSupported %d "
19473 "isOffChannelConfigured %d "
19474 "isOffChannelEstablished %d",
19475 __func__,
19476 (connPeer ? connPeer->isOffChannelSupported : -1),
19477 (connPeer ? connPeer->isOffChannelConfigured : -1),
19478 (connPeer ? connPeer->isOffChannelEstablished : -1));
19479
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019480 if ((connPeer) &&
19481 (connPeer->isOffChannelSupported == TRUE) &&
19482 (connPeer->isOffChannelConfigured == TRUE))
19483 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053019484 connPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019485 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019486 status = sme_SendTdlsChanSwitchReq(
19487 WLAN_HDD_GET_HAL_CTX(pAdapter),
19488 pAdapter->sessionId,
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019489 peerMac,
19490 channel,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019491 TDLS_OFF_CHANNEL_BW_OFFSET,
19492 TDLS_CHANNEL_SWITCH_ENABLE);
19493 if (status != VOS_STATUS_SUCCESS) {
19494 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
19495 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019496 }
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019497 else
19498 mutex_unlock(&pHddCtx->tdls_lock);
19499 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019500 else
19501 {
19502 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19503 "%s: TDLS channel switch request not sent "
19504 "numCurrTdlsPeers %d ",
19505 __func__, numCurrTdlsPeers);
19506 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080019507 }
19508 else
19509 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019510 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019511 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19512 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080019513 }
Bhargav Shah66896792015-10-01 18:17:37 +053019514 if (numCurrTdlsPeers == 0) {
19515 /* start TCP delack timer if TDLS is disable */
19516 clear_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
19517 hdd_manage_delack_timer(pHddCtx);
19518 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080019519 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019520 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019521 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053019522 {
Atul Mittal115287b2014-07-08 13:26:33 +053019523 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053019524
Atul Mittal115287b2014-07-08 13:26:33 +053019525 if (0 != status)
19526 {
19527 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019528 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053019529 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053019530 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053019531 break;
19532 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019533 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053019534 {
Atul Mittal115287b2014-07-08 13:26:33 +053019535 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
19536 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019537 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053019538 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053019539
Atul Mittal115287b2014-07-08 13:26:33 +053019540 if (0 != status)
19541 {
19542 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019543 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053019544 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053019545 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053019546 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053019547 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019548 case NL80211_TDLS_DISCOVERY_REQ:
19549 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019550 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019551 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019552 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019553 return -ENOTSUPP;
19554 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019555 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19556 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019557 return -ENOTSUPP;
19558 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019559
19560 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019561 return 0;
19562}
Chilam NG571c65a2013-01-19 12:27:36 +053019563
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019564static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019565#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19566 const u8 *peer,
19567#else
19568 u8 *peer,
19569#endif
19570 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019571{
19572 int ret;
19573
19574 vos_ssr_protect(__func__);
19575 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
19576 vos_ssr_unprotect(__func__);
19577
19578 return ret;
19579}
19580
Chilam NG571c65a2013-01-19 12:27:36 +053019581int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
19582 struct net_device *dev, u8 *peer)
19583{
Arif Hussaina7c8e412013-11-20 11:06:42 -080019584 hddLog(VOS_TRACE_LEVEL_INFO,
19585 "tdls send discover req: "MAC_ADDRESS_STR,
19586 MAC_ADDR_ARRAY(peer));
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019587#if TDLS_MGMT_VERSION2
19588 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19589 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
19590#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019591#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
19592 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19593 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
19594#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
19595 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19596 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
19597#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
19598 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19599 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
19600#else
Chilam NG571c65a2013-01-19 12:27:36 +053019601 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19602 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019603#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019604#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053019605}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019606#endif
19607
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019608#ifdef WLAN_FEATURE_GTK_OFFLOAD
19609/*
19610 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
19611 * Callback rountine called upon receiving response for
19612 * get offload info
19613 */
19614void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
19615 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
19616{
19617
19618 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019619 tANI_U8 tempReplayCounter[8];
19620 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019621
19622 ENTER();
19623
19624 if (NULL == pAdapter)
19625 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053019626 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019627 "%s: HDD adapter is Null", __func__);
19628 return ;
19629 }
19630
19631 if (NULL == pGtkOffloadGetInfoRsp)
19632 {
19633 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19634 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
19635 return ;
19636 }
19637
19638 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
19639 {
19640 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19641 "%s: wlan Failed to get replay counter value",
19642 __func__);
19643 return ;
19644 }
19645
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019646 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
19647 /* Update replay counter */
19648 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
19649 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
19650
19651 {
19652 /* changing from little to big endian since supplicant
19653 * works on big endian format
19654 */
19655 int i;
19656 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
19657
19658 for (i = 0; i < 8; i++)
19659 {
19660 tempReplayCounter[7-i] = (tANI_U8)p[i];
19661 }
19662 }
19663
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019664 /* Update replay counter to NL */
19665 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019666 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019667}
19668
19669/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019670 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019671 * This function is used to offload GTK rekeying job to the firmware.
19672 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019673int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019674 struct cfg80211_gtk_rekey_data *data)
19675{
19676 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19677 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
19678 hdd_station_ctx_t *pHddStaCtx;
19679 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019680 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019681 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019682 eHalStatus status = eHAL_STATUS_FAILURE;
19683
19684 ENTER();
19685
19686 if (NULL == pAdapter)
19687 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019688 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019689 "%s: HDD adapter is Null", __func__);
19690 return -ENODEV;
19691 }
19692
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019693 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19694 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
19695 pAdapter->sessionId, pAdapter->device_mode));
19696
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019697 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019698 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019699 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019700 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019701 }
19702
19703 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
19704 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
19705 if (NULL == hHal)
19706 {
19707 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19708 "%s: HAL context is Null!!!", __func__);
19709 return -EAGAIN;
19710 }
19711
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019712 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
19713 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
19714 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
19715 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019716 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019717 {
19718 /* changing from big to little endian since driver
19719 * works on little endian format
19720 */
19721 tANI_U8 *p =
19722 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
19723 int i;
19724
19725 for (i = 0; i < 8; i++)
19726 {
19727 p[7-i] = data->replay_ctr[i];
19728 }
19729 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019730
19731 if (TRUE == pHddCtx->hdd_wlan_suspended)
19732 {
19733 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019734 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
19735 sizeof (tSirGtkOffloadParams));
19736 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019737 pAdapter->sessionId);
19738
19739 if (eHAL_STATUS_SUCCESS != status)
19740 {
19741 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19742 "%s: sme_SetGTKOffload failed, returned %d",
19743 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053019744
19745 /* Need to clear any trace of key value in the memory.
19746 * Thus zero out the memory even though it is local
19747 * variable.
19748 */
19749 vos_mem_zero(&hddGtkOffloadReqParams,
19750 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019751 return status;
19752 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019753 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19754 "%s: sme_SetGTKOffload successfull", __func__);
19755 }
19756 else
19757 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019758 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19759 "%s: wlan not suspended GTKOffload request is stored",
19760 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019761 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019762
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053019763 /* Need to clear any trace of key value in the memory.
19764 * Thus zero out the memory even though it is local
19765 * variable.
19766 */
19767 vos_mem_zero(&hddGtkOffloadReqParams,
19768 sizeof(hddGtkOffloadReqParams));
19769
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019770 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019771 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019772}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019773
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019774int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
19775 struct cfg80211_gtk_rekey_data *data)
19776{
19777 int ret;
19778
19779 vos_ssr_protect(__func__);
19780 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
19781 vos_ssr_unprotect(__func__);
19782
19783 return ret;
19784}
19785#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019786/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019787 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019788 * This function is used to set access control policy
19789 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019790static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
19791 struct net_device *dev,
19792 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019793{
19794 int i;
19795 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19796 hdd_hostapd_state_t *pHostapdState;
19797 tsap_Config_t *pConfig;
19798 v_CONTEXT_t pVosContext = NULL;
19799 hdd_context_t *pHddCtx;
19800 int status;
19801
19802 ENTER();
19803
19804 if (NULL == pAdapter)
19805 {
19806 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19807 "%s: HDD adapter is Null", __func__);
19808 return -ENODEV;
19809 }
19810
19811 if (NULL == params)
19812 {
19813 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19814 "%s: params is Null", __func__);
19815 return -EINVAL;
19816 }
19817
19818 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19819 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019820 if (0 != status)
19821 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019822 return status;
19823 }
19824
19825 pVosContext = pHddCtx->pvosContext;
19826 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
19827
19828 if (NULL == pHostapdState)
19829 {
19830 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19831 "%s: pHostapdState is Null", __func__);
19832 return -EINVAL;
19833 }
19834
19835 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
19836 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019837 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19838 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
19839 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019840
19841 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
19842 {
19843 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
19844
19845 /* default value */
19846 pConfig->num_accept_mac = 0;
19847 pConfig->num_deny_mac = 0;
19848
19849 /**
19850 * access control policy
19851 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
19852 * listed in hostapd.deny file.
19853 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
19854 * listed in hostapd.accept file.
19855 */
19856 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
19857 {
19858 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
19859 }
19860 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
19861 {
19862 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
19863 }
19864 else
19865 {
19866 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19867 "%s:Acl Policy : %d is not supported",
19868 __func__, params->acl_policy);
19869 return -ENOTSUPP;
19870 }
19871
19872 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
19873 {
19874 pConfig->num_accept_mac = params->n_acl_entries;
19875 for (i = 0; i < params->n_acl_entries; i++)
19876 {
19877 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19878 "** Add ACL MAC entry %i in WhiletList :"
19879 MAC_ADDRESS_STR, i,
19880 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
19881
19882 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
19883 sizeof(qcmacaddr));
19884 }
19885 }
19886 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
19887 {
19888 pConfig->num_deny_mac = params->n_acl_entries;
19889 for (i = 0; i < params->n_acl_entries; i++)
19890 {
19891 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19892 "** Add ACL MAC entry %i in BlackList :"
19893 MAC_ADDRESS_STR, i,
19894 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
19895
19896 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
19897 sizeof(qcmacaddr));
19898 }
19899 }
19900
19901 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
19902 {
19903 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19904 "%s: SAP Set Mac Acl fail", __func__);
19905 return -EINVAL;
19906 }
19907 }
19908 else
19909 {
19910 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053019911 "%s: Invalid device_mode = %s (%d)",
19912 __func__, hdd_device_modetoString(pAdapter->device_mode),
19913 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019914 return -EINVAL;
19915 }
19916
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019917 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019918 return 0;
19919}
19920
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019921static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
19922 struct net_device *dev,
19923 const struct cfg80211_acl_data *params)
19924{
19925 int ret;
19926 vos_ssr_protect(__func__);
19927 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
19928 vos_ssr_unprotect(__func__);
19929
19930 return ret;
19931}
19932
Leo Chang9056f462013-08-01 19:21:11 -070019933#ifdef WLAN_NL80211_TESTMODE
19934#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070019935void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070019936(
19937 void *pAdapter,
19938 void *indCont
19939)
19940{
Leo Changd9df8aa2013-09-26 13:32:26 -070019941 tSirLPHBInd *lphbInd;
19942 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053019943 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070019944
19945 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070019946 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070019947
c_hpothu73f35e62014-04-18 13:40:08 +053019948 if (pAdapter == NULL)
19949 {
19950 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19951 "%s: pAdapter is NULL\n",__func__);
19952 return;
19953 }
19954
Leo Chang9056f462013-08-01 19:21:11 -070019955 if (NULL == indCont)
19956 {
19957 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070019958 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070019959 return;
19960 }
19961
c_hpothu73f35e62014-04-18 13:40:08 +053019962 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070019963 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070019964 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053019965 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070019966 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070019967 GFP_ATOMIC);
19968 if (!skb)
19969 {
19970 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19971 "LPHB timeout, NL buffer alloc fail");
19972 return;
19973 }
19974
Leo Changac3ba772013-10-07 09:47:04 -070019975 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070019976 {
19977 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19978 "WLAN_HDD_TM_ATTR_CMD put fail");
19979 goto nla_put_failure;
19980 }
Leo Changac3ba772013-10-07 09:47:04 -070019981 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070019982 {
19983 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19984 "WLAN_HDD_TM_ATTR_TYPE put fail");
19985 goto nla_put_failure;
19986 }
Leo Changac3ba772013-10-07 09:47:04 -070019987 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070019988 sizeof(tSirLPHBInd), lphbInd))
19989 {
19990 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19991 "WLAN_HDD_TM_ATTR_DATA put fail");
19992 goto nla_put_failure;
19993 }
Leo Chang9056f462013-08-01 19:21:11 -070019994 cfg80211_testmode_event(skb, GFP_ATOMIC);
19995 return;
19996
19997nla_put_failure:
19998 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19999 "NLA Put fail");
20000 kfree_skb(skb);
20001
20002 return;
20003}
20004#endif /* FEATURE_WLAN_LPHB */
20005
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020006static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070020007{
20008 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
20009 int err = 0;
20010#ifdef FEATURE_WLAN_LPHB
20011 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070020012 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020013
20014 ENTER();
20015
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053020016 err = wlan_hdd_validate_context(pHddCtx);
20017 if (0 != err)
20018 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053020019 return err;
20020 }
Leo Chang9056f462013-08-01 19:21:11 -070020021#endif /* FEATURE_WLAN_LPHB */
20022
20023 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
20024 if (err)
20025 {
20026 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20027 "%s Testmode INV ATTR", __func__);
20028 return err;
20029 }
20030
20031 if (!tb[WLAN_HDD_TM_ATTR_CMD])
20032 {
20033 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20034 "%s Testmode INV CMD", __func__);
20035 return -EINVAL;
20036 }
20037
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053020038 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20039 TRACE_CODE_HDD_CFG80211_TESTMODE,
20040 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070020041 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
20042 {
20043#ifdef FEATURE_WLAN_LPHB
20044 /* Low Power Heartbeat configuration request */
20045 case WLAN_HDD_TM_CMD_WLAN_HB:
20046 {
20047 int buf_len;
20048 void *buf;
20049 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080020050 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070020051
20052 if (!tb[WLAN_HDD_TM_ATTR_DATA])
20053 {
20054 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20055 "%s Testmode INV DATA", __func__);
20056 return -EINVAL;
20057 }
20058
20059 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
20060 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080020061
20062 hb_params_temp =(tSirLPHBReq *)buf;
20063 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
20064 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
20065 return -EINVAL;
20066
Leo Chang9056f462013-08-01 19:21:11 -070020067 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
20068 if (NULL == hb_params)
20069 {
20070 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20071 "%s Request Buffer Alloc Fail", __func__);
20072 return -EINVAL;
20073 }
20074
20075 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070020076 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
20077 hb_params,
20078 wlan_hdd_cfg80211_lphb_ind_handler);
20079 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070020080 {
Leo Changd9df8aa2013-09-26 13:32:26 -070020081 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20082 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070020083 vos_mem_free(hb_params);
20084 }
Leo Chang9056f462013-08-01 19:21:11 -070020085 return 0;
20086 }
20087#endif /* FEATURE_WLAN_LPHB */
20088 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020089 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20090 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070020091 return -EOPNOTSUPP;
20092 }
20093
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020094 EXIT();
20095 return err;
Leo Chang9056f462013-08-01 19:21:11 -070020096}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020097
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053020098static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
20099#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
20100 struct wireless_dev *wdev,
20101#endif
20102 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020103{
20104 int ret;
20105
20106 vos_ssr_protect(__func__);
20107 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
20108 vos_ssr_unprotect(__func__);
20109
20110 return ret;
20111}
Leo Chang9056f462013-08-01 19:21:11 -070020112#endif /* CONFIG_NL80211_TESTMODE */
20113
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053020114extern void hdd_set_wlan_suspend_mode(bool suspend);
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020115static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020116 struct net_device *dev,
20117 int idx, struct survey_info *survey)
20118{
20119 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20120 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053020121 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020122 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053020123 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020124 v_S7_t snr,rssi;
20125 int status, i, j, filled = 0;
20126
20127 ENTER();
20128
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020129 if (NULL == pAdapter)
20130 {
20131 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20132 "%s: HDD adapter is Null", __func__);
20133 return -ENODEV;
20134 }
20135
20136 if (NULL == wiphy)
20137 {
20138 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20139 "%s: wiphy is Null", __func__);
20140 return -ENODEV;
20141 }
20142
20143 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
20144 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020145 if (0 != status)
20146 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020147 return status;
20148 }
20149
Mihir Sheted9072e02013-08-21 17:02:29 +053020150 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
20151
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020152 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053020153 0 != pAdapter->survey_idx ||
20154 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020155 {
20156 /* The survey dump ops when implemented completely is expected to
20157 * return a survey of all channels and the ops is called by the
20158 * kernel with incremental values of the argument 'idx' till it
20159 * returns -ENONET. But we can only support the survey for the
20160 * operating channel for now. survey_idx is used to track
20161 * that the ops is called only once and then return -ENONET for
20162 * the next iteration
20163 */
20164 pAdapter->survey_idx = 0;
20165 return -ENONET;
20166 }
20167
Mukul Sharma9d5233b2015-06-11 20:28:20 +053020168 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
20169 {
20170 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20171 "%s: Roaming in progress, hence return ", __func__);
20172 return -ENONET;
20173 }
20174
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020175 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
20176
20177 wlan_hdd_get_snr(pAdapter, &snr);
20178 wlan_hdd_get_rssi(pAdapter, &rssi);
20179
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053020180 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20181 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
20182 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020183 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
20184 hdd_wlan_get_freq(channel, &freq);
20185
20186
20187 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
20188 {
20189 if (NULL == wiphy->bands[i])
20190 {
20191 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
20192 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
20193 continue;
20194 }
20195
20196 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
20197 {
20198 struct ieee80211_supported_band *band = wiphy->bands[i];
20199
20200 if (band->channels[j].center_freq == (v_U16_t)freq)
20201 {
20202 survey->channel = &band->channels[j];
20203 /* The Rx BDs contain SNR values in dB for the received frames
20204 * while the supplicant expects noise. So we calculate and
20205 * return the value of noise (dBm)
20206 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
20207 */
20208 survey->noise = rssi - snr;
20209 survey->filled = SURVEY_INFO_NOISE_DBM;
20210 filled = 1;
20211 }
20212 }
20213 }
20214
20215 if (filled)
20216 pAdapter->survey_idx = 1;
20217 else
20218 {
20219 pAdapter->survey_idx = 0;
20220 return -ENONET;
20221 }
20222
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020223 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020224 return 0;
20225}
20226
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020227static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
20228 struct net_device *dev,
20229 int idx, struct survey_info *survey)
20230{
20231 int ret;
20232
20233 vos_ssr_protect(__func__);
20234 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
20235 vos_ssr_unprotect(__func__);
20236
20237 return ret;
20238}
20239
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020240/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053020241 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020242 * this is called when cfg80211 driver resume
20243 * driver updates latest sched_scan scan result(if any) to cfg80211 database
20244 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053020245int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020246{
20247 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
20248 hdd_adapter_t *pAdapter;
20249 hdd_adapter_list_node_t *pAdapterNode, *pNext;
20250 VOS_STATUS status = VOS_STATUS_SUCCESS;
20251
20252 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020253
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053020254 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020255 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020256 return 0;
20257 }
20258
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053020259 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
20260 NO_SESSION, pHddCtx->isWiphySuspended));
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053020261
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053020262 if (pHddCtx->is_ap_mode_wow_supported)
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053020263 {
20264 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20265 "%s: Resume SoftAP", __func__);
20266 hdd_set_wlan_suspend_mode(false);
20267 }
20268
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020269 spin_lock(&pHddCtx->schedScan_lock);
20270 pHddCtx->isWiphySuspended = FALSE;
20271 if (TRUE != pHddCtx->isSchedScanUpdatePending)
20272 {
20273 spin_unlock(&pHddCtx->schedScan_lock);
20274 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20275 "%s: Return resume is not due to PNO indication", __func__);
20276 return 0;
20277 }
20278 // Reset flag to avoid updatating cfg80211 data old results again
20279 pHddCtx->isSchedScanUpdatePending = FALSE;
20280 spin_unlock(&pHddCtx->schedScan_lock);
20281
20282 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
20283
20284 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
20285 {
20286 pAdapter = pAdapterNode->pAdapter;
20287 if ( (NULL != pAdapter) &&
20288 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
20289 {
20290 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053020291 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020292 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
20293 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053020294 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020295 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053020296 {
20297 /* Acquire wakelock to handle the case where APP's tries to
20298 * suspend immediately after updating the scan results. Whis
20299 * results in app's is in suspended state and not able to
20300 * process the connect request to AP
20301 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053020302 hdd_prevent_suspend_timeout(2000,
20303 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020304 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053020305 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020306
20307 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20308 "%s : cfg80211 scan result database updated", __func__);
20309
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020310 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020311 return 0;
20312
20313 }
20314 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
20315 pAdapterNode = pNext;
20316 }
20317
20318 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20319 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020320 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020321 return 0;
20322}
20323
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053020324int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
20325{
20326 int ret;
20327
20328 vos_ssr_protect(__func__);
20329 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
20330 vos_ssr_unprotect(__func__);
20331
20332 return ret;
20333}
20334
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020335/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053020336 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020337 * this is called when cfg80211 driver suspends
20338 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053020339int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020340 struct cfg80211_wowlan *wow)
20341{
20342 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053020343 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020344
20345 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020346
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053020347 ret = wlan_hdd_validate_context(pHddCtx);
20348 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020349 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053020350 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020351 }
20352
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053020353 if (pHddCtx->is_ap_mode_wow_supported) {
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053020354 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20355 "%s: Suspend SoftAP", __func__);
20356 hdd_set_wlan_suspend_mode(true);
20357 }
20358
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053020359
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053020360 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20361 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
20362 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020363 pHddCtx->isWiphySuspended = TRUE;
20364
20365 EXIT();
20366
20367 return 0;
20368}
20369
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053020370int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
20371 struct cfg80211_wowlan *wow)
20372{
20373 int ret;
20374
20375 vos_ssr_protect(__func__);
20376 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
20377 vos_ssr_unprotect(__func__);
20378
20379 return ret;
20380}
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053020381
20382#ifdef FEATURE_OEM_DATA_SUPPORT
20383static void wlan_hdd_cfg80211_oem_data_rsp_ind_new(void *ctx,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053020384 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053020385{
20386 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
20387
20388 ENTER();
20389
20390 if (wlan_hdd_validate_context(pHddCtx)) {
20391 return;
20392 }
20393 if (!pMsg)
20394 {
20395 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
20396 return;
20397 }
20398
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053020399 send_oem_data_rsp_msg(evLen, pMsg);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053020400
20401 EXIT();
20402 return;
20403
20404}
20405
20406void wlan_hdd_cfg80211_oemdata_callback(void *ctx, const tANI_U16 evType,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053020407 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053020408{
20409 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
20410
20411 ENTER();
20412
20413 if (wlan_hdd_validate_context(pHddCtx)) {
20414 return;
20415 }
20416
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053020417 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d) evLen %d"), evType, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053020418
20419 switch(evType) {
20420 case SIR_HAL_START_OEM_DATA_RSP_IND_NEW:
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053020421 wlan_hdd_cfg80211_oem_data_rsp_ind_new(ctx, pMsg, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053020422 break;
20423 default:
20424 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
20425 break;
20426 }
20427 EXIT();
20428}
20429#endif
20430
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053020431#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
20432 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053020433/**
20434 * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api
20435 * @wiphy: Pointer to wiphy
20436 * @wdev: Pointer to wireless device structure
20437 *
20438 * This function is used to abort an ongoing scan
20439 *
20440 * Return: None
20441 */
20442static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
20443 struct wireless_dev *wdev)
20444{
20445 struct net_device *dev = wdev->netdev;
20446 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
20447 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
20448 int ret;
20449
20450 ENTER();
20451
20452 if (NULL == adapter) {
20453 hddLog(VOS_TRACE_LEVEL_FATAL, FL("HDD adapter is NULL"));
20454 return;
20455 }
20456
20457 ret = wlan_hdd_validate_context(hdd_ctx);
20458 if (0 != ret)
20459 return;
20460
20461 wlan_hdd_scan_abort(adapter);
20462
20463 return;
20464}
20465
20466/**
20467 * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api
20468 * @wiphy: Pointer to wiphy
20469 * @wdev: Pointer to wireless device structure
20470 *
20471 * Return: None
20472 */
20473void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
20474 struct wireless_dev *wdev)
20475{
20476 vos_ssr_protect(__func__);
20477 __wlan_hdd_cfg80211_abort_scan(wiphy, wdev);
20478 vos_ssr_unprotect(__func__);
20479
20480 return;
20481}
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053020482#endif
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053020483
Jeff Johnson295189b2012-06-20 16:38:30 -070020484/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053020485static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070020486{
20487 .add_virtual_intf = wlan_hdd_add_virtual_intf,
20488 .del_virtual_intf = wlan_hdd_del_virtual_intf,
20489 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
20490 .change_station = wlan_hdd_change_station,
20491#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
20492 .add_beacon = wlan_hdd_cfg80211_add_beacon,
20493 .del_beacon = wlan_hdd_cfg80211_del_beacon,
20494 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070020495#else
20496 .start_ap = wlan_hdd_cfg80211_start_ap,
20497 .change_beacon = wlan_hdd_cfg80211_change_beacon,
20498 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070020499#endif
20500 .change_bss = wlan_hdd_cfg80211_change_bss,
20501 .add_key = wlan_hdd_cfg80211_add_key,
20502 .get_key = wlan_hdd_cfg80211_get_key,
20503 .del_key = wlan_hdd_cfg80211_del_key,
20504 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080020505#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070020506 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080020507#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070020508 .scan = wlan_hdd_cfg80211_scan,
20509 .connect = wlan_hdd_cfg80211_connect,
20510 .disconnect = wlan_hdd_cfg80211_disconnect,
20511 .join_ibss = wlan_hdd_cfg80211_join_ibss,
20512 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
20513 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
20514 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
20515 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070020516 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
20517 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053020518 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070020519#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
20520 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
20521 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
20522 .set_txq_params = wlan_hdd_set_txq_params,
20523#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070020524 .get_station = wlan_hdd_cfg80211_get_station,
20525 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
20526 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070020527 .add_station = wlan_hdd_cfg80211_add_station,
20528#ifdef FEATURE_WLAN_LFR
20529 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
20530 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
20531 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
20532#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070020533#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
20534 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
20535#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020536#ifdef FEATURE_WLAN_TDLS
20537 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
20538 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
20539#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020540#ifdef WLAN_FEATURE_GTK_OFFLOAD
20541 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
20542#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020543#ifdef FEATURE_WLAN_SCAN_PNO
20544 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
20545 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
20546#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020547 .resume = wlan_hdd_cfg80211_resume_wlan,
20548 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020549 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070020550#ifdef WLAN_NL80211_TESTMODE
20551 .testmode_cmd = wlan_hdd_cfg80211_testmode,
20552#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020553 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053020554#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
20555 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053020556 .abort_scan = wlan_hdd_cfg80211_abort_scan,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053020557#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070020558};
20559