blob: dbcd369812759c05671f452f9df5b02547dea693 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Masti, Narayanraddie1892a52015-12-15 15:01:01 +05302 * Copyright (c) 2012-2016 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);
Anurag Chouhand64d5232016-08-29 17:01:38 +05304011 if (ssid_length > SIR_MAC_MAX_SSID_LENGTH) {
4012 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
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307261#define PARAM_WIFICONFIG_MAX QCA_WLAN_VENDOR_ATTR_CONFIG_MAX
7262#define PARAM_MODULATED_DTIM QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM
7263#define PARAM_STATS_AVG_FACTOR QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR
7264#define PARAM_GUARD_TIME QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307265#define PARAM_BCNMISS_PENALTY_PARAM_COUNT \
7266 QCA_WLAN_VENDOR_ATTR_CONFIG_PENALIZE_AFTER_NCONS_BEACON_MISS
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307267
7268/**
7269 * __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7270 * vendor command
7271 *
7272 * @wiphy: wiphy device pointer
7273 * @wdev: wireless device pointer
7274 * @data: Vendor command data buffer
7275 * @data_len: Buffer length
7276 *
7277 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7278 *
7279 * Return: EOK or other error codes.
7280 */
7281
7282static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7283 struct wireless_dev *wdev,
7284 const void *data,
7285 int data_len)
7286{
7287 struct net_device *dev = wdev->netdev;
7288 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7289 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7290 hdd_station_ctx_t *pHddStaCtx;
7291 struct nlattr *tb[PARAM_WIFICONFIG_MAX + 1];
7292 tpSetWifiConfigParams pReq;
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307293 tModifyRoamParamsReqParams modifyRoamParamsReq;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307294 eHalStatus status;
7295 int ret_val;
7296 static const struct nla_policy policy[PARAM_WIFICONFIG_MAX + 1] = {
7297 [PARAM_STATS_AVG_FACTOR] = { .type = NLA_U16 },
7298 [PARAM_MODULATED_DTIM] = { .type = NLA_U32 },
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307299 [PARAM_GUARD_TIME] = { .type = NLA_U32},
7300 [PARAM_BCNMISS_PENALTY_PARAM_COUNT] =
7301 { .type = NLA_U32},
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307302 };
7303
7304 ENTER();
7305
7306 if (VOS_FTM_MODE == hdd_get_conparam()) {
7307 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7308 return -EINVAL;
7309 }
7310
7311 ret_val = wlan_hdd_validate_context(pHddCtx);
7312 if (ret_val) {
7313 return ret_val;
7314 }
7315
7316 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7317
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307318 if (nla_parse(tb, PARAM_WIFICONFIG_MAX, data, data_len, policy)) {
7319 hddLog(LOGE, FL("Invalid ATTR"));
7320 return -EINVAL;
7321 }
7322
7323 /* check the Wifi Capability */
7324 if ( (TRUE != pHddCtx->cfg_ini->fEnableWifiConfig) &&
7325 (TRUE != sme_IsFeatureSupportedByFW(WIFI_CONFIG)))
7326 {
7327 hddLog(VOS_TRACE_LEVEL_ERROR,
7328 FL("WIFICONFIG not supported by Firmware"));
7329 return -EINVAL;
7330 }
7331
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307332 if (tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]) {
7333 modifyRoamParamsReq.param = WIFI_CONFIG_SET_BCNMISS_PENALTY_COUNT;
7334 modifyRoamParamsReq.value =
7335 nla_get_u32(tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]);
7336
7337 if (eHAL_STATUS_SUCCESS !=
7338 sme_setBcnMissPenaltyCount(pHddCtx->hHal,&modifyRoamParamsReq))
7339 {
7340 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed", __func__);
7341 ret_val = -EINVAL;
7342 }
7343 return ret_val;
7344 }
7345
7346 /* Moved this down in order to provide provision to set beacon
7347 * miss penalty count irrespective of connection state.
7348 */
7349 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
7350 hddLog(LOGE, FL("Not in Connected state!"));
7351 return -ENOTSUPP;
7352 }
7353
7354 pReq = vos_mem_malloc(sizeof(tSetWifiConfigParams));
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307355
7356 if (!pReq) {
7357 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7358 "%s: Not able to allocate memory for tSetWifiConfigParams",
7359 __func__);
7360 return eHAL_STATUS_E_MALLOC_FAILED;
7361 }
7362
7363 vos_mem_set(pReq, sizeof(tSetWifiConfigParams), 0);
7364
7365 pReq->sessionId = pAdapter->sessionId;
7366 vos_mem_copy( &pReq->bssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
7367
7368 if (tb[PARAM_MODULATED_DTIM]) {
7369 pReq->paramValue = nla_get_u32(
7370 tb[PARAM_MODULATED_DTIM]);
7371 hddLog(LOG1, FL("Modulated DTIM: pReq->paramValue:%d "),
7372 pReq->paramValue);
Arun Khandavalli876886f2015-11-23 11:42:27 +05307373 pHddCtx->cfg_ini->enableDynamicDTIM = pReq->paramValue;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307374 hdd_set_pwrparams(pHddCtx);
7375 if (BMPS == pmcGetPmcState(pHddCtx->hHal)) {
7376 hddLog( LOG1, FL("WifiConfig: Requesting FullPower!"));
7377
7378 sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
7379 iw_full_power_cbfn, pAdapter,
7380 eSME_FULL_PWR_NEEDED_BY_HDD);
7381 }
7382 else
7383 {
7384 hddLog( LOG1, FL("WifiConfig Not in BMPS state"));
7385 }
7386 }
7387
7388 if (tb[PARAM_STATS_AVG_FACTOR]) {
7389 pReq->paramType = WIFI_CONFIG_SET_AVG_STATS_FACTOR;
7390 pReq->paramValue = nla_get_u16(
7391 tb[PARAM_STATS_AVG_FACTOR]);
7392 hddLog(LOG1, FL("AVG_STATS_FACTOR pReq->paramType:%d,pReq->paramValue:%d "),
7393 pReq->paramType, pReq->paramValue);
7394 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7395
7396 if (eHAL_STATUS_SUCCESS != status)
7397 {
7398 vos_mem_free(pReq);
7399 pReq = NULL;
7400 ret_val = -EPERM;
7401 return ret_val;
7402 }
7403 }
7404
7405
7406 if (tb[PARAM_GUARD_TIME]) {
7407 pReq->paramType = WIFI_CONFIG_SET_GUARD_TIME;
7408 pReq->paramValue = nla_get_u32(
7409 tb[PARAM_GUARD_TIME]);
7410 hddLog(LOG1, FL("GUARD_TIME pReq->paramType:%d,pReq->paramValue:%d "),
7411 pReq->paramType, pReq->paramValue);
7412 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7413
7414 if (eHAL_STATUS_SUCCESS != status)
7415 {
7416 vos_mem_free(pReq);
7417 pReq = NULL;
7418 ret_val = -EPERM;
7419 return ret_val;
7420 }
7421
7422 }
7423
7424 EXIT();
7425 return ret_val;
7426}
7427
7428/**
7429 * wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7430 * vendor command
7431 *
7432 * @wiphy: wiphy device pointer
7433 * @wdev: wireless device pointer
7434 * @data: Vendor command data buffer
7435 * @data_len: Buffer length
7436 *
7437 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7438 *
7439 * Return: EOK or other error codes.
7440 */
7441static int wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7442 struct wireless_dev *wdev,
7443 const void *data,
7444 int data_len)
7445{
7446 int ret;
7447
7448 vos_ssr_protect(__func__);
7449 ret = __wlan_hdd_cfg80211_wifi_configuration_set(wiphy, wdev,
7450 data, data_len);
7451 vos_ssr_unprotect(__func__);
7452
7453 return ret;
7454}
Sunil Duttc69bccb2014-05-26 21:30:20 +05307455const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
7456{
Mukul Sharma2a271632014-10-13 14:59:01 +05307457 {
7458 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7459 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
7460 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7461 WIPHY_VENDOR_CMD_NEED_NETDEV |
7462 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307463 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05307464 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05307465
7466 {
7467 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7468 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
7469 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7470 WIPHY_VENDOR_CMD_NEED_NETDEV |
7471 WIPHY_VENDOR_CMD_NEED_RUNNING,
7472 .doit = wlan_hdd_cfg80211_nan_request
7473 },
7474
Sunil Duttc69bccb2014-05-26 21:30:20 +05307475#ifdef WLAN_FEATURE_LINK_LAYER_STATS
7476 {
7477 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7478 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
7479 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7480 WIPHY_VENDOR_CMD_NEED_NETDEV |
7481 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307482 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05307483 },
7484
7485 {
7486 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7487 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
7488 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7489 WIPHY_VENDOR_CMD_NEED_NETDEV |
7490 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307491 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05307492 },
7493
7494 {
7495 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7496 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
7497 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7498 WIPHY_VENDOR_CMD_NEED_NETDEV |
7499 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307500 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05307501 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05307502#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05307503#ifdef WLAN_FEATURE_EXTSCAN
7504 {
7505 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7506 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
7507 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7508 WIPHY_VENDOR_CMD_NEED_NETDEV |
7509 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307510 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05307511 },
7512 {
7513 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7514 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
7515 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7516 WIPHY_VENDOR_CMD_NEED_NETDEV |
7517 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307518 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05307519 },
7520 {
7521 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7522 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
7523 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7524 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307525 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05307526 },
7527 {
7528 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7529 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
7530 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7531 WIPHY_VENDOR_CMD_NEED_NETDEV |
7532 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307533 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05307534 },
7535 {
7536 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7537 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
7538 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7539 WIPHY_VENDOR_CMD_NEED_NETDEV |
7540 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307541 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05307542 },
7543 {
7544 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7545 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
7546 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7547 WIPHY_VENDOR_CMD_NEED_NETDEV |
7548 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307549 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05307550 },
7551 {
7552 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7553 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
7554 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7555 WIPHY_VENDOR_CMD_NEED_NETDEV |
7556 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307557 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05307558 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05307559 {
7560 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7561 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST,
7562 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7563 WIPHY_VENDOR_CMD_NEED_NETDEV |
7564 WIPHY_VENDOR_CMD_NEED_RUNNING,
7565 .doit = wlan_hdd_cfg80211_extscan_set_ssid_hotlist
7566 },
7567 {
7568 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7569 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST,
7570 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7571 WIPHY_VENDOR_CMD_NEED_NETDEV |
7572 WIPHY_VENDOR_CMD_NEED_RUNNING,
7573 .doit = wlan_hdd_cfg80211_extscan_reset_ssid_hotlist
7574 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05307575#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05307576/*EXT TDLS*/
7577 {
7578 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7579 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
7580 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7581 WIPHY_VENDOR_CMD_NEED_NETDEV |
7582 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307583 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05307584 },
7585 {
7586 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7587 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
7588 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7589 WIPHY_VENDOR_CMD_NEED_NETDEV |
7590 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307591 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05307592 },
7593 {
7594 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7595 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
7596 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7597 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307598 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05307599 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05307600 {
7601 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7602 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
7603 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7604 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307605 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05307606 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05307607 {
7608 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7609 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
7610 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7611 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307612 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05307613 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05307614 {
7615 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7616 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
7617 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7618 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307619 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05307620 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05307621 {
7622 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7623 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
7624 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7625 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307626 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05307627 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307628 {
7629 .info.vendor_id = QCA_NL80211_VENDOR_ID,
c_manjeecfd1efb2015-09-25 19:32:34 +05307630 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
7631 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7632 WIPHY_VENDOR_CMD_NEED_NETDEV |
7633 WIPHY_VENDOR_CMD_NEED_RUNNING,
7634 .doit = wlan_hdd_cfg80211_get_fw_mem_dump
7635 },
7636 {
7637 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307638 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
7639 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7640 WIPHY_VENDOR_CMD_NEED_NETDEV |
7641 WIPHY_VENDOR_CMD_NEED_RUNNING,
7642 .doit = wlan_hdd_cfg80211_setband
Sushant Kaushik8e644982015-09-23 12:18:54 +05307643 },
7644 {
7645 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7646 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
7647 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7648 WIPHY_VENDOR_CMD_NEED_NETDEV,
7649 .doit = wlan_hdd_cfg80211_wifi_logger_start
7650 },
Sushant Kaushik847890c2015-09-28 16:05:17 +05307651 {
7652 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7653 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
7654 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7655 WIPHY_VENDOR_CMD_NEED_NETDEV|
7656 WIPHY_VENDOR_CMD_NEED_RUNNING,
7657 .doit = wlan_hdd_cfg80211_get_wifi_info
Sachin Ahujac08f72a2015-09-22 15:25:47 +05307658 },
7659 {
7660 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7661 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
7662 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7663 WIPHY_VENDOR_CMD_NEED_NETDEV |
7664 WIPHY_VENDOR_CMD_NEED_RUNNING,
7665 .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307666 },
7667 {
7668 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7669 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,
7670 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7671 WIPHY_VENDOR_CMD_NEED_NETDEV |
7672 WIPHY_VENDOR_CMD_NEED_RUNNING,
7673 .doit = wlan_hdd_cfg80211_monitor_rssi
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307674 },
7675#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
7676 {
7677 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7678 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS,
7679 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7680 WIPHY_VENDOR_CMD_NEED_NETDEV |
7681 WIPHY_VENDOR_CMD_NEED_RUNNING,
7682 .doit = wlan_hdd_cfg80211_offloaded_packets
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307683 },
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307684#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307685 {
7686 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7687 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
7688 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7689 WIPHY_VENDOR_CMD_NEED_NETDEV |
7690 WIPHY_VENDOR_CMD_NEED_RUNNING,
7691 .doit = wlan_hdd_cfg80211_get_link_properties
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307692 },
7693 {
7694 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7695 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION,
7696 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7697 WIPHY_VENDOR_CMD_NEED_NETDEV |
7698 WIPHY_VENDOR_CMD_NEED_RUNNING,
7699 .doit = wlan_hdd_cfg80211_wifi_configuration_set
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307700 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05307701};
7702
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007703/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05307704static const
7705struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007706{
7707#ifdef FEATURE_WLAN_CH_AVOID
7708 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05307709 .vendor_id = QCA_NL80211_VENDOR_ID,
7710 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007711 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05307712#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
7713#ifdef WLAN_FEATURE_LINK_LAYER_STATS
7714 {
7715 /* Index = 1*/
7716 .vendor_id = QCA_NL80211_VENDOR_ID,
7717 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
7718 },
7719 {
7720 /* Index = 2*/
7721 .vendor_id = QCA_NL80211_VENDOR_ID,
7722 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
7723 },
7724 {
7725 /* Index = 3*/
7726 .vendor_id = QCA_NL80211_VENDOR_ID,
7727 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
7728 },
7729 {
7730 /* Index = 4*/
7731 .vendor_id = QCA_NL80211_VENDOR_ID,
7732 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
7733 },
7734 {
7735 /* Index = 5*/
7736 .vendor_id = QCA_NL80211_VENDOR_ID,
7737 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
7738 },
7739 {
7740 /* Index = 6*/
7741 .vendor_id = QCA_NL80211_VENDOR_ID,
7742 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
7743 },
7744#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05307745#ifdef WLAN_FEATURE_EXTSCAN
7746 {
7747 .vendor_id = QCA_NL80211_VENDOR_ID,
7748 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
7749 },
7750 {
7751 .vendor_id = QCA_NL80211_VENDOR_ID,
7752 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
7753 },
7754 {
7755 .vendor_id = QCA_NL80211_VENDOR_ID,
7756 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
7757 },
7758 {
7759 .vendor_id = QCA_NL80211_VENDOR_ID,
7760 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
7761 },
7762 {
7763 .vendor_id = QCA_NL80211_VENDOR_ID,
7764 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
7765 },
7766 {
7767 .vendor_id = QCA_NL80211_VENDOR_ID,
7768 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
7769 },
7770 {
7771 .vendor_id = QCA_NL80211_VENDOR_ID,
7772 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
7773 },
7774 {
7775 .vendor_id = QCA_NL80211_VENDOR_ID,
7776 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
7777 },
7778 {
7779 .vendor_id = QCA_NL80211_VENDOR_ID,
7780 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
7781 },
7782 {
7783 .vendor_id = QCA_NL80211_VENDOR_ID,
7784 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
7785 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05307786 {
7787 .vendor_id = QCA_NL80211_VENDOR_ID,
7788 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST
7789 },
7790 {
7791 .vendor_id = QCA_NL80211_VENDOR_ID,
7792 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST
7793 },
7794 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND_INDEX] = {
7795 .vendor_id = QCA_NL80211_VENDOR_ID,
7796 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND
7797 },
7798 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST_INDEX] = {
7799 .vendor_id = QCA_NL80211_VENDOR_ID,
7800 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST
7801 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05307802#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05307803/*EXT TDLS*/
7804 {
7805 .vendor_id = QCA_NL80211_VENDOR_ID,
7806 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
7807 },
c_manjeecfd1efb2015-09-25 19:32:34 +05307808 [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
7809 .vendor_id = QCA_NL80211_VENDOR_ID,
7810 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
7811 },
7812
Srinivas Dasari030bad32015-02-18 23:23:54 +05307813
7814 {
7815 .vendor_id = QCA_NL80211_VENDOR_ID,
7816 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
7817 },
7818
Sushant Kaushik084f6592015-09-10 13:11:56 +05307819 {
7820 .vendor_id = QCA_NL80211_VENDOR_ID,
7821 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307822 },
7823 [QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = {
7824 .vendor_id = QCA_NL80211_VENDOR_ID,
7825 .subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI
7826 },
Padma, Santhosh Kumar7bbc7d92015-12-08 20:23:19 +05307827 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX] = {
7828 .vendor_id = QCA_NL80211_VENDOR_ID,
7829 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST
7830 },
Sushant Kaushik084f6592015-09-10 13:11:56 +05307831
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007832};
7833
Jeff Johnson295189b2012-06-20 16:38:30 -07007834/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307835 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307836 * This function is called by hdd_wlan_startup()
7837 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307838 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07007839 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307840struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07007841{
7842 struct wiphy *wiphy;
7843 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307844 /*
7845 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07007846 */
7847 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
7848
7849 if (!wiphy)
7850 {
7851 /* Print error and jump into err label and free the memory */
7852 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
7853 return NULL;
7854 }
7855
Sunil Duttc69bccb2014-05-26 21:30:20 +05307856
Jeff Johnson295189b2012-06-20 16:38:30 -07007857 return wiphy;
7858}
7859
Anurag Chouhan343af7e2016-12-16 13:11:19 +05307860#if (LINUX_VERSION_CODE > KERNEL_VERSION(4,4,0)) || \
7861 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
7862/**
7863 * hdd_config_sched_scan_plans_to_wiphy() - configure sched scan plans to wiphy
7864 * @wiphy: pointer to wiphy
7865 * @config: pointer to config
7866 *
7867 * Return: None
7868 */
7869static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
7870 hdd_config_t *config)
7871{
7872 wiphy->max_sched_scan_plans = MAX_SCHED_SCAN_PLANS;
7873 if (config->max_sched_scan_plan_interval)
7874 wiphy->max_sched_scan_plan_interval =
7875 config->max_sched_scan_plan_interval;
7876 if (config->max_sched_scan_plan_iterations)
7877 wiphy->max_sched_scan_plan_iterations =
7878 config->max_sched_scan_plan_iterations;
7879}
7880#else
7881static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
7882 hdd_config_t *config)
7883{
7884}
7885#endif
7886
Jeff Johnson295189b2012-06-20 16:38:30 -07007887/*
7888 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307889 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07007890 * private ioctl to change the band value
7891 */
7892int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
7893{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307894 int i, j;
7895 eNVChannelEnabledType channelEnabledState;
7896
Jeff Johnsone7245742012-09-05 17:12:55 -07007897 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307898
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307899 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007900 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307901
7902 if (NULL == wiphy->bands[i])
7903 {
7904 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
7905 __func__, i);
7906 continue;
7907 }
7908
7909 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
7910 {
7911 struct ieee80211_supported_band *band = wiphy->bands[i];
7912
7913 channelEnabledState = vos_nv_getChannelEnabledState(
7914 band->channels[j].hw_value);
7915
7916 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
7917 {
Abhishek Singh678227a2014-11-04 10:52:38 +05307918 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307919 continue;
7920 }
7921 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
7922 {
7923 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
7924 continue;
7925 }
7926
7927 if (NV_CHANNEL_DISABLE == channelEnabledState ||
7928 NV_CHANNEL_INVALID == channelEnabledState)
7929 {
7930 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
7931 }
7932 else if (NV_CHANNEL_DFS == channelEnabledState)
7933 {
7934 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
7935 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
7936 }
7937 else
7938 {
7939 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
7940 |IEEE80211_CHAN_RADAR);
7941 }
7942 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007943 }
7944 return 0;
7945}
7946/*
7947 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307948 * This function is called by hdd_wlan_startup()
7949 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07007950 * This function is used to initialize and register wiphy structure.
7951 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307952int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07007953 struct wiphy *wiphy,
7954 hdd_config_t *pCfg
7955 )
7956{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307957 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05307958 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7959
Jeff Johnsone7245742012-09-05 17:12:55 -07007960 ENTER();
7961
Jeff Johnson295189b2012-06-20 16:38:30 -07007962 /* Now bind the underlying wlan device with wiphy */
7963 set_wiphy_dev(wiphy, dev);
7964
7965 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07007966
Kiet Lam6c583332013-10-14 05:37:09 +05307967#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07007968 /* the flag for the other case would be initialzed in
7969 vos_init_wiphy_from_nv_bin */
Manjeet Singh9e19de62016-08-18 18:26:41 +05307970#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
7971 wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
7972#else
Amar Singhal0a402232013-10-11 20:57:16 -07007973 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05307974#endif
Manjeet Singh9e19de62016-08-18 18:26:41 +05307975#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07007976
Amar Singhalfddc28c2013-09-05 13:03:40 -07007977 /* This will disable updating of NL channels from passive to
7978 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307979#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
7980 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
7981#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07007982 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307983#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07007984
Amar Singhala49cbc52013-10-08 18:37:44 -07007985
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007986#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07007987 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
7988 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
7989 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07007990 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307991#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Rajeev Kumar Sirasanagandla0d6dd752016-08-17 15:01:39 +05307992 wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307993#else
7994 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
7995#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007996#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07007997
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007998#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07007999 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08008000#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07008001 || pCfg->isFastRoamIniFeatureEnabled
8002#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08008003#ifdef FEATURE_WLAN_ESE
8004 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07008005#endif
8006 )
8007 {
8008 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
8009 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08008010#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008011#ifdef FEATURE_WLAN_TDLS
8012 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
8013 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
8014#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308015#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05308016 if (pCfg->configPNOScanSupport)
8017 {
8018 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
8019 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
8020 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
8021 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
8022 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308023#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008024
Abhishek Singh10d85972015-04-17 10:27:23 +05308025#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
8026 wiphy->features |= NL80211_FEATURE_HT_IBSS;
8027#endif
8028
Amar Singhalfddc28c2013-09-05 13:03:40 -07008029#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07008030 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
8031 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07008032 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07008033 driver need to determine what to do with both
8034 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07008035
8036 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07008037#else
8038 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07008039#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008040
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308041 wiphy->max_scan_ssids = MAX_SCAN_SSID;
8042
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05308043 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07008044
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308045 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
8046
Jeff Johnson295189b2012-06-20 16:38:30 -07008047 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05308048 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
8049 | BIT(NL80211_IFTYPE_ADHOC)
8050 | BIT(NL80211_IFTYPE_P2P_CLIENT)
8051 | BIT(NL80211_IFTYPE_P2P_GO)
8052 | BIT(NL80211_IFTYPE_AP);
8053
8054 if (VOS_MONITOR_MODE == hdd_get_conparam())
8055 {
8056 wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
8057 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008058
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308059 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008060 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308061#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
8062 if( pCfg->enableMCC )
8063 {
8064 /* Currently, supports up to two channels */
8065 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008066
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308067 if( !pCfg->allowMCCGODiffBI )
8068 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008069
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308070 }
8071 wiphy->iface_combinations = &wlan_hdd_iface_combination;
8072 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008073#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308074 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008075
Jeff Johnson295189b2012-06-20 16:38:30 -07008076 /* Before registering we need to update the ht capabilitied based
8077 * on ini values*/
8078 if( !pCfg->ShortGI20MhzEnable )
8079 {
8080 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
8081 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
Jeff Johnson295189b2012-06-20 16:38:30 -07008082 }
8083
8084 if( !pCfg->ShortGI40MhzEnable )
8085 {
8086 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
8087 }
8088
8089 if( !pCfg->nChannelBondingMode5GHz )
8090 {
8091 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
8092 }
Agrawal Ashish97dec502015-11-26 20:20:58 +05308093 /*
8094 * In case of static linked driver at the time of driver unload,
8095 * module exit doesn't happens. Module cleanup helps in cleaning
8096 * of static memory.
8097 * If driver load happens statically, at the time of driver unload,
8098 * wiphy flags don't get reset because of static memory.
8099 * It's better not to store channel in static memory.
8100 */
8101 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
8102 wiphy->bands[IEEE80211_BAND_2GHZ]->channels =
8103 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_2_4_GHZ));
8104 if (wiphy->bands[IEEE80211_BAND_2GHZ]->channels == NULL)
8105 {
8106 hddLog(VOS_TRACE_LEVEL_ERROR,
8107 FL("Not enough memory to allocate channels"));
8108 return -ENOMEM;
8109 }
8110 vos_mem_copy(wiphy->bands[IEEE80211_BAND_2GHZ]->channels,
8111 &hdd_channels_2_4_GHZ[0],
8112 sizeof(hdd_channels_2_4_GHZ));
Jeff Johnson295189b2012-06-20 16:38:30 -07008113
Agrawal Ashish97dec502015-11-26 20:20:58 +05308114 if (true == hdd_is_5g_supported(pHddCtx))
8115 {
8116 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
8117 wiphy->bands[IEEE80211_BAND_5GHZ]->channels =
8118 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_5_GHZ));
8119 if (wiphy->bands[IEEE80211_BAND_5GHZ]->channels == NULL)
8120 {
8121 hddLog(VOS_TRACE_LEVEL_ERROR,
8122 FL("Not enough memory to allocate channels"));
8123 vos_mem_free(wiphy->bands[IEEE80211_BAND_2GHZ]->channels);
8124 wiphy->bands[IEEE80211_BAND_2GHZ]->channels = NULL;
8125 return -ENOMEM;
8126 }
8127 vos_mem_copy(wiphy->bands[IEEE80211_BAND_5GHZ]->channels,
8128 &hdd_channels_5_GHZ[0],
8129 sizeof(hdd_channels_5_GHZ));
8130 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308131
8132 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
8133 {
8134
8135 if (NULL == wiphy->bands[i])
8136 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05308137 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308138 __func__, i);
8139 continue;
8140 }
8141
8142 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
8143 {
8144 struct ieee80211_supported_band *band = wiphy->bands[i];
8145
8146 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
8147 {
8148 // Enable social channels for P2P
8149 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
8150 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
8151 else
8152 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8153 continue;
8154 }
8155 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
8156 {
8157 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8158 continue;
8159 }
8160 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008161 }
8162 /*Initialise the supported cipher suite details*/
8163 wiphy->cipher_suites = hdd_cipher_suites;
8164 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
8165
8166 /*signal strength in mBm (100*dBm) */
8167 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
8168
8169#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05308170 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07008171#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008172
Sunil Duttc69bccb2014-05-26 21:30:20 +05308173 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
8174 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008175 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
8176 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
8177
Anurag Chouhan343af7e2016-12-16 13:11:19 +05308178 hdd_config_sched_scan_plans_to_wiphy(wiphy, pCfg);
8179
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308180 EXIT();
8181 return 0;
8182}
8183
8184/* In this function we are registering wiphy. */
8185int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
8186{
8187 ENTER();
8188 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008189 if (0 > wiphy_register(wiphy))
8190 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308191 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07008192 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8193 return -EIO;
8194 }
8195
8196 EXIT();
8197 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308198}
Jeff Johnson295189b2012-06-20 16:38:30 -07008199
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308200/* In this function we are updating channel list when,
8201 regulatory domain is FCC and country code is US.
8202 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
8203 As per FCC smart phone is not a indoor device.
8204 GO should not opeate on indoor channels */
8205void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
8206{
8207 int j;
8208 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
8209 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
8210 //Default counrtycode from NV at the time of wiphy initialization.
8211 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
8212 &defaultCountryCode[0]))
8213 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008214 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308215 }
8216 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
8217 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308218 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
8219 {
8220 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
8221 return;
8222 }
8223 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
8224 {
8225 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
8226 // Mark UNII -1 band channel as passive
8227 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
8228 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
8229 }
8230 }
8231}
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05308232/* This function registers for all frame which supplicant is interested in */
8233void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008234{
Jeff Johnson295189b2012-06-20 16:38:30 -07008235 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8236 /* Register for all P2P action, public action etc frames */
8237 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
Jeff Johnsone7245742012-09-05 17:12:55 -07008238 ENTER();
Abhishek Singh16e05762015-11-30 14:29:27 +05308239 /* Register frame indication call back */
8240 sme_register_mgmt_frame_ind_callback(hHal, hdd_indicate_mgmt_frame);
Jeff Johnson295189b2012-06-20 16:38:30 -07008241 /* Right now we are registering these frame when driver is getting
8242 initialized. Once we will move to 2.6.37 kernel, in which we have
8243 frame register ops, we will move this code as a part of that */
8244 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308245 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07008246 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
8247
8248 /* GAS Initial Response */
8249 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8250 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308251
Jeff Johnson295189b2012-06-20 16:38:30 -07008252 /* GAS Comeback Request */
8253 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8254 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
8255
8256 /* GAS Comeback Response */
8257 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8258 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
8259
8260 /* P2P Public Action */
8261 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308262 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07008263 P2P_PUBLIC_ACTION_FRAME_SIZE );
8264
8265 /* P2P Action */
8266 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8267 (v_U8_t*)P2P_ACTION_FRAME,
8268 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07008269
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05308270 /* WNM BSS Transition Request frame */
8271 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8272 (v_U8_t*)WNM_BSS_ACTION_FRAME,
8273 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07008274
8275 /* WNM-Notification */
8276 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8277 (v_U8_t*)WNM_NOTIFICATION_FRAME,
8278 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008279}
8280
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05308281void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008282{
Jeff Johnson295189b2012-06-20 16:38:30 -07008283 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8284 /* Register for all P2P action, public action etc frames */
8285 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
8286
Jeff Johnsone7245742012-09-05 17:12:55 -07008287 ENTER();
8288
Jeff Johnson295189b2012-06-20 16:38:30 -07008289 /* Right now we are registering these frame when driver is getting
8290 initialized. Once we will move to 2.6.37 kernel, in which we have
8291 frame register ops, we will move this code as a part of that */
8292 /* GAS Initial Request */
8293
8294 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8295 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
8296
8297 /* GAS Initial Response */
8298 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8299 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308300
Jeff Johnson295189b2012-06-20 16:38:30 -07008301 /* GAS Comeback Request */
8302 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8303 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
8304
8305 /* GAS Comeback Response */
8306 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8307 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
8308
8309 /* P2P Public Action */
8310 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308311 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07008312 P2P_PUBLIC_ACTION_FRAME_SIZE );
8313
8314 /* P2P Action */
8315 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8316 (v_U8_t*)P2P_ACTION_FRAME,
8317 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07008318 /* WNM-Notification */
8319 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8320 (v_U8_t*)WNM_NOTIFICATION_FRAME,
8321 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008322}
8323
8324#ifdef FEATURE_WLAN_WAPI
8325void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05308326 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07008327{
8328 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8329 tCsrRoamSetKey setKey;
8330 v_BOOL_t isConnected = TRUE;
8331 int status = 0;
8332 v_U32_t roamId= 0xFF;
8333 tANI_U8 *pKeyPtr = NULL;
8334 int n = 0;
8335
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308336 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
8337 __func__, hdd_device_modetoString(pAdapter->device_mode),
8338 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008339
Gopichand Nakkalae7480202013-02-11 15:24:22 +05308340 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07008341 setKey.keyId = key_index; // Store Key ID
8342 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
8343 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
8344 setKey.paeRole = 0 ; // the PAE role
8345 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
8346 {
8347 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
8348 }
8349 else
8350 {
8351 isConnected = hdd_connIsConnected(pHddStaCtx);
8352 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
8353 }
8354 setKey.keyLength = key_Len;
8355 pKeyPtr = setKey.Key;
8356 memcpy( pKeyPtr, key, key_Len);
8357
Arif Hussain6d2a3322013-11-17 19:50:10 -08008358 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07008359 __func__, key_Len);
8360 for (n = 0 ; n < key_Len; n++)
8361 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
8362 __func__,n,setKey.Key[n]);
8363
8364 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8365 if ( isConnected )
8366 {
8367 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8368 pAdapter->sessionId, &setKey, &roamId );
8369 }
8370 if ( status != 0 )
8371 {
8372 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8373 "[%4d] sme_RoamSetKey returned ERROR status= %d",
8374 __LINE__, status );
8375 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8376 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308377 /* Need to clear any trace of key value in the memory.
8378 * Thus zero out the memory even though it is local
8379 * variable.
8380 */
8381 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07008382}
8383#endif /* FEATURE_WLAN_WAPI*/
8384
8385#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308386int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07008387 beacon_data_t **ppBeacon,
8388 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008389#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308390int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008391 beacon_data_t **ppBeacon,
8392 struct cfg80211_beacon_data *params,
8393 int dtim_period)
8394#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308395{
Jeff Johnson295189b2012-06-20 16:38:30 -07008396 int size;
8397 beacon_data_t *beacon = NULL;
8398 beacon_data_t *old = NULL;
8399 int head_len,tail_len;
8400
Jeff Johnsone7245742012-09-05 17:12:55 -07008401 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008402 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308403 {
8404 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8405 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008406 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308407 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008408
8409 old = pAdapter->sessionCtx.ap.beacon;
8410
8411 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308412 {
8413 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8414 FL("session(%d) old and new heads points to NULL"),
8415 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008416 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308417 }
8418
8419 if (params->tail && !params->tail_len)
8420 {
8421 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8422 FL("tail_len is zero but tail is not NULL"));
8423 return -EINVAL;
8424 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008425
Jeff Johnson295189b2012-06-20 16:38:30 -07008426#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
8427 /* Kernel 3.0 is not updating dtim_period for set beacon */
8428 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308429 {
8430 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8431 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008432 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308433 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008434#endif
8435
8436 if(params->head)
8437 head_len = params->head_len;
8438 else
8439 head_len = old->head_len;
8440
8441 if(params->tail || !old)
8442 tail_len = params->tail_len;
8443 else
8444 tail_len = old->tail_len;
8445
8446 size = sizeof(beacon_data_t) + head_len + tail_len;
8447
8448 beacon = kzalloc(size, GFP_KERNEL);
8449
8450 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308451 {
8452 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8453 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008454 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308455 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008456
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008457#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008458 if(params->dtim_period || !old )
8459 beacon->dtim_period = params->dtim_period;
8460 else
8461 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008462#else
8463 if(dtim_period || !old )
8464 beacon->dtim_period = dtim_period;
8465 else
8466 beacon->dtim_period = old->dtim_period;
8467#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308468
Jeff Johnson295189b2012-06-20 16:38:30 -07008469 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
8470 beacon->tail = beacon->head + head_len;
8471 beacon->head_len = head_len;
8472 beacon->tail_len = tail_len;
8473
8474 if(params->head) {
8475 memcpy (beacon->head,params->head,beacon->head_len);
8476 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308477 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07008478 if(old)
8479 memcpy (beacon->head,old->head,beacon->head_len);
8480 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308481
Jeff Johnson295189b2012-06-20 16:38:30 -07008482 if(params->tail) {
8483 memcpy (beacon->tail,params->tail,beacon->tail_len);
8484 }
8485 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308486 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07008487 memcpy (beacon->tail,old->tail,beacon->tail_len);
8488 }
8489
8490 *ppBeacon = beacon;
8491
8492 kfree(old);
8493
8494 return 0;
8495
8496}
Jeff Johnson295189b2012-06-20 16:38:30 -07008497
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308498v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
8499#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
8500 const v_U8_t *pIes,
8501#else
8502 v_U8_t *pIes,
8503#endif
8504 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07008505{
8506 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308507 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07008508 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308509
Jeff Johnson295189b2012-06-20 16:38:30 -07008510 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308511 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008512 elem_id = ptr[0];
8513 elem_len = ptr[1];
8514 left -= 2;
8515 if(elem_len > left)
8516 {
8517 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07008518 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07008519 eid,elem_len,left);
8520 return NULL;
8521 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308522 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07008523 {
8524 return ptr;
8525 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308526
Jeff Johnson295189b2012-06-20 16:38:30 -07008527 left -= elem_len;
8528 ptr += (elem_len + 2);
8529 }
8530 return NULL;
8531}
8532
Jeff Johnson295189b2012-06-20 16:38:30 -07008533/* Check if rate is 11g rate or not */
8534static int wlan_hdd_rate_is_11g(u8 rate)
8535{
Sanjay Devnani28322e22013-06-21 16:13:40 -07008536 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008537 u8 i;
8538 for (i = 0; i < 8; i++)
8539 {
8540 if(rate == gRateArray[i])
8541 return TRUE;
8542 }
8543 return FALSE;
8544}
8545
8546/* Check for 11g rate and set proper 11g only mode */
8547static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
8548 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
8549{
8550 u8 i, num_rates = pIe[0];
8551
8552 pIe += 1;
8553 for ( i = 0; i < num_rates; i++)
8554 {
8555 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
8556 {
8557 /* If rate set have 11g rate than change the mode to 11G */
8558 *pSapHw_mode = eSAP_DOT11_MODE_11g;
8559 if (pIe[i] & BASIC_RATE_MASK)
8560 {
8561 /* If we have 11g rate as basic rate, it means mode
8562 is 11g only mode.
8563 */
8564 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
8565 *pCheckRatesfor11g = FALSE;
8566 }
8567 }
8568 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
8569 {
8570 *require_ht = TRUE;
8571 }
8572 }
8573 return;
8574}
8575
8576static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
8577{
8578 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
8579 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8580 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
8581 u8 checkRatesfor11g = TRUE;
8582 u8 require_ht = FALSE;
8583 u8 *pIe=NULL;
8584
8585 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
8586
8587 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
8588 pBeacon->head_len, WLAN_EID_SUPP_RATES);
8589 if (pIe != NULL)
8590 {
8591 pIe += 1;
8592 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
8593 &pConfig->SapHw_mode);
8594 }
8595
8596 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
8597 WLAN_EID_EXT_SUPP_RATES);
8598 if (pIe != NULL)
8599 {
8600
8601 pIe += 1;
8602 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
8603 &pConfig->SapHw_mode);
8604 }
8605
8606 if( pConfig->channel > 14 )
8607 {
8608 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
8609 }
8610
8611 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
8612 WLAN_EID_HT_CAPABILITY);
8613
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308614 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07008615 {
8616 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
8617 if(require_ht)
8618 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
8619 }
8620}
8621
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308622static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
8623 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
8624{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008625 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308626 v_U8_t *pIe = NULL;
8627 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8628
8629 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
8630 pBeacon->tail, pBeacon->tail_len);
8631
8632 if (pIe)
8633 {
8634 ielen = pIe[1] + 2;
8635 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
8636 {
8637 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
8638 }
8639 else
8640 {
8641 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
8642 return -EINVAL;
8643 }
8644 *total_ielen += ielen;
8645 }
8646 return 0;
8647}
8648
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008649static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
8650 v_U8_t *genie, v_U8_t *total_ielen)
8651{
8652 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8653 int left = pBeacon->tail_len;
8654 v_U8_t *ptr = pBeacon->tail;
8655 v_U8_t elem_id, elem_len;
8656 v_U16_t ielen = 0;
8657
8658 if ( NULL == ptr || 0 == left )
8659 return;
8660
8661 while (left >= 2)
8662 {
8663 elem_id = ptr[0];
8664 elem_len = ptr[1];
8665 left -= 2;
8666 if (elem_len > left)
8667 {
8668 hddLog( VOS_TRACE_LEVEL_ERROR,
8669 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
8670 elem_id, elem_len, left);
8671 return;
8672 }
8673 if (IE_EID_VENDOR == elem_id)
8674 {
8675 /* skipping the VSIE's which we don't want to include or
8676 * it will be included by existing code
8677 */
8678 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
8679#ifdef WLAN_FEATURE_WFD
8680 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
8681#endif
8682 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8683 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8684 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
8685 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8686 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
8687 {
8688 ielen = ptr[1] + 2;
8689 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
8690 {
8691 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
8692 *total_ielen += ielen;
8693 }
8694 else
8695 {
8696 hddLog( VOS_TRACE_LEVEL_ERROR,
8697 "IE Length is too big "
8698 "IEs eid=%d elem_len=%d total_ie_lent=%d",
8699 elem_id, elem_len, *total_ielen);
8700 }
8701 }
8702 }
8703
8704 left -= elem_len;
8705 ptr += (elem_len + 2);
8706 }
8707 return;
8708}
8709
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008710#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008711static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
8712 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008713#else
8714static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
8715 struct cfg80211_beacon_data *params)
8716#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008717{
8718 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308719 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008720 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07008721 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008722
8723 genie = vos_mem_malloc(MAX_GENIE_LEN);
8724
8725 if(genie == NULL) {
8726
8727 return -ENOMEM;
8728 }
8729
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308730 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8731 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07008732 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308733 hddLog(LOGE,
8734 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308735 ret = -EINVAL;
8736 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008737 }
8738
8739#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308740 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8741 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
8742 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308743 hddLog(LOGE,
8744 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308745 ret = -EINVAL;
8746 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008747 }
8748#endif
8749
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308750 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8751 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07008752 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308753 hddLog(LOGE,
8754 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308755 ret = -EINVAL;
8756 goto done;
8757 }
8758
8759 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
8760 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008761 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07008762 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008763
8764 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8765 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
8766 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
8767 {
8768 hddLog(LOGE,
8769 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008770 ret = -EINVAL;
8771 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008772 }
8773
8774 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8775 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
8776 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8777 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8778 ==eHAL_STATUS_FAILURE)
8779 {
8780 hddLog(LOGE,
8781 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008782 ret = -EINVAL;
8783 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008784 }
8785
8786 // Added for ProResp IE
8787 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
8788 {
8789 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
8790 u8 probe_rsp_ie_len[3] = {0};
8791 u8 counter = 0;
8792 /* Check Probe Resp Length if it is greater then 255 then Store
8793 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
8794 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
8795 Store More then 255 bytes into One Variable.
8796 */
8797 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
8798 {
8799 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
8800 {
8801 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
8802 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
8803 }
8804 else
8805 {
8806 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
8807 rem_probe_resp_ie_len = 0;
8808 }
8809 }
8810
8811 rem_probe_resp_ie_len = 0;
8812
8813 if (probe_rsp_ie_len[0] > 0)
8814 {
8815 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8816 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
8817 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
8818 probe_rsp_ie_len[0], NULL,
8819 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8820 {
8821 hddLog(LOGE,
8822 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008823 ret = -EINVAL;
8824 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008825 }
8826 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
8827 }
8828
8829 if (probe_rsp_ie_len[1] > 0)
8830 {
8831 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8832 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
8833 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
8834 probe_rsp_ie_len[1], NULL,
8835 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8836 {
8837 hddLog(LOGE,
8838 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008839 ret = -EINVAL;
8840 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008841 }
8842 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
8843 }
8844
8845 if (probe_rsp_ie_len[2] > 0)
8846 {
8847 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8848 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
8849 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
8850 probe_rsp_ie_len[2], NULL,
8851 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8852 {
8853 hddLog(LOGE,
8854 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008855 ret = -EINVAL;
8856 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008857 }
8858 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
8859 }
8860
8861 if (probe_rsp_ie_len[1] == 0 )
8862 {
8863 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8864 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
8865 eANI_BOOLEAN_FALSE) )
8866 {
8867 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008868 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008869 }
8870 }
8871
8872 if (probe_rsp_ie_len[2] == 0 )
8873 {
8874 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8875 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
8876 eANI_BOOLEAN_FALSE) )
8877 {
8878 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008879 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008880 }
8881 }
8882
8883 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8884 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
8885 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8886 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8887 == eHAL_STATUS_FAILURE)
8888 {
8889 hddLog(LOGE,
8890 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008891 ret = -EINVAL;
8892 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008893 }
8894 }
8895 else
8896 {
8897 // Reset WNI_CFG_PROBE_RSP Flags
8898 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
8899
8900 hddLog(VOS_TRACE_LEVEL_INFO,
8901 "%s: No Probe Response IE received in set beacon",
8902 __func__);
8903 }
8904
8905 // Added for AssocResp IE
8906 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
8907 {
8908 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8909 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
8910 params->assocresp_ies_len, NULL,
8911 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8912 {
8913 hddLog(LOGE,
8914 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008915 ret = -EINVAL;
8916 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008917 }
8918
8919 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8920 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
8921 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8922 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8923 == eHAL_STATUS_FAILURE)
8924 {
8925 hddLog(LOGE,
8926 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008927 ret = -EINVAL;
8928 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008929 }
8930 }
8931 else
8932 {
8933 hddLog(VOS_TRACE_LEVEL_INFO,
8934 "%s: No Assoc Response IE received in set beacon",
8935 __func__);
8936
8937 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8938 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
8939 eANI_BOOLEAN_FALSE) )
8940 {
8941 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008942 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008943 }
8944 }
8945
Jeff Johnsone7245742012-09-05 17:12:55 -07008946done:
Jeff Johnson295189b2012-06-20 16:38:30 -07008947 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308948 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008949}
Jeff Johnson295189b2012-06-20 16:38:30 -07008950
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308951/*
Jeff Johnson295189b2012-06-20 16:38:30 -07008952 * FUNCTION: wlan_hdd_validate_operation_channel
8953 * called by wlan_hdd_cfg80211_start_bss() and
8954 * wlan_hdd_cfg80211_set_channel()
8955 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308956 * channel list.
8957 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07008958VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07008959{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308960
Jeff Johnson295189b2012-06-20 16:38:30 -07008961 v_U32_t num_ch = 0;
8962 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
8963 u32 indx = 0;
8964 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308965 v_U8_t fValidChannel = FALSE, count = 0;
8966 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308967
Jeff Johnson295189b2012-06-20 16:38:30 -07008968 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
8969
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308970 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07008971 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308972 /* Validate the channel */
8973 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07008974 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308975 if ( channel == rfChannels[count].channelNum )
8976 {
8977 fValidChannel = TRUE;
8978 break;
8979 }
8980 }
8981 if (fValidChannel != TRUE)
8982 {
8983 hddLog(VOS_TRACE_LEVEL_ERROR,
8984 "%s: Invalid Channel [%d]", __func__, channel);
8985 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008986 }
8987 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308988 else
Jeff Johnson295189b2012-06-20 16:38:30 -07008989 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308990 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
8991 valid_ch, &num_ch))
8992 {
8993 hddLog(VOS_TRACE_LEVEL_ERROR,
8994 "%s: failed to get valid channel list", __func__);
8995 return VOS_STATUS_E_FAILURE;
8996 }
8997 for (indx = 0; indx < num_ch; indx++)
8998 {
8999 if (channel == valid_ch[indx])
9000 {
9001 break;
9002 }
9003 }
9004
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05309005 if (indx >= num_ch)
9006 {
9007 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
9008 {
9009 eCsrBand band;
9010 unsigned int freq;
9011
9012 sme_GetFreqBand(hHal, &band);
9013
9014 if (eCSR_BAND_5G == band)
9015 {
9016#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
9017 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
9018 {
9019 freq = ieee80211_channel_to_frequency(channel,
9020 IEEE80211_BAND_2GHZ);
9021 }
9022 else
9023 {
9024 freq = ieee80211_channel_to_frequency(channel,
9025 IEEE80211_BAND_5GHZ);
9026 }
9027#else
9028 freq = ieee80211_channel_to_frequency(channel);
9029#endif
9030 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
9031 return VOS_STATUS_SUCCESS;
9032 }
9033 }
9034
9035 hddLog(VOS_TRACE_LEVEL_ERROR,
9036 "%s: Invalid Channel [%d]", __func__, channel);
9037 return VOS_STATUS_E_FAILURE;
9038 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009039 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05309040
Jeff Johnson295189b2012-06-20 16:38:30 -07009041 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309042
Jeff Johnson295189b2012-06-20 16:38:30 -07009043}
9044
Viral Modi3a32cc52013-02-08 11:14:52 -08009045/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309046 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08009047 * This function is used to set the channel number
9048 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309049static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08009050 struct ieee80211_channel *chan,
9051 enum nl80211_channel_type channel_type
9052 )
9053{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309054 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08009055 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07009056 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08009057 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309058 hdd_context_t *pHddCtx;
9059 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009060
9061 ENTER();
9062
9063 if( NULL == dev )
9064 {
9065 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009066 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08009067 return -ENODEV;
9068 }
9069 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309070
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309071 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9072 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
9073 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08009074 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309075 "%s: device_mode = %s (%d) freq = %d", __func__,
9076 hdd_device_modetoString(pAdapter->device_mode),
9077 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309078
9079 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9080 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309081 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08009082 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309083 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009084 }
9085
9086 /*
9087 * Do freq to chan conversion
9088 * TODO: for 11a
9089 */
9090
9091 channel = ieee80211_frequency_to_channel(freq);
9092
9093 /* Check freq range */
9094 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
9095 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
9096 {
9097 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009098 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08009099 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
9100 WNI_CFG_CURRENT_CHANNEL_STAMAX);
9101 return -EINVAL;
9102 }
9103
9104 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
9105
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05309106 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
9107 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08009108 {
9109 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
9110 {
9111 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009112 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08009113 return -EINVAL;
9114 }
9115 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
9116 "%s: set channel to [%d] for device mode =%d",
9117 __func__, channel,pAdapter->device_mode);
9118 }
9119 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08009120 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08009121 )
9122 {
9123 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9124 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
9125 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9126
9127 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
9128 {
9129 /* Link is up then return cant set channel*/
9130 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009131 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08009132 return -EINVAL;
9133 }
9134
9135 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
9136 pHddStaCtx->conn_info.operationChannel = channel;
9137 pRoamProfile->ChannelInfo.ChannelList =
9138 &pHddStaCtx->conn_info.operationChannel;
9139 }
9140 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08009141 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08009142 )
9143 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309144 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
9145 {
9146 if(VOS_STATUS_SUCCESS !=
9147 wlan_hdd_validate_operation_channel(pAdapter,channel))
9148 {
9149 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009150 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309151 return -EINVAL;
9152 }
9153 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
9154 }
9155 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08009156 {
9157 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
9158
9159 /* If auto channel selection is configured as enable/ 1 then ignore
9160 channel set by supplicant
9161 */
9162 if ( cfg_param->apAutoChannelSelection )
9163 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309164 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
9165 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08009166 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309167 "%s: set channel to auto channel (0) for device mode =%s (%d)",
9168 __func__, hdd_device_modetoString(pAdapter->device_mode),
9169 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08009170 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309171 else
9172 {
9173 if(VOS_STATUS_SUCCESS !=
9174 wlan_hdd_validate_operation_channel(pAdapter,channel))
9175 {
9176 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009177 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309178 return -EINVAL;
9179 }
9180 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
9181 }
Viral Modi3a32cc52013-02-08 11:14:52 -08009182 }
9183 }
9184 else
9185 {
9186 hddLog(VOS_TRACE_LEVEL_FATAL,
9187 "%s: Invalid device mode failed to set valid channel", __func__);
9188 return -EINVAL;
9189 }
9190 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309191 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009192}
9193
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309194static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
9195 struct net_device *dev,
9196 struct ieee80211_channel *chan,
9197 enum nl80211_channel_type channel_type
9198 )
9199{
9200 int ret;
9201
9202 vos_ssr_protect(__func__);
9203 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
9204 vos_ssr_unprotect(__func__);
9205
9206 return ret;
9207}
9208
Anurag Chouhan83026002016-12-13 22:46:21 +05309209#ifdef DHCP_SERVER_OFFLOAD
9210void hdd_dhcp_server_offload_done(void *fw_dhcp_srv_offload_cb_context,
9211 VOS_STATUS status)
9212{
9213 hdd_adapter_t* adapter = (hdd_adapter_t*)fw_dhcp_srv_offload_cb_context;
9214
9215 ENTER();
9216
9217 if (NULL == adapter)
9218 {
9219 hddLog(VOS_TRACE_LEVEL_ERROR,
9220 "%s: adapter is NULL",__func__);
9221 return;
9222 }
9223
9224 adapter->dhcp_status.dhcp_offload_status = status;
9225 vos_event_set(&adapter->dhcp_status.vos_event);
9226 return;
9227}
9228
9229/**
9230 * wlan_hdd_set_dhcp_server_offload() - set dhcp server offload
9231 * @hostapd_adapter: pointer to hostapd adapter.
9232 *
9233 * Return: None
9234 */
9235static VOS_STATUS wlan_hdd_set_dhcp_server_offload(hdd_adapter_t *hostapd_adapter)
9236{
9237 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter);
9238 sir_dhcp_srv_offload_info dhcp_srv_info;
9239 tANI_U8 num_entries = 0;
9240 tANI_U8 srv_ip[IPADDR_NUM_ENTRIES];
9241 tANI_U8 num;
9242 tANI_U32 temp;
9243 VOS_STATUS ret;
9244
9245 ENTER();
9246
9247 ret = wlan_hdd_validate_context(hdd_ctx);
9248 if (0 != ret)
9249 return VOS_STATUS_E_INVAL;
9250
9251 /* Prepare the request to send to SME */
9252 dhcp_srv_info = vos_mem_malloc(sizeof(*dhcp_srv_info));
9253 if (NULL == dhcp_srv_info) {
9254 hddLog(VOS_TRACE_LEVEL_ERROR,
9255 "%s: could not allocate tDhcpSrvOffloadInfo!", __func__);
9256 return VOS_STATUS_E_NOMEM;
9257 }
9258
9259 vos_mem_zero(dhcp_srv_info, sizeof(*dhcp_srv_info));
9260
9261 dhcp_srv_info->bssidx = hostapd_adapter->sessionId;
9262 dhcp_srv_info->dhcp_srv_offload_enabled = TRUE;
9263 dhcp_srv_info->dhcp_client_num = hdd_ctx->cfg_ini->dhcp_max_num_clients;
9264 dhcp_srv_info->start_lsb = hdd_ctx->cfg_ini->dhcp_start_lsb;
9265 dhcp_srv_info->dhcp_offload_callback = hdd_dhcp_server_offload_done;
9266 dhcp_srv_info->dhcp_server_offload_cb_context = hostapd_adapter;
9267
9268 hdd_string_to_u8_array(hdd_ctx->cfg_ini->dhcp_srv_ip,
9269 srv_ip,
9270 &num_entries,
Anurag Chouhanac145c22016-11-22 16:51:47 +05309271 IPADDR_NUM_ENTRIES, ".");
Anurag Chouhan83026002016-12-13 22:46:21 +05309272 if (num_entries != IPADDR_NUM_ENTRIES) {
9273 hddLog(VOS_TRACE_LEVEL_ERROR,
9274 "%s: incorrect IP address (%s) assigned for DHCP server!",
9275 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
9276 vos_mem_free(dhcp_srv_info);
9277 return VOS_STATUS_E_FAILURE;
9278 }
9279
9280 if ((srv_ip[0] >= 224) && (srv_ip[0] <= 239)) {
9281 hddLog(VOS_TRACE_LEVEL_ERROR,
9282 "%s: invalid IP address (%s)! It could NOT be multicast IP address!",
9283 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
9284 vos_mem_free(dhcp_srv_info);
9285 return VOS_STATUS_E_FAILURE;
9286 }
9287
9288 if (srv_ip[IPADDR_NUM_ENTRIES-1] >= DHCP_START_POOL_ADDRESS) {
9289 hddLog(VOS_TRACE_LEVEL_ERROR,
9290 "%s: invalid IP address (%s)! The last field must be less than 100!",
9291 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
9292 vos_mem_free(dhcp_srv_info);
9293 return VOS_STATUS_E_FAILURE;
9294 }
9295
9296 for (num = 0; num < num_entries; num++) {
9297 temp = srv_ip[num];
9298 dhcp_srv_info->dhcp_srv_ip |= (temp << (8 * num));
9299 }
9300
9301 if (eHAL_STATUS_SUCCESS !=
9302 sme_set_dhcp_srv_offload(hdd_ctx->hHal, dhcp_srv_info)) {
9303 hddLog(VOS_TRACE_LEVEL_ERROR,
9304 "%s: sme_set_dhcp_srv_offload fail!", __func__);
9305 vos_mem_free(dhcp_srv_info);
9306 return VOS_STATUS_E_FAILURE;
9307 }
9308
9309 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
9310 "%s: enable DHCP Server offload successfully!", __func__);
9311
9312 vos_mem_free(dhcp_srv_info);
9313 return 0;
9314}
9315#endif /* DHCP_SERVER_OFFLOAD */
9316
Jeff Johnson295189b2012-06-20 16:38:30 -07009317#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9318static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
9319 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009320#else
9321static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
9322 struct cfg80211_beacon_data *params,
9323 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309324 enum nl80211_hidden_ssid hidden_ssid,
9325 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009326#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009327{
9328 tsap_Config_t *pConfig;
9329 beacon_data_t *pBeacon = NULL;
9330 struct ieee80211_mgmt *pMgmt_frame;
9331 v_U8_t *pIe=NULL;
9332 v_U16_t capab_info;
9333 eCsrAuthType RSNAuthType;
9334 eCsrEncryptionType RSNEncryptType;
9335 eCsrEncryptionType mcRSNEncryptType;
9336 int status = VOS_STATUS_SUCCESS;
9337 tpWLAN_SAPEventCB pSapEventCallback;
9338 hdd_hostapd_state_t *pHostapdState;
9339 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
9340 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309341 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009342 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309343 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07009344 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08009345 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05309346 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07009347 v_BOOL_t MFPCapable = VOS_FALSE;
9348 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309349 v_BOOL_t sapEnable11AC =
9350 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Jeff Johnson295189b2012-06-20 16:38:30 -07009351 ENTER();
9352
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309353 iniConfig = pHddCtx->cfg_ini;
9354
Jeff Johnson295189b2012-06-20 16:38:30 -07009355 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
9356
9357 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9358
9359 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9360
9361 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9362
9363 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
9364
9365 //channel is already set in the set_channel Call back
9366 //pConfig->channel = pCommitConfig->channel;
9367
9368 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309369 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07009370 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
9371
9372 pConfig->dtim_period = pBeacon->dtim_period;
9373
Arif Hussain6d2a3322013-11-17 19:50:10 -08009374 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07009375 pConfig->dtim_period);
9376
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08009377 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07009378 {
9379 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07009380 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05309381 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
9382 {
9383 tANI_BOOLEAN restartNeeded;
9384 pConfig->ieee80211d = 1;
9385 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
9386 sme_setRegInfo(hHal, pConfig->countryCode);
9387 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
9388 }
9389 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009390 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07009391 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07009392 pConfig->ieee80211d = 1;
9393 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
9394 sme_setRegInfo(hHal, pConfig->countryCode);
9395 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07009396 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07009397 else
9398 {
9399 pConfig->ieee80211d = 0;
9400 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309401 /*
9402 * If auto channel is configured i.e. channel is 0,
9403 * so skip channel validation.
9404 */
9405 if( AUTO_CHANNEL_SELECT != pConfig->channel )
9406 {
9407 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
9408 {
9409 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009410 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309411 return -EINVAL;
9412 }
9413 }
9414 else
9415 {
9416 if(1 != pHddCtx->is_dynamic_channel_range_set)
9417 {
9418 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
9419 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
9420 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
9421 }
9422 pHddCtx->is_dynamic_channel_range_set = 0;
9423 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009424 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07009425 else
Jeff Johnson295189b2012-06-20 16:38:30 -07009426 {
9427 pConfig->ieee80211d = 0;
9428 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309429
9430#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9431 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
9432 pConfig->authType = eSAP_OPEN_SYSTEM;
9433 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
9434 pConfig->authType = eSAP_SHARED_KEY;
9435 else
9436 pConfig->authType = eSAP_AUTO_SWITCH;
9437#else
9438 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
9439 pConfig->authType = eSAP_OPEN_SYSTEM;
9440 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
9441 pConfig->authType = eSAP_SHARED_KEY;
9442 else
9443 pConfig->authType = eSAP_AUTO_SWITCH;
9444#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009445
9446 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309447
9448 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07009449 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
Agrawal Ashisha8e8a722016-10-18 19:07:45 +05309450#ifdef SAP_AUTH_OFFLOAD
9451 /* In case of sap offload, hostapd.conf is configuted with open mode and
9452 * security is configured from ini file. Due to open mode in hostapd.conf
9453 * privacy bit is set to false which will result in not sending,
9454 * data packets as encrypted.
9455 * If enable_sap_auth_offload is enabled in ini and
9456 * sap_auth_offload_sec_type is type of WPA2-PSK,
9457 * driver will set privacy bit to 1.
9458 */
9459 if (pHddCtx->cfg_ini->enable_sap_auth_offload &&
9460 pHddCtx->cfg_ini->sap_auth_offload_sec_type)
9461 pConfig->privacy = VOS_TRUE;
9462#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009463
9464 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
9465
9466 /*Set wps station to configured*/
9467 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
9468
9469 if(pIe)
9470 {
9471 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
9472 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009473 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07009474 return -EINVAL;
9475 }
9476 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
9477 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07009478 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07009479 /* Check 15 bit of WPS IE as it contain information for wps state
9480 * WPS state
9481 */
9482 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
9483 {
9484 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
9485 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
9486 {
9487 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
9488 }
9489 }
9490 }
9491 else
9492 {
9493 pConfig->wps_state = SAP_WPS_DISABLED;
9494 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309495 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07009496
c_hpothufe599e92014-06-16 11:38:55 +05309497 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
9498 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
9499 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
9500 eCSR_ENCRYPT_TYPE_NONE;
9501
Jeff Johnson295189b2012-06-20 16:38:30 -07009502 pConfig->RSNWPAReqIELength = 0;
9503 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309504 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07009505 WLAN_EID_RSN);
9506 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309507 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009508 pConfig->RSNWPAReqIELength = pIe[1] + 2;
9509 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
9510 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309511 /* The actual processing may eventually be more extensive than
9512 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07009513 * by the app.
9514 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309515 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07009516 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
9517 &RSNEncryptType,
9518 &mcRSNEncryptType,
9519 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08009520 &MFPCapable,
9521 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07009522 pConfig->pRSNWPAReqIE[1]+2,
9523 pConfig->pRSNWPAReqIE );
9524
9525 if( VOS_STATUS_SUCCESS == status )
9526 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309527 /* Now copy over all the security attributes you have
9528 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07009529 * */
9530 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
9531 pConfig->mcRSNEncryptType = mcRSNEncryptType;
9532 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
9533 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309534 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08009535 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009536 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
9537 }
9538 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309539
Jeff Johnson295189b2012-06-20 16:38:30 -07009540 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9541 pBeacon->tail, pBeacon->tail_len);
9542
9543 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
9544 {
9545 if (pConfig->pRSNWPAReqIE)
9546 {
9547 /*Mixed mode WPA/WPA2*/
9548 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
9549 pConfig->RSNWPAReqIELength += pIe[1] + 2;
9550 }
9551 else
9552 {
9553 pConfig->RSNWPAReqIELength = pIe[1] + 2;
9554 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
9555 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309556 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07009557 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
9558 &RSNEncryptType,
9559 &mcRSNEncryptType,
9560 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08009561 &MFPCapable,
9562 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07009563 pConfig->pRSNWPAReqIE[1]+2,
9564 pConfig->pRSNWPAReqIE );
9565
9566 if( VOS_STATUS_SUCCESS == status )
9567 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309568 /* Now copy over all the security attributes you have
9569 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07009570 * */
9571 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
9572 pConfig->mcRSNEncryptType = mcRSNEncryptType;
9573 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
9574 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309575 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08009576 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009577 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
9578 }
9579 }
9580 }
9581
Jeff Johnson4416a782013-03-25 14:17:50 -07009582 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
9583 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
9584 return -EINVAL;
9585 }
9586
Jeff Johnson295189b2012-06-20 16:38:30 -07009587 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
9588
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009589#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009590 if (params->ssid != NULL)
9591 {
9592 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
9593 pConfig->SSIDinfo.ssid.length = params->ssid_len;
9594 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
9595 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
9596 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009597#else
9598 if (ssid != NULL)
9599 {
9600 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
9601 pConfig->SSIDinfo.ssid.length = ssid_len;
9602 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
9603 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
9604 }
9605#endif
9606
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309607 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07009608 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309609
Jeff Johnson295189b2012-06-20 16:38:30 -07009610 /* default value */
9611 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
9612 pConfig->num_accept_mac = 0;
9613 pConfig->num_deny_mac = 0;
9614
9615 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9616 pBeacon->tail, pBeacon->tail_len);
9617
9618 /* pIe for black list is following form:
9619 type : 1 byte
9620 length : 1 byte
9621 OUI : 4 bytes
9622 acl type : 1 byte
9623 no of mac addr in black list: 1 byte
9624 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309625 */
9626 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009627 {
9628 pConfig->SapMacaddr_acl = pIe[6];
9629 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08009630 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009631 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309632 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
9633 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009634 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
9635 for (i = 0; i < pConfig->num_deny_mac; i++)
9636 {
9637 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
9638 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309639 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009640 }
9641 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9642 pBeacon->tail, pBeacon->tail_len);
9643
9644 /* pIe for white list is following form:
9645 type : 1 byte
9646 length : 1 byte
9647 OUI : 4 bytes
9648 acl type : 1 byte
9649 no of mac addr in white list: 1 byte
9650 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309651 */
9652 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009653 {
9654 pConfig->SapMacaddr_acl = pIe[6];
9655 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08009656 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009657 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309658 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
9659 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009660 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
9661 for (i = 0; i < pConfig->num_accept_mac; i++)
9662 {
9663 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
9664 acl_entry++;
9665 }
9666 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309667
Jeff Johnson295189b2012-06-20 16:38:30 -07009668 wlan_hdd_set_sapHwmode(pHostapdAdapter);
9669
Jeff Johnsone7245742012-09-05 17:12:55 -07009670#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08009671 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309672 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
9673 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +05309674 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
9675 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08009676 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
9677 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309678 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
9679 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07009680 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309681 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07009682 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309683 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009684
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309685 /* If ACS disable and selected channel <= 14
9686 * OR
9687 * ACS enabled and ACS operating band is choosen as 2.4
9688 * AND
9689 * VHT in 2.4G Disabled
9690 * THEN
9691 * Fallback to 11N mode
9692 */
9693 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
9694 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +05309695 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309696 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009697 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309698 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
9699 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009700 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
9701 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009702 }
9703#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309704
Jeff Johnson295189b2012-06-20 16:38:30 -07009705 // ht_capab is not what the name conveys,this is used for protection bitmap
9706 pConfig->ht_capab =
9707 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
9708
9709 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
9710 {
9711 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
9712 return -EINVAL;
9713 }
9714
9715 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309716 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07009717 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
9718 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309719 pConfig->obssProtEnabled =
9720 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07009721
Chet Lanctot8cecea22014-02-11 19:09:36 -08009722#ifdef WLAN_FEATURE_11W
9723 pConfig->mfpCapable = MFPCapable;
9724 pConfig->mfpRequired = MFPRequired;
9725 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
9726 pConfig->mfpCapable, pConfig->mfpRequired);
9727#endif
9728
Arif Hussain6d2a3322013-11-17 19:50:10 -08009729 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07009730 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08009731 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
9732 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
9733 (int)pConfig->channel);
9734 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
9735 pConfig->SapHw_mode, pConfig->privacy,
9736 pConfig->authType);
9737 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
9738 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
9739 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
9740 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07009741
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309742 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07009743 {
9744 //Bss already started. just return.
9745 //TODO Probably it should update some beacon params.
9746 hddLog( LOGE, "Bss Already started...Ignore the request");
9747 EXIT();
9748 return 0;
9749 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309750
Agarwal Ashish51325b52014-06-16 16:50:49 +05309751 if (vos_max_concurrent_connections_reached()) {
9752 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
9753 return -EINVAL;
9754 }
9755
Jeff Johnson295189b2012-06-20 16:38:30 -07009756 pConfig->persona = pHostapdAdapter->device_mode;
9757
Peng Xu2446a892014-09-05 17:21:18 +05309758 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
9759 if ( NULL != psmeConfig)
9760 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05309761 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +05309762 sme_GetConfigParam(hHal, psmeConfig);
9763 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05309764#ifdef WLAN_FEATURE_AP_HT40_24G
9765 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
9766 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
9767 && pHddCtx->cfg_ini->apHT40_24GEnabled)
9768 {
9769 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
9770 sme_UpdateConfig (hHal, psmeConfig);
9771 }
9772#endif
Peng Xu2446a892014-09-05 17:21:18 +05309773 vos_mem_free(psmeConfig);
9774 }
Peng Xuafc34e32014-09-25 13:23:55 +05309775 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05309776
Jeff Johnson295189b2012-06-20 16:38:30 -07009777 pSapEventCallback = hdd_hostapd_SAPEventCB;
9778 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
9779 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
9780 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009781 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009782 return -EINVAL;
9783 }
9784
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309785 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07009786 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
9787
9788 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309789
Jeff Johnson295189b2012-06-20 16:38:30 -07009790 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309791 {
9792 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009793 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07009794 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07009795 VOS_ASSERT(0);
9796 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309797
Jeff Johnson295189b2012-06-20 16:38:30 -07009798 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Kaushik, Sushantf6070802014-10-15 15:09:23 +05309799 /* Initialize WMM configuation */
9800 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +05309801 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009802
Anurag Chouhan83026002016-12-13 22:46:21 +05309803#ifdef DHCP_SERVER_OFFLOAD
9804 /* set dhcp server offload */
9805 if (iniConfig->enable_dhcp_srv_offload &&
9806 sme_IsFeatureSupportedByFW(SAP_OFFLOADS)) {
9807 status = wlan_hdd_set_dhcp_server_offload(pHostapdAdapter);
9808 if (!VOS_IS_STATUS_SUCCESS(status))
9809 {
9810 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9811 ("HDD DHCP Server Offload Failed!!"));
9812 return -EINVAL;
9813 }
9814 vos_event_reset(&pHostapdAdapter->dhcp_status.vos_event);
9815 status = vos_wait_single_event(&pHostapdAdapter->dhcp_status.vos_event, 2000);
9816 if (!VOS_IS_STATUS_SUCCESS(status) || pHostapdAdapter->dhcp_status.dhcp_offload_status)
9817 {
9818 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9819 ("ERROR: DHCP HDD vos wait for single_event failed!! %d"),
9820 pHostapdAdapter->dhcp_status.dhcp_offload_status);
9821 return -EINVAL;
9822 }
9823 }
9824#endif /* DHCP_SERVER_OFFLOAD */
9825
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009826#ifdef WLAN_FEATURE_P2P_DEBUG
9827 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
9828 {
9829 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
9830 {
9831 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
9832 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08009833 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009834 }
9835 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
9836 {
9837 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
9838 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08009839 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009840 }
9841 }
9842#endif
9843
Jeff Johnson295189b2012-06-20 16:38:30 -07009844 pHostapdState->bCommit = TRUE;
9845 EXIT();
9846
9847 return 0;
9848}
9849
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009850#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309851static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309852 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07009853 struct beacon_parameters *params)
9854{
9855 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309856 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309857 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009858
9859 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309860
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309861 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9862 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
9863 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309864 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
9865 hdd_device_modetoString(pAdapter->device_mode),
9866 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009867
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309868 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9869 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309870 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009871 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309872 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009873 }
9874
Agarwal Ashish51325b52014-06-16 16:50:49 +05309875 if (vos_max_concurrent_connections_reached()) {
9876 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
9877 return -EINVAL;
9878 }
9879
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309880 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009881 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07009882 )
9883 {
9884 beacon_data_t *old,*new;
9885
9886 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309887
Jeff Johnson295189b2012-06-20 16:38:30 -07009888 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309889 {
9890 hddLog(VOS_TRACE_LEVEL_WARN,
9891 FL("already beacon info added to session(%d)"),
9892 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009893 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309894 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009895
9896 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
9897
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309898 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07009899 {
9900 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009901 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009902 return -EINVAL;
9903 }
9904
9905 pAdapter->sessionCtx.ap.beacon = new;
9906
9907 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
9908 }
9909
9910 EXIT();
9911 return status;
9912}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309913
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309914static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
9915 struct net_device *dev,
9916 struct beacon_parameters *params)
9917{
9918 int ret;
9919
9920 vos_ssr_protect(__func__);
9921 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
9922 vos_ssr_unprotect(__func__);
9923
9924 return ret;
9925}
9926
9927static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009928 struct net_device *dev,
9929 struct beacon_parameters *params)
9930{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309931 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309932 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9933 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309934 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009935
9936 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309937
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309938 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9939 TRACE_CODE_HDD_CFG80211_SET_BEACON,
9940 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
9941 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9942 __func__, hdd_device_modetoString(pAdapter->device_mode),
9943 pAdapter->device_mode);
9944
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309945 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9946 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309947 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009948 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309949 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009950 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309951
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309952 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009953 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309954 )
Jeff Johnson295189b2012-06-20 16:38:30 -07009955 {
9956 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309957
Jeff Johnson295189b2012-06-20 16:38:30 -07009958 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309959
Jeff Johnson295189b2012-06-20 16:38:30 -07009960 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309961 {
9962 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9963 FL("session(%d) old and new heads points to NULL"),
9964 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009965 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309966 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009967
9968 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
9969
9970 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309971 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009972 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009973 return -EINVAL;
9974 }
9975
9976 pAdapter->sessionCtx.ap.beacon = new;
9977
9978 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
9979 }
9980
9981 EXIT();
9982 return status;
9983}
9984
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309985static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
9986 struct net_device *dev,
9987 struct beacon_parameters *params)
9988{
9989 int ret;
9990
9991 vos_ssr_protect(__func__);
9992 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
9993 vos_ssr_unprotect(__func__);
9994
9995 return ret;
9996}
9997
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009998#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9999
10000#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010001static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010002 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010003#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010004static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010005 struct net_device *dev)
10006#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010007{
10008 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -070010009 hdd_context_t *pHddCtx = NULL;
10010 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010011 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010012 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010013
10014 ENTER();
10015
10016 if (NULL == pAdapter)
10017 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010018 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010019 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010020 return -ENODEV;
10021 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010022
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010023 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10024 TRACE_CODE_HDD_CFG80211_STOP_AP,
10025 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010026 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10027 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010028 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010029 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010030 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -070010031 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010032
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010033 pScanInfo = &pHddCtx->scan_info;
10034
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010035 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10036 __func__, hdd_device_modetoString(pAdapter->device_mode),
10037 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010038
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010039 ret = wlan_hdd_scan_abort(pAdapter);
10040
Girish Gowli4bf7a632014-06-12 13:42:11 +053010041 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -070010042 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010043 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10044 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010045
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010046 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -070010047 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010048 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10049 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -080010050
Jeff Johnsone7245742012-09-05 17:12:55 -070010051 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010052 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -070010053 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010054 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070010055 }
10056
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010057 /* Delete all associated STAs before stopping AP/P2P GO */
10058 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +053010059 hdd_hostapd_stop(dev);
10060
Jeff Johnson295189b2012-06-20 16:38:30 -070010061 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010062 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070010063 )
10064 {
10065 beacon_data_t *old;
10066
10067 old = pAdapter->sessionCtx.ap.beacon;
10068
10069 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010070 {
10071 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10072 FL("session(%d) beacon data points to NULL"),
10073 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070010074 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010075 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010076
Jeff Johnson295189b2012-06-20 16:38:30 -070010077 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010078
10079 mutex_lock(&pHddCtx->sap_lock);
10080 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
10081 {
Jeff Johnson4416a782013-03-25 14:17:50 -070010082 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -070010083 {
10084 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
10085
10086 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
10087
10088 if (!VOS_IS_STATUS_SUCCESS(status))
10089 {
10090 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010091 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -070010092 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010093 }
10094 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010095 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010096 /* BSS stopped, clear the active sessions for this device mode */
10097 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010098 }
10099 mutex_unlock(&pHddCtx->sap_lock);
10100
10101 if(status != VOS_STATUS_SUCCESS)
10102 {
10103 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010104 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010105 return -EINVAL;
10106 }
10107
Jeff Johnson4416a782013-03-25 14:17:50 -070010108 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070010109 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
10110 ==eHAL_STATUS_FAILURE)
10111 {
10112 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010113 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010114 }
10115
Jeff Johnson4416a782013-03-25 14:17:50 -070010116 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070010117 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
10118 eANI_BOOLEAN_FALSE) )
10119 {
10120 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010121 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010122 }
10123
10124 // Reset WNI_CFG_PROBE_RSP Flags
10125 wlan_hdd_reset_prob_rspies(pAdapter);
10126
10127 pAdapter->sessionCtx.ap.beacon = NULL;
10128 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010129#ifdef WLAN_FEATURE_P2P_DEBUG
10130 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
10131 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
10132 {
10133 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
10134 "GO got removed");
10135 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
10136 }
10137#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010138 }
10139 EXIT();
10140 return status;
10141}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010142
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010143#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10144static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
10145 struct net_device *dev)
10146{
10147 int ret;
10148
10149 vos_ssr_protect(__func__);
10150 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
10151 vos_ssr_unprotect(__func__);
10152
10153 return ret;
10154}
10155#else
10156static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
10157 struct net_device *dev)
10158{
10159 int ret;
10160
10161 vos_ssr_protect(__func__);
10162 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
10163 vos_ssr_unprotect(__func__);
10164
10165 return ret;
10166}
10167#endif
10168
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010169#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
10170
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010171static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010172 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010173 struct cfg80211_ap_settings *params)
10174{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010175 hdd_adapter_t *pAdapter;
10176 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010177 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010178
10179 ENTER();
10180
Girish Gowlib143d7a2015-02-18 19:39:55 +053010181 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010182 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010183 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +053010184 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010185 return -ENODEV;
10186 }
10187
10188 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
10189 if (NULL == pAdapter)
10190 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010191 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010192 "%s: HDD adapter is Null", __func__);
10193 return -ENODEV;
10194 }
10195
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010196 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10197 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
10198 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010199 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
10200 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010201 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010202 "%s: HDD adapter magic is invalid", __func__);
10203 return -ENODEV;
10204 }
10205
10206 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010207 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010208 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010209 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010210 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010211 }
10212
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010213 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
10214 __func__, hdd_device_modetoString(pAdapter->device_mode),
10215 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010216
10217 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010218 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010219 )
10220 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010221 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010222
10223 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010224
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010225 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010226 {
10227 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
10228 FL("already beacon info added to session(%d)"),
10229 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010230 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010231 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010232
Girish Gowlib143d7a2015-02-18 19:39:55 +053010233#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10234 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
10235 &new,
10236 &params->beacon);
10237#else
10238 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
10239 &new,
10240 &params->beacon,
10241 params->dtim_period);
10242#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010243
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010244 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010245 {
10246 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010247 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010248 return -EINVAL;
10249 }
10250 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -080010251#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -070010252 wlan_hdd_cfg80211_set_channel(wiphy, dev,
10253#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
10254 params->channel, params->channel_type);
10255#else
10256 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
10257#endif
Viral Modi3a32cc52013-02-08 11:14:52 -080010258#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010259 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010260 params->ssid_len, params->hidden_ssid,
10261 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010262 }
10263
10264 EXIT();
10265 return status;
10266}
10267
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010268static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
10269 struct net_device *dev,
10270 struct cfg80211_ap_settings *params)
10271{
10272 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010273
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010274 vos_ssr_protect(__func__);
10275 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
10276 vos_ssr_unprotect(__func__);
10277
10278 return ret;
10279}
10280
10281static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010282 struct net_device *dev,
10283 struct cfg80211_beacon_data *params)
10284{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010285 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010286 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010287 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010288
10289 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010290
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010291 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10292 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
10293 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -080010294 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010295 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010296
10297 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10298 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010299 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010300 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010301 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010302 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010303
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010304 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010305 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010306 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010307 {
10308 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010309
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010310 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010311
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010312 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010313 {
10314 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10315 FL("session(%d) beacon data points to NULL"),
10316 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010317 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010318 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010319
10320 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
10321
10322 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010323 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010324 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010325 return -EINVAL;
10326 }
10327
10328 pAdapter->sessionCtx.ap.beacon = new;
10329
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010330 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
10331 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010332 }
10333
10334 EXIT();
10335 return status;
10336}
10337
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010338static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
10339 struct net_device *dev,
10340 struct cfg80211_beacon_data *params)
10341{
10342 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010343
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010344 vos_ssr_protect(__func__);
10345 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
10346 vos_ssr_unprotect(__func__);
10347
10348 return ret;
10349}
10350
10351#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010352
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010353static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010354 struct net_device *dev,
10355 struct bss_parameters *params)
10356{
10357 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010358 hdd_context_t *pHddCtx;
10359 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010360
10361 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010362
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010363 if (NULL == pAdapter)
10364 {
10365 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10366 "%s: HDD adapter is Null", __func__);
10367 return -ENODEV;
10368 }
10369 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010370 ret = wlan_hdd_validate_context(pHddCtx);
10371 if (0 != ret)
10372 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010373 return ret;
10374 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010375 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10376 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
10377 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010378 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10379 __func__, hdd_device_modetoString(pAdapter->device_mode),
10380 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010381
10382 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010383 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010384 )
Jeff Johnson295189b2012-06-20 16:38:30 -070010385 {
10386 /* ap_isolate == -1 means that in change bss, upper layer doesn't
10387 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010388 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -070010389 {
10390 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010391 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010392 }
10393
10394 EXIT();
10395 return 0;
10396}
10397
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010398static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
10399 struct net_device *dev,
10400 struct bss_parameters *params)
10401{
10402 int ret;
10403
10404 vos_ssr_protect(__func__);
10405 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
10406 vos_ssr_unprotect(__func__);
10407
10408 return ret;
10409}
Kiet Lam10841362013-11-01 11:36:50 +053010410/* FUNCTION: wlan_hdd_change_country_code_cd
10411* to wait for contry code completion
10412*/
10413void* wlan_hdd_change_country_code_cb(void *pAdapter)
10414{
10415 hdd_adapter_t *call_back_pAdapter = pAdapter;
10416 complete(&call_back_pAdapter->change_country_code);
10417 return NULL;
10418}
10419
Jeff Johnson295189b2012-06-20 16:38:30 -070010420/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010421 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -070010422 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
10423 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010424int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010425 struct net_device *ndev,
10426 enum nl80211_iftype type,
10427 u32 *flags,
10428 struct vif_params *params
10429 )
10430{
10431 struct wireless_dev *wdev;
10432 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010433 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -070010434 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010435 tCsrRoamProfile *pRoamProfile = NULL;
10436 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010437 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010438 eMib_dot11DesiredBssType connectedBssType;
10439 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010440 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010441
10442 ENTER();
10443
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010444 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010445 {
10446 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10447 "%s: Adapter context is null", __func__);
10448 return VOS_STATUS_E_FAILURE;
10449 }
10450
10451 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10452 if (!pHddCtx)
10453 {
10454 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10455 "%s: HDD context is null", __func__);
10456 return VOS_STATUS_E_FAILURE;
10457 }
10458
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010459 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10460 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
10461 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010462 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010463 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010464 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010465 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010466 }
10467
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010468 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10469 __func__, hdd_device_modetoString(pAdapter->device_mode),
10470 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010471
Agarwal Ashish51325b52014-06-16 16:50:49 +053010472 if (vos_max_concurrent_connections_reached()) {
10473 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10474 return -EINVAL;
10475 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010476 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070010477 wdev = ndev->ieee80211_ptr;
10478
10479#ifdef WLAN_BTAMP_FEATURE
10480 if((NL80211_IFTYPE_P2P_CLIENT == type)||
10481 (NL80211_IFTYPE_ADHOC == type)||
10482 (NL80211_IFTYPE_AP == type)||
10483 (NL80211_IFTYPE_P2P_GO == type))
10484 {
10485 pHddCtx->isAmpAllowed = VOS_FALSE;
10486 // stop AMP traffic
10487 status = WLANBAP_StopAmp();
10488 if(VOS_STATUS_SUCCESS != status )
10489 {
10490 pHddCtx->isAmpAllowed = VOS_TRUE;
10491 hddLog(VOS_TRACE_LEVEL_FATAL,
10492 "%s: Failed to stop AMP", __func__);
10493 return -EINVAL;
10494 }
10495 }
10496#endif //WLAN_BTAMP_FEATURE
10497 /* Reset the current device mode bit mask*/
10498 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
10499
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +053010500 if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
10501 ((type == NL80211_IFTYPE_P2P_CLIENT) ||
10502 (type == NL80211_IFTYPE_P2P_GO)))
10503 {
10504 /* Notify Mode change in case of concurrency.
10505 * Below function invokes TDLS teardown Functionality Since TDLS is
10506 * not Supported in case of concurrency i.e Once P2P session
10507 * is detected disable offchannel and teardown TDLS links
10508 */
10509 hddLog(LOG1,
10510 FL("Device mode = %d Interface type = %d"),
10511 pAdapter->device_mode, type);
10512 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
10513 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +053010514
Jeff Johnson295189b2012-06-20 16:38:30 -070010515 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070010516 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -070010517 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -070010518 )
10519 {
10520 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010521 if (!pWextState)
10522 {
10523 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10524 "%s: pWextState is null", __func__);
10525 return VOS_STATUS_E_FAILURE;
10526 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010527 pRoamProfile = &pWextState->roamProfile;
10528 LastBSSType = pRoamProfile->BSSType;
10529
10530 switch (type)
10531 {
10532 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070010533 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070010534 hddLog(VOS_TRACE_LEVEL_INFO,
10535 "%s: setting interface Type to INFRASTRUCTURE", __func__);
10536 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -070010537#ifdef WLAN_FEATURE_11AC
10538 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
10539 {
10540 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
10541 }
10542#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010543 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -070010544 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010545 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010546 //Check for sub-string p2p to confirm its a p2p interface
10547 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010548 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +053010549#ifdef FEATURE_WLAN_TDLS
10550 mutex_lock(&pHddCtx->tdls_lock);
10551 wlan_hdd_tdls_exit(pAdapter, TRUE);
10552 mutex_unlock(&pHddCtx->tdls_lock);
10553#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010554 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
10555 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
10556 }
10557 else
10558 {
10559 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070010560 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010561 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010562 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +053010563
Jeff Johnson295189b2012-06-20 16:38:30 -070010564 case NL80211_IFTYPE_ADHOC:
10565 hddLog(VOS_TRACE_LEVEL_INFO,
10566 "%s: setting interface Type to ADHOC", __func__);
10567 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
10568 pRoamProfile->phyMode =
10569 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -070010570 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010571 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +053010572 hdd_set_ibss_ops( pAdapter );
10573 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +053010574
10575 status = hdd_sta_id_hash_attach(pAdapter);
10576 if (VOS_STATUS_SUCCESS != status) {
10577 hddLog(VOS_TRACE_LEVEL_ERROR,
10578 FL("Failed to initialize hash for IBSS"));
10579 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010580 break;
10581
10582 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070010583 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070010584 {
10585 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10586 "%s: setting interface Type to %s", __func__,
10587 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
10588
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010589 //Cancel any remain on channel for GO mode
10590 if (NL80211_IFTYPE_P2P_GO == type)
10591 {
10592 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
10593 }
Mohit Khanna0f232092012-09-11 14:46:08 -070010594 if (NL80211_IFTYPE_AP == type)
10595 {
10596 /* As Loading WLAN Driver one interface being created for p2p device
10597 * address. This will take one HW STA and the max number of clients
10598 * that can connect to softAP will be reduced by one. so while changing
10599 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
10600 * interface as it is not required in SoftAP mode.
10601 */
10602
10603 // Get P2P Adapter
10604 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
10605
10606 if (pP2pAdapter)
10607 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010608 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +053010609 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -070010610 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
10611 }
10612 }
Swaroop Goltia2e32212014-04-09 23:37:33 +053010613 //Disable IMPS & BMPS for SAP/GO
10614 if(VOS_STATUS_E_FAILURE ==
10615 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
10616 {
10617 //Fail to Exit BMPS
10618 VOS_ASSERT(0);
10619 }
Deepthi Gowri500fc472014-08-11 19:53:10 +053010620
10621 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
10622
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010623#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -070010624
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010625 /* A Mutex Lock is introduced while changing the mode to
10626 * protect the concurrent access for the Adapters by TDLS
10627 * module.
10628 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010629 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010630#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010631 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +053010632 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010633 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -070010634 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
10635 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010636#ifdef FEATURE_WLAN_TDLS
10637 mutex_unlock(&pHddCtx->tdls_lock);
10638#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070010639 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
10640 (pConfig->apRandomBssidEnabled))
10641 {
10642 /* To meet Android requirements create a randomized
10643 MAC address of the form 02:1A:11:Fx:xx:xx */
10644 get_random_bytes(&ndev->dev_addr[3], 3);
10645 ndev->dev_addr[0] = 0x02;
10646 ndev->dev_addr[1] = 0x1A;
10647 ndev->dev_addr[2] = 0x11;
10648 ndev->dev_addr[3] |= 0xF0;
10649 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
10650 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -080010651 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
10652 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070010653 }
10654
Jeff Johnson295189b2012-06-20 16:38:30 -070010655 hdd_set_ap_ops( pAdapter->dev );
10656
Kiet Lam10841362013-11-01 11:36:50 +053010657 /* This is for only SAP mode where users can
10658 * control country through ini.
10659 * P2P GO follows station country code
10660 * acquired during the STA scanning. */
10661 if((NL80211_IFTYPE_AP == type) &&
10662 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
10663 {
10664 int status = 0;
10665 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
10666 "%s: setting country code from INI ", __func__);
10667 init_completion(&pAdapter->change_country_code);
10668 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
10669 (void *)(tSmeChangeCountryCallback)
10670 wlan_hdd_change_country_code_cb,
10671 pConfig->apCntryCode, pAdapter,
10672 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053010673 eSIR_FALSE,
10674 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +053010675 if (eHAL_STATUS_SUCCESS == status)
10676 {
10677 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010678 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +053010679 &pAdapter->change_country_code,
10680 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010681 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +053010682 {
10683 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010684 FL("SME Timed out while setting country code %ld"),
10685 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -080010686
10687 if (pHddCtx->isLogpInProgress)
10688 {
10689 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10690 "%s: LOGP in Progress. Ignore!!!", __func__);
10691 return -EAGAIN;
10692 }
Kiet Lam10841362013-11-01 11:36:50 +053010693 }
10694 }
10695 else
10696 {
10697 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010698 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +053010699 return -EINVAL;
10700 }
10701 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010702 status = hdd_init_ap_mode(pAdapter);
10703 if(status != VOS_STATUS_SUCCESS)
10704 {
10705 hddLog(VOS_TRACE_LEVEL_FATAL,
10706 "%s: Error initializing the ap mode", __func__);
10707 return -EINVAL;
10708 }
10709 hdd_set_conparam(1);
10710
Nirav Shah7e3c8132015-06-22 23:51:42 +053010711 status = hdd_sta_id_hash_attach(pAdapter);
10712 if (VOS_STATUS_SUCCESS != status)
10713 {
10714 hddLog(VOS_TRACE_LEVEL_ERROR,
10715 FL("Failed to initialize hash for AP"));
10716 return -EINVAL;
10717 }
10718
Jeff Johnson295189b2012-06-20 16:38:30 -070010719 /*interface type changed update in wiphy structure*/
10720 if(wdev)
10721 {
10722 wdev->iftype = type;
10723 pHddCtx->change_iface = type;
10724 }
10725 else
10726 {
10727 hddLog(VOS_TRACE_LEVEL_ERROR,
10728 "%s: ERROR !!!! Wireless dev is NULL", __func__);
10729 return -EINVAL;
10730 }
10731 goto done;
10732 }
10733
10734 default:
10735 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
10736 __func__);
10737 return -EOPNOTSUPP;
10738 }
10739 }
10740 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010741 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070010742 )
10743 {
10744 switch(type)
10745 {
10746 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070010747 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070010748 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +053010749
10750 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010751#ifdef FEATURE_WLAN_TDLS
10752
10753 /* A Mutex Lock is introduced while changing the mode to
10754 * protect the concurrent access for the Adapters by TDLS
10755 * module.
10756 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010757 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010758#endif
c_hpothu002231a2015-02-05 14:58:51 +053010759 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010760 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010761 //Check for sub-string p2p to confirm its a p2p interface
10762 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010763 {
10764 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
10765 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
10766 }
10767 else
10768 {
10769 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070010770 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010771 }
Agrawal Ashishcfe83282016-09-29 13:03:45 +053010772
10773 /* set con_mode to STA only when no SAP concurrency mode */
10774 if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO)))
10775 hdd_set_conparam(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070010776 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070010777 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
10778 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010779#ifdef FEATURE_WLAN_TDLS
10780 mutex_unlock(&pHddCtx->tdls_lock);
10781#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +053010782 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -070010783 if( VOS_STATUS_SUCCESS != status )
10784 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -070010785 /* In case of JB, for P2P-GO, only change interface will be called,
10786 * This is the right place to enable back bmps_imps()
10787 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010788 if (pHddCtx->hdd_wlan_suspended)
10789 {
10790 hdd_set_pwrparams(pHddCtx);
10791 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010792 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010793 goto done;
10794 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070010795 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070010796 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070010797 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
10798 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -070010799 goto done;
10800 default:
10801 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
10802 __func__);
10803 return -EOPNOTSUPP;
10804
10805 }
10806
10807 }
10808 else
10809 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010810 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
10811 __func__, hdd_device_modetoString(pAdapter->device_mode),
10812 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010813 return -EOPNOTSUPP;
10814 }
10815
10816
10817 if(pRoamProfile)
10818 {
10819 if ( LastBSSType != pRoamProfile->BSSType )
10820 {
10821 /*interface type changed update in wiphy structure*/
10822 wdev->iftype = type;
10823
10824 /*the BSS mode changed, We need to issue disconnect
10825 if connected or in IBSS disconnect state*/
10826 if ( hdd_connGetConnectedBssType(
10827 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
10828 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
10829 {
10830 /*need to issue a disconnect to CSR.*/
10831 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10832 if( eHAL_STATUS_SUCCESS ==
10833 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10834 pAdapter->sessionId,
10835 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
10836 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010837 ret = wait_for_completion_interruptible_timeout(
10838 &pAdapter->disconnect_comp_var,
10839 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10840 if (ret <= 0)
10841 {
10842 hddLog(VOS_TRACE_LEVEL_ERROR,
10843 FL("wait on disconnect_comp_var failed %ld"), ret);
10844 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010845 }
10846 }
10847 }
10848 }
10849
10850done:
10851 /*set bitmask based on updated value*/
10852 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -070010853
10854 /* Only STA mode support TM now
10855 * all other mode, TM feature should be disabled */
10856 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
10857 (~VOS_STA & pHddCtx->concurrency_mode) )
10858 {
10859 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
10860 }
10861
Jeff Johnson295189b2012-06-20 16:38:30 -070010862#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010863 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053010864 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -070010865 {
10866 //we are ok to do AMP
10867 pHddCtx->isAmpAllowed = VOS_TRUE;
10868 }
10869#endif //WLAN_BTAMP_FEATURE
10870 EXIT();
10871 return 0;
10872}
10873
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010874/*
10875 * FUNCTION: wlan_hdd_cfg80211_change_iface
10876 * wrapper function to protect the actual implementation from SSR.
10877 */
10878int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
10879 struct net_device *ndev,
10880 enum nl80211_iftype type,
10881 u32 *flags,
10882 struct vif_params *params
10883 )
10884{
10885 int ret;
10886
10887 vos_ssr_protect(__func__);
10888 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
10889 vos_ssr_unprotect(__func__);
10890
10891 return ret;
10892}
10893
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010894#ifdef FEATURE_WLAN_TDLS
10895static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053010896 struct net_device *dev,
10897#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
10898 const u8 *mac,
10899#else
10900 u8 *mac,
10901#endif
10902 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010903{
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010904 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010905 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010906 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010907 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010908 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053010909 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010910
10911 ENTER();
10912
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010913 if (!dev) {
10914 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
10915 return -EINVAL;
10916 }
10917
10918 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
10919 if (!pAdapter) {
10920 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
10921 return -EINVAL;
10922 }
10923
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053010924 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010925 {
10926 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10927 "Invalid arguments");
10928 return -EINVAL;
10929 }
Hoonki Lee27511902013-03-14 18:19:06 -070010930
10931 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
10932 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
10933 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010934 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070010935 "%s: TDLS mode is disabled OR not enabled in FW."
10936 MAC_ADDRESS_STR " Request declined.",
10937 __func__, MAC_ADDR_ARRAY(mac));
10938 return -ENOTSUPP;
10939 }
10940
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010941 if (pHddCtx->isLogpInProgress)
10942 {
10943 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10944 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053010945 wlan_hdd_tdls_set_link_status(pAdapter,
10946 mac,
10947 eTDLS_LINK_IDLE,
10948 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010949 return -EBUSY;
10950 }
10951
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053010952 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +053010953 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010954
10955 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010956 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010957 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
10958 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053010959 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010960 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070010961 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010962
10963 /* in add station, we accept existing valid staId if there is */
10964 if ((0 == update) &&
10965 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
10966 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010967 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010968 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010969 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010970 " link_status %d. staId %d. add station ignored.",
10971 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010972 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010973 return 0;
10974 }
10975 /* in change station, we accept only when staId is valid */
10976 if ((1 == update) &&
10977 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
10978 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
10979 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010980 tANI_U16 staId = pTdlsPeer->staId;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010981 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010982 "%s: " MAC_ADDRESS_STR
10983 " link status %d. staId %d. change station %s.",
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010984 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, staId,
10985 (TDLS_STA_INDEX_VALID(staId)) ? "ignored" : "declined");
10986 mutex_unlock(&pHddCtx->tdls_lock);
10987 return (TDLS_STA_INDEX_VALID(staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010988 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010989 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070010990
10991 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053010992 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010993 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010994 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10995 "%s: " MAC_ADDRESS_STR
10996 " TDLS setup is ongoing. Request declined.",
10997 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -070010998 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010999 }
11000
11001 /* first to check if we reached to maximum supported TDLS peer.
11002 TODO: for now, return -EPERM looks working fine,
11003 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011004 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
11005 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011006 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011007 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11008 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011009 " TDLS Max peer already connected. Request declined."
11010 " Num of peers (%d), Max allowed (%d).",
11011 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
11012 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070011013 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011014 }
11015 else
11016 {
11017 hddTdlsPeer_t *pTdlsPeer;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011018 mutex_lock(&pHddCtx->tdls_lock);
11019 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011020 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011021 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011022 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011023 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11024 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
11025 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011026 return -EPERM;
11027 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011028 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011029 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011030 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +053011031 wlan_hdd_tdls_set_link_status(pAdapter,
11032 mac,
11033 eTDLS_LINK_CONNECTING,
11034 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011035
Jeff Johnsond75fe012013-04-06 10:53:06 -070011036 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053011037 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011038 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011039 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011040 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -070011041 if(StaParams->htcap_present)
11042 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011043 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070011044 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011045 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070011046 "ht_capa->extended_capabilities: %0x",
11047 StaParams->HTCap.extendedHtCapInfo);
11048 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011049 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011050 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011051 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011052 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -070011053 if(StaParams->vhtcap_present)
11054 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011055 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070011056 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
11057 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
11058 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
11059 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011060 {
11061 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011062 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011063 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011064 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011065 "[%d]: %x ", i, StaParams->supported_rates[i]);
11066 }
Jeff Johnsond75fe012013-04-06 10:53:06 -070011067 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053011068 else if ((1 == update) && (NULL == StaParams))
11069 {
11070 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11071 "%s : update is true, but staParams is NULL. Error!", __func__);
11072 return -EPERM;
11073 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011074
11075 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
11076
11077 if (!update)
11078 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053011079 /*Before adding sta make sure that device exited from BMPS*/
11080 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
11081 {
11082 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11083 "%s: Adding tdls peer sta. Disable BMPS", __func__);
11084 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
11085 if (status != VOS_STATUS_SUCCESS) {
11086 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
11087 }
11088 }
11089
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011090 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011091 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011092 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053011093 hddLog(VOS_TRACE_LEVEL_ERROR,
11094 FL("Failed to add TDLS peer STA. Enable Bmps"));
11095 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011096 return -EPERM;
11097 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011098 }
11099 else
11100 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011101 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011102 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011103 if (ret != eHAL_STATUS_SUCCESS) {
11104 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
11105 return -EPERM;
11106 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011107 }
11108
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011109 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011110 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
11111
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053011112 mutex_lock(&pHddCtx->tdls_lock);
11113 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
11114
Masti, Narayanraddi07262462016-01-19 12:40:06 +053011115 if ((pTdlsPeer != NULL) &&
11116 (pTdlsPeer->link_status == eTDLS_LINK_TEARING))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011117 {
Masti, Narayanraddi07262462016-01-19 12:40:06 +053011118 hddLog(VOS_TRACE_LEVEL_ERROR,
11119 FL("peer link status %u"), pTdlsPeer->link_status);
11120 mutex_unlock(&pHddCtx->tdls_lock);
11121 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011122 }
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053011123 mutex_unlock(&pHddCtx->tdls_lock);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011124
Masti, Narayanraddi07262462016-01-19 12:40:06 +053011125 if (ret <= 0)
11126 {
11127 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11128 "%s: timeout waiting for tdls add station indication %ld",
11129 __func__, ret);
11130 goto error;
11131 }
11132
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011133 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
11134 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011135 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011136 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070011137 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011138 }
11139
11140 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -070011141
11142error:
Atul Mittal115287b2014-07-08 13:26:33 +053011143 wlan_hdd_tdls_set_link_status(pAdapter,
11144 mac,
11145 eTDLS_LINK_IDLE,
11146 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -070011147 return -EPERM;
11148
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011149}
11150#endif
11151
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011152static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011153 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011154#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
11155 const u8 *mac,
11156#else
Jeff Johnson295189b2012-06-20 16:38:30 -070011157 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011158#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011159 struct station_parameters *params)
11160{
11161 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011162 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +053011163 hdd_context_t *pHddCtx;
11164 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011165 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011166 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070011167#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011168 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011169 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011170 tANI_U8 isOffChannelSupported = 0;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011171 tANI_U8 isQosWmmSta = FALSE;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070011172#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070011173
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011174 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011175
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011176 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +053011177 if ((NULL == pAdapter))
11178 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011179 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053011180 "invalid adapter ");
11181 return -EINVAL;
11182 }
11183
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011184 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11185 TRACE_CODE_HDD_CHANGE_STATION,
11186 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +053011187 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +053011188
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011189 ret = wlan_hdd_validate_context(pHddCtx);
11190 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +053011191 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011192 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +053011193 }
11194
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011195 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11196
11197 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011198 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011199 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11200 "invalid HDD station context");
11201 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011202 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011203 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
11204
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011205 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
11206 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -070011207 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011208 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -070011209 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011210 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -070011211 WLANTL_STA_AUTHENTICATED);
11212
Gopichand Nakkala29149562013-05-10 21:43:41 +053011213 if (status != VOS_STATUS_SUCCESS)
11214 {
11215 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11216 "%s: Not able to change TL state to AUTHENTICATED", __func__);
11217 return -EINVAL;
11218 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011219 }
11220 }
Hoonki Leea6d49be2013-04-05 09:43:25 -070011221 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
11222 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +053011223#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011224 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
11225 StaParams.capability = params->capability;
11226 StaParams.uapsd_queues = params->uapsd_queues;
11227 StaParams.max_sp = params->max_sp;
11228
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011229 /* Convert (first channel , number of channels) tuple to
11230 * the total list of channels. This goes with the assumption
11231 * that if the first channel is < 14, then the next channels
11232 * are an incremental of 1 else an incremental of 4 till the number
11233 * of channels.
11234 */
11235 if (0 != params->supported_channels_len) {
11236 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
11237 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
11238 {
11239 int wifi_chan_index;
11240 StaParams.supported_channels[j] = params->supported_channels[i];
11241 wifi_chan_index =
11242 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
11243 no_of_channels = params->supported_channels[i+1];
11244 for(k=1; k <= no_of_channels; k++)
11245 {
11246 StaParams.supported_channels[j+1] =
11247 StaParams.supported_channels[j] + wifi_chan_index;
11248 j+=1;
11249 }
11250 }
11251 StaParams.supported_channels_len = j;
11252 }
11253 vos_mem_copy(StaParams.supported_oper_classes,
11254 params->supported_oper_classes,
11255 params->supported_oper_classes_len);
11256 StaParams.supported_oper_classes_len =
11257 params->supported_oper_classes_len;
11258
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011259 if (0 != params->ext_capab_len)
11260 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
11261 sizeof(StaParams.extn_capability));
11262
11263 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070011264 {
11265 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011266 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070011267 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011268
11269 StaParams.supported_rates_len = params->supported_rates_len;
11270
11271 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
11272 * The supported_rates array , for all the structures propogating till Add Sta
11273 * to the firmware has to be modified , if the supplicant (ieee80211) is
11274 * modified to send more rates.
11275 */
11276
11277 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
11278 */
11279 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
11280 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
11281
11282 if (0 != StaParams.supported_rates_len) {
11283 int i = 0;
11284 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
11285 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011286 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011287 "Supported Rates with Length %d", StaParams.supported_rates_len);
11288 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011289 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011290 "[%d]: %0x", i, StaParams.supported_rates[i]);
11291 }
11292
11293 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070011294 {
11295 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011296 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070011297 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011298
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011299 if (0 != params->ext_capab_len ) {
11300 /*Define A Macro : TODO Sunil*/
11301 if ((1<<4) & StaParams.extn_capability[3]) {
11302 isBufSta = 1;
11303 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011304 /* TDLS Channel Switching Support */
11305 if ((1<<6) & StaParams.extn_capability[3]) {
11306 isOffChannelSupported = 1;
11307 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011308 }
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011309
11310 if (pHddCtx->cfg_ini->fEnableTDLSWmmMode &&
Nitesh Shah48df4c02016-08-12 16:27:33 +053011311 (params->ht_capa || params->vht_capa ||
11312 (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME))))
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011313 /* TDLS Peer is WME/QoS capable */
11314 isQosWmmSta = TRUE;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011315
11316 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11317 "%s: TDLS Peer is QOS capable isQosWmmSta= %d HTcapPresent= %d",
11318 __func__, isQosWmmSta, StaParams.htcap_present);
11319
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011320 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
11321 &StaParams, isBufSta,
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011322 isOffChannelSupported,
11323 isQosWmmSta);
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011324
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053011325 if (VOS_STATUS_SUCCESS != status) {
11326 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11327 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
11328 return -EINVAL;
11329 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011330 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
11331
11332 if (VOS_STATUS_SUCCESS != status) {
11333 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11334 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
11335 return -EINVAL;
11336 }
11337 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -070011338#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +053011339 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011340 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011341 return status;
11342}
11343
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011344#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
11345static int wlan_hdd_change_station(struct wiphy *wiphy,
11346 struct net_device *dev,
11347 const u8 *mac,
11348 struct station_parameters *params)
11349#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011350static int wlan_hdd_change_station(struct wiphy *wiphy,
11351 struct net_device *dev,
11352 u8 *mac,
11353 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011354#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011355{
11356 int ret;
11357
11358 vos_ssr_protect(__func__);
11359 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
11360 vos_ssr_unprotect(__func__);
11361
11362 return ret;
11363}
11364
Jeff Johnson295189b2012-06-20 16:38:30 -070011365/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011366 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011367 * This function is used to initialize the key information
11368 */
11369#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011370static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011371 struct net_device *ndev,
11372 u8 key_index, bool pairwise,
11373 const u8 *mac_addr,
11374 struct key_params *params
11375 )
11376#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011377static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011378 struct net_device *ndev,
11379 u8 key_index, const u8 *mac_addr,
11380 struct key_params *params
11381 )
11382#endif
11383{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011384 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070011385 tCsrRoamSetKey setKey;
11386 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011387 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011388 v_U32_t roamId= 0xFF;
11389 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011390 hdd_hostapd_state_t *pHostapdState;
11391 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011392 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011393 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011394
11395 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011396
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011397 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11398 TRACE_CODE_HDD_CFG80211_ADD_KEY,
11399 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011400 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11401 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011402 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011403 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011404 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011405 }
11406
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011407 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11408 __func__, hdd_device_modetoString(pAdapter->device_mode),
11409 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011410
11411 if (CSR_MAX_NUM_KEY <= key_index)
11412 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011413 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011414 key_index);
11415
11416 return -EINVAL;
11417 }
11418
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011419 if (CSR_MAX_KEY_LEN < params->key_len)
11420 {
11421 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
11422 params->key_len);
11423
11424 return -EINVAL;
11425 }
11426
11427 hddLog(VOS_TRACE_LEVEL_INFO,
11428 "%s: called with key index = %d & key length %d",
11429 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070011430
11431 /*extract key idx, key len and key*/
11432 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11433 setKey.keyId = key_index;
11434 setKey.keyLength = params->key_len;
11435 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
11436
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011437 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070011438 {
11439 case WLAN_CIPHER_SUITE_WEP40:
11440 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
11441 break;
11442
11443 case WLAN_CIPHER_SUITE_WEP104:
11444 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
11445 break;
11446
11447 case WLAN_CIPHER_SUITE_TKIP:
11448 {
11449 u8 *pKey = &setKey.Key[0];
11450 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
11451
11452 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
11453
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011454 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -070011455
11456 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011457 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070011458 |--------------|----------|----------|
11459 <---16bytes---><--8bytes--><--8bytes-->
11460
11461 */
11462 /*Sme expects the 32 bytes key to be in the below order
11463
11464 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011465 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070011466 |--------------|----------|----------|
11467 <---16bytes---><--8bytes--><--8bytes-->
11468 */
11469 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011470 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -070011471
11472 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011473 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070011474
11475 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011476 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070011477
11478
11479 break;
11480 }
11481
11482 case WLAN_CIPHER_SUITE_CCMP:
11483 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
11484 break;
11485
11486#ifdef FEATURE_WLAN_WAPI
11487 case WLAN_CIPHER_SUITE_SMS4:
11488 {
11489 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11490 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
11491 params->key, params->key_len);
11492 return 0;
11493 }
11494#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070011495
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011496#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011497 case WLAN_CIPHER_SUITE_KRK:
11498 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
11499 break;
11500#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070011501
11502#ifdef WLAN_FEATURE_11W
11503 case WLAN_CIPHER_SUITE_AES_CMAC:
11504 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -070011505 break;
Chet Lanctot186b5732013-03-18 10:26:30 -070011506#endif
11507
Jeff Johnson295189b2012-06-20 16:38:30 -070011508 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011509 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070011510 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011511 status = -EOPNOTSUPP;
11512 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011513 }
11514
11515 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
11516 __func__, setKey.encType);
11517
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011518 if (
Jeff Johnson295189b2012-06-20 16:38:30 -070011519#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11520 (!pairwise)
11521#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011522 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -070011523#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011524 )
11525 {
11526 /* set group key*/
11527 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11528 "%s- %d: setting Broadcast key",
11529 __func__, __LINE__);
11530 setKey.keyDirection = eSIR_RX_ONLY;
11531 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
11532 }
11533 else
11534 {
11535 /* set pairwise key*/
11536 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11537 "%s- %d: setting pairwise key",
11538 __func__, __LINE__);
11539 setKey.keyDirection = eSIR_TX_RX;
11540 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
11541 }
11542 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
11543 {
11544 setKey.keyDirection = eSIR_TX_RX;
11545 /*Set the group key*/
11546 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
11547 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -070011548
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011549 if ( 0 != status )
11550 {
11551 hddLog(VOS_TRACE_LEVEL_ERROR,
11552 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011553 status = -EINVAL;
11554 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011555 }
11556 /*Save the keys here and call sme_RoamSetKey for setting
11557 the PTK after peer joins the IBSS network*/
11558 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
11559 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011560 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011561 }
Gopichand Nakkala29149562013-05-10 21:43:41 +053011562 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
11563 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
11564 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011565 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011566 if( pHostapdState->bssState == BSS_START )
11567 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011568 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11569 vos_status = wlan_hdd_check_ula_done(pAdapter);
11570
11571 if ( vos_status != VOS_STATUS_SUCCESS )
11572 {
11573 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11574 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
11575 __LINE__, vos_status );
11576
11577 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
11578
11579 status = -EINVAL;
11580 goto end;
11581 }
11582
Jeff Johnson295189b2012-06-20 16:38:30 -070011583 status = WLANSAP_SetKeySta( pVosContext, &setKey);
11584
11585 if ( status != eHAL_STATUS_SUCCESS )
11586 {
11587 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11588 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
11589 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011590 status = -EINVAL;
11591 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011592 }
11593 }
11594
11595 /* Saving WEP keys */
11596 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
11597 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
11598 {
11599 //Save the wep key in ap context. Issue setkey after the BSS is started.
11600 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
11601 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
11602 }
11603 else
11604 {
11605 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011606 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011607 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
11608 }
11609 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011610 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
11611 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011612 {
11613 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11614 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11615
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011616#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11617 if (!pairwise)
11618#else
11619 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
11620#endif
11621 {
11622 /* set group key*/
11623 if (pHddStaCtx->roam_info.deferKeyComplete)
11624 {
11625 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11626 "%s- %d: Perform Set key Complete",
11627 __func__, __LINE__);
11628 hdd_PerformRoamSetKeyComplete(pAdapter);
11629 }
11630 }
11631
Jeff Johnson295189b2012-06-20 16:38:30 -070011632 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
11633
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -080011634 pWextState->roamProfile.Keys.defaultIndex = key_index;
11635
11636
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011637 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070011638 params->key, params->key_len);
11639
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011640
Jeff Johnson295189b2012-06-20 16:38:30 -070011641 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
11642
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011643 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070011644 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011645 __func__, setKey.peerMac[0], setKey.peerMac[1],
11646 setKey.peerMac[2], setKey.peerMac[3],
11647 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070011648 setKey.keyDirection);
11649
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011650 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +053011651
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011652 if ( vos_status != VOS_STATUS_SUCCESS )
11653 {
11654 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011655 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
11656 __LINE__, vos_status );
11657
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011658 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011659
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011660 status = -EINVAL;
11661 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011662
11663 }
11664
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011665#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011666 /* The supplicant may attempt to set the PTK once pre-authentication
11667 is done. Save the key in the UMAC and include it in the ADD BSS
11668 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011669 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011670 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011671 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011672 hddLog(VOS_TRACE_LEVEL_INFO_MED,
11673 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011674 status = 0;
11675 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011676 }
11677 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
11678 {
11679 hddLog(VOS_TRACE_LEVEL_ERROR,
11680 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011681 status = -EINVAL;
11682 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011683 }
11684#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070011685
11686 /* issue set key request to SME*/
11687 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
11688 pAdapter->sessionId, &setKey, &roamId );
11689
11690 if ( 0 != status )
11691 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011692 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011693 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
11694 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011695 status = -EINVAL;
11696 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011697 }
11698
11699
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011700 /* in case of IBSS as there was no information available about WEP keys during
11701 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070011702 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011703 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
11704 !( ( IW_AUTH_KEY_MGMT_802_1X
11705 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070011706 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
11707 )
11708 &&
11709 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
11710 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
11711 )
11712 )
11713 {
11714 setKey.keyDirection = eSIR_RX_ONLY;
11715 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
11716
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011717 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070011718 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011719 __func__, setKey.peerMac[0], setKey.peerMac[1],
11720 setKey.peerMac[2], setKey.peerMac[3],
11721 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070011722 setKey.keyDirection);
11723
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011724 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011725 pAdapter->sessionId, &setKey, &roamId );
11726
11727 if ( 0 != status )
11728 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011729 hddLog(VOS_TRACE_LEVEL_ERROR,
11730 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011731 __func__, status);
11732 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011733 status = -EINVAL;
11734 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011735 }
11736 }
11737 }
11738
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011739end:
11740 /* Need to clear any trace of key value in the memory.
11741 * Thus zero out the memory even though it is local
11742 * variable.
11743 */
11744 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011745 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011746 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011747}
11748
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011749#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11750static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
11751 struct net_device *ndev,
11752 u8 key_index, bool pairwise,
11753 const u8 *mac_addr,
11754 struct key_params *params
11755 )
11756#else
11757static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
11758 struct net_device *ndev,
11759 u8 key_index, const u8 *mac_addr,
11760 struct key_params *params
11761 )
11762#endif
11763{
11764 int ret;
11765 vos_ssr_protect(__func__);
11766#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11767 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
11768 mac_addr, params);
11769#else
11770 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
11771 params);
11772#endif
11773 vos_ssr_unprotect(__func__);
11774
11775 return ret;
11776}
11777
Jeff Johnson295189b2012-06-20 16:38:30 -070011778/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011779 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011780 * This function is used to get the key information
11781 */
11782#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011783static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011784 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011785 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011786 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070011787 const u8 *mac_addr, void *cookie,
11788 void (*callback)(void *cookie, struct key_params*)
11789 )
11790#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011791static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011792 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011793 struct net_device *ndev,
11794 u8 key_index, const u8 *mac_addr, void *cookie,
11795 void (*callback)(void *cookie, struct key_params*)
11796 )
11797#endif
11798{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011799 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011800 hdd_wext_state_t *pWextState = NULL;
11801 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011802 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011803 hdd_context_t *pHddCtx;
11804 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011805
11806 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011807
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011808 if (NULL == pAdapter)
11809 {
11810 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11811 "%s: HDD adapter is Null", __func__);
11812 return -ENODEV;
11813 }
11814
11815 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11816 ret = wlan_hdd_validate_context(pHddCtx);
11817 if (0 != ret)
11818 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011819 return ret;
11820 }
11821
11822 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11823 pRoamProfile = &(pWextState->roamProfile);
11824
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011825 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11826 __func__, hdd_device_modetoString(pAdapter->device_mode),
11827 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011828
Jeff Johnson295189b2012-06-20 16:38:30 -070011829 memset(&params, 0, sizeof(params));
11830
11831 if (CSR_MAX_NUM_KEY <= key_index)
11832 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011833 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070011834 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011835 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011836
11837 switch(pRoamProfile->EncryptionType.encryptionType[0])
11838 {
11839 case eCSR_ENCRYPT_TYPE_NONE:
11840 params.cipher = IW_AUTH_CIPHER_NONE;
11841 break;
11842
11843 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
11844 case eCSR_ENCRYPT_TYPE_WEP40:
11845 params.cipher = WLAN_CIPHER_SUITE_WEP40;
11846 break;
11847
11848 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
11849 case eCSR_ENCRYPT_TYPE_WEP104:
11850 params.cipher = WLAN_CIPHER_SUITE_WEP104;
11851 break;
11852
11853 case eCSR_ENCRYPT_TYPE_TKIP:
11854 params.cipher = WLAN_CIPHER_SUITE_TKIP;
11855 break;
11856
11857 case eCSR_ENCRYPT_TYPE_AES:
11858 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
11859 break;
11860
11861 default:
11862 params.cipher = IW_AUTH_CIPHER_NONE;
11863 break;
11864 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011865
c_hpothuaaf19692014-05-17 17:01:48 +053011866 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11867 TRACE_CODE_HDD_CFG80211_GET_KEY,
11868 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011869
Jeff Johnson295189b2012-06-20 16:38:30 -070011870 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
11871 params.seq_len = 0;
11872 params.seq = NULL;
11873 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
11874 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011875 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011876 return 0;
11877}
11878
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011879#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11880static int wlan_hdd_cfg80211_get_key(
11881 struct wiphy *wiphy,
11882 struct net_device *ndev,
11883 u8 key_index, bool pairwise,
11884 const u8 *mac_addr, void *cookie,
11885 void (*callback)(void *cookie, struct key_params*)
11886 )
11887#else
11888static int wlan_hdd_cfg80211_get_key(
11889 struct wiphy *wiphy,
11890 struct net_device *ndev,
11891 u8 key_index, const u8 *mac_addr, void *cookie,
11892 void (*callback)(void *cookie, struct key_params*)
11893 )
11894#endif
11895{
11896 int ret;
11897
11898 vos_ssr_protect(__func__);
11899#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11900 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
11901 mac_addr, cookie, callback);
11902#else
11903 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
11904 callback);
11905#endif
11906 vos_ssr_unprotect(__func__);
11907
11908 return ret;
11909}
11910
Jeff Johnson295189b2012-06-20 16:38:30 -070011911/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011912 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011913 * This function is used to delete the key information
11914 */
11915#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011916static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011917 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011918 u8 key_index,
11919 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070011920 const u8 *mac_addr
11921 )
11922#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011923static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011924 struct net_device *ndev,
11925 u8 key_index,
11926 const u8 *mac_addr
11927 )
11928#endif
11929{
11930 int status = 0;
11931
11932 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011933 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070011934 //it is observed that this is invalidating peer
11935 //key index whenever re-key is done. This is affecting data link.
11936 //It should be ok to ignore del_key.
11937#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011938 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
11939 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011940 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
11941 tCsrRoamSetKey setKey;
11942 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011943
Jeff Johnson295189b2012-06-20 16:38:30 -070011944 ENTER();
11945
11946 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
11947 __func__,pAdapter->device_mode);
11948
11949 if (CSR_MAX_NUM_KEY <= key_index)
11950 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011951 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011952 key_index);
11953
11954 return -EINVAL;
11955 }
11956
11957 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11958 setKey.keyId = key_index;
11959
11960 if (mac_addr)
11961 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
11962 else
11963 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
11964
11965 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
11966
11967 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011968 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011969 )
11970 {
11971
11972 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070011973 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11974 if( pHostapdState->bssState == BSS_START)
11975 {
11976 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011977
Jeff Johnson295189b2012-06-20 16:38:30 -070011978 if ( status != eHAL_STATUS_SUCCESS )
11979 {
11980 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11981 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
11982 __LINE__, status );
11983 }
11984 }
11985 }
11986 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011987 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070011988 )
11989 {
11990 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11991
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011992 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
11993
11994 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070011995 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011996 __func__, setKey.peerMac[0], setKey.peerMac[1],
11997 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070011998 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011999 if(pAdapter->sessionCtx.station.conn_info.connState ==
12000 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070012001 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012002 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070012003 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012004
Jeff Johnson295189b2012-06-20 16:38:30 -070012005 if ( 0 != status )
12006 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012007 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012008 "%s: sme_RoamSetKey failure, returned %d",
12009 __func__, status);
12010 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
12011 return -EINVAL;
12012 }
12013 }
12014 }
12015#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070012016 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012017 return status;
12018}
12019
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012020#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12021static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
12022 struct net_device *ndev,
12023 u8 key_index,
12024 bool pairwise,
12025 const u8 *mac_addr
12026 )
12027#else
12028static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
12029 struct net_device *ndev,
12030 u8 key_index,
12031 const u8 *mac_addr
12032 )
12033#endif
12034{
12035 int ret;
12036
12037 vos_ssr_protect(__func__);
12038#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12039 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
12040 mac_addr);
12041#else
12042 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
12043#endif
12044 vos_ssr_unprotect(__func__);
12045
12046 return ret;
12047}
12048
Jeff Johnson295189b2012-06-20 16:38:30 -070012049/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012050 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070012051 * This function is used to set the default tx key index
12052 */
12053#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012054static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012055 struct net_device *ndev,
12056 u8 key_index,
12057 bool unicast, bool multicast)
12058#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012059static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012060 struct net_device *ndev,
12061 u8 key_index)
12062#endif
12063{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012064 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012065 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053012066 hdd_wext_state_t *pWextState;
12067 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012068 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012069
12070 ENTER();
12071
Gopichand Nakkala29149562013-05-10 21:43:41 +053012072 if ((NULL == pAdapter))
12073 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012074 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053012075 "invalid adapter");
12076 return -EINVAL;
12077 }
12078
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012079 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12080 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
12081 pAdapter->sessionId, key_index));
12082
Gopichand Nakkala29149562013-05-10 21:43:41 +053012083 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12084 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12085
12086 if ((NULL == pWextState) || (NULL == pHddStaCtx))
12087 {
12088 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12089 "invalid Wext state or HDD context");
12090 return -EINVAL;
12091 }
12092
Arif Hussain6d2a3322013-11-17 19:50:10 -080012093 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012094 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012095
Jeff Johnson295189b2012-06-20 16:38:30 -070012096 if (CSR_MAX_NUM_KEY <= key_index)
12097 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012098 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012099 key_index);
12100
12101 return -EINVAL;
12102 }
12103
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012104 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12105 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012106 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012107 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012108 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012109 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012110
Jeff Johnson295189b2012-06-20 16:38:30 -070012111 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070012112 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012113 )
Jeff Johnson295189b2012-06-20 16:38:30 -070012114 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053012115 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080012116 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012117 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080012118 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070012119 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012120 {
12121 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070012122 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012123
Jeff Johnson295189b2012-06-20 16:38:30 -070012124 tCsrRoamSetKey setKey;
12125 v_U32_t roamId= 0xFF;
12126 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012127
12128 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012129 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012130
Jeff Johnson295189b2012-06-20 16:38:30 -070012131 Keys->defaultIndex = (u8)key_index;
12132 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
12133 setKey.keyId = key_index;
12134 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012135
12136 vos_mem_copy(&setKey.Key[0],
12137 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070012138 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012139
Gopichand Nakkala29149562013-05-10 21:43:41 +053012140 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012141
12142 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070012143 &pHddStaCtx->conn_info.bssId[0],
12144 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012145
Gopichand Nakkala29149562013-05-10 21:43:41 +053012146 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
12147 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
12148 eCSR_ENCRYPT_TYPE_WEP104)
12149 {
12150 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
12151 even though ap is configured for WEP-40 encryption. In this canse the key length
12152 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
12153 type(104) and switching encryption type to 40*/
12154 pWextState->roamProfile.EncryptionType.encryptionType[0] =
12155 eCSR_ENCRYPT_TYPE_WEP40;
12156 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
12157 eCSR_ENCRYPT_TYPE_WEP40;
12158 }
12159
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012160 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070012161 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012162
Jeff Johnson295189b2012-06-20 16:38:30 -070012163 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012164 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070012165 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012166
Jeff Johnson295189b2012-06-20 16:38:30 -070012167 if ( 0 != status )
12168 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012169 hddLog(VOS_TRACE_LEVEL_ERROR,
12170 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012171 status);
12172 return -EINVAL;
12173 }
12174 }
12175 }
12176
12177 /* In SoftAp mode setting key direction for default mode */
12178 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
12179 {
12180 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
12181 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
12182 (eCSR_ENCRYPT_TYPE_AES !=
12183 pWextState->roamProfile.EncryptionType.encryptionType[0])
12184 )
12185 {
12186 /* Saving key direction for default key index to TX default */
12187 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
12188 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
12189 }
12190 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012191 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012192 return status;
12193}
12194
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012195#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12196static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
12197 struct net_device *ndev,
12198 u8 key_index,
12199 bool unicast, bool multicast)
12200#else
12201static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
12202 struct net_device *ndev,
12203 u8 key_index)
12204#endif
12205{
12206 int ret;
12207 vos_ssr_protect(__func__);
12208#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12209 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
12210 multicast);
12211#else
12212 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
12213#endif
12214 vos_ssr_unprotect(__func__);
12215
12216 return ret;
12217}
12218
Jeff Johnson295189b2012-06-20 16:38:30 -070012219/*
12220 * FUNCTION: wlan_hdd_cfg80211_inform_bss
12221 * This function is used to inform the BSS details to nl80211 interface.
12222 */
12223static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
12224 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
12225{
12226 struct net_device *dev = pAdapter->dev;
12227 struct wireless_dev *wdev = dev->ieee80211_ptr;
12228 struct wiphy *wiphy = wdev->wiphy;
12229 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
12230 int chan_no;
12231 int ie_length;
12232 const char *ie;
12233 unsigned int freq;
12234 struct ieee80211_channel *chan;
12235 int rssi = 0;
12236 struct cfg80211_bss *bss = NULL;
12237
Jeff Johnson295189b2012-06-20 16:38:30 -070012238 if( NULL == pBssDesc )
12239 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012240 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012241 return bss;
12242 }
12243
12244 chan_no = pBssDesc->channelId;
12245 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
12246 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
12247
12248 if( NULL == ie )
12249 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012250 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012251 return bss;
12252 }
12253
12254#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
12255 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
12256 {
12257 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
12258 }
12259 else
12260 {
12261 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
12262 }
12263#else
12264 freq = ieee80211_channel_to_frequency(chan_no);
12265#endif
12266
12267 chan = __ieee80211_get_channel(wiphy, freq);
12268
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053012269 if (!chan) {
12270 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
12271 return NULL;
12272 }
12273
Abhishek Singhaee43942014-06-16 18:55:47 +053012274 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070012275
Anand N Sunkad9f80b742015-07-30 20:05:51 +053012276 return cfg80211_inform_bss(wiphy, chan,
12277#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12278 CFG80211_BSS_FTYPE_UNKNOWN,
12279#endif
12280 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012281 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070012282 pBssDesc->capabilityInfo,
12283 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053012284 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070012285}
12286
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053012287/*
12288 * wlan_hdd_cfg80211_update_bss_list :to inform nl80211
12289 * interface that BSS might have been lost.
12290 * @pAdapter: adaptor
12291 * @bssid: bssid which might have been lost
12292 *
12293 * Return: bss which is unlinked from kernel cache
12294 */
12295struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_list(
12296 hdd_adapter_t *pAdapter, tSirMacAddr bssid)
12297{
12298 struct net_device *dev = pAdapter->dev;
12299 struct wireless_dev *wdev = dev->ieee80211_ptr;
12300 struct wiphy *wiphy = wdev->wiphy;
12301 struct cfg80211_bss *bss = NULL;
12302
Abhishek Singh5a597e62016-12-05 15:16:30 +053012303 bss = hdd_get_bss_entry(wiphy,
12304 NULL, bssid,
12305 NULL, 0);
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053012306 if (bss == NULL) {
12307 hddLog(LOGE, FL("BSS not present"));
12308 } else {
12309 hddLog(LOG1, FL("cfg80211_unlink_bss called for BSSID "
12310 MAC_ADDRESS_STR), MAC_ADDR_ARRAY(bssid));
12311 cfg80211_unlink_bss(wiphy, bss);
12312 }
12313 return bss;
12314}
Jeff Johnson295189b2012-06-20 16:38:30 -070012315
12316
12317/*
12318 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
12319 * This function is used to inform the BSS details to nl80211 interface.
12320 */
12321struct cfg80211_bss*
12322wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
12323 tSirBssDescription *bss_desc
12324 )
12325{
12326 /*
12327 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
12328 already exists in bss data base of cfg80211 for that particular BSS ID.
12329 Using cfg80211_inform_bss_frame to update the bss entry instead of
12330 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
12331 now there is no possibility to get the mgmt(probe response) frame from PE,
12332 converting bss_desc to ieee80211_mgmt(probe response) and passing to
12333 cfg80211_inform_bss_frame.
12334 */
12335 struct net_device *dev = pAdapter->dev;
12336 struct wireless_dev *wdev = dev->ieee80211_ptr;
12337 struct wiphy *wiphy = wdev->wiphy;
12338 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012339#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
12340 qcom_ie_age *qie_age = NULL;
12341 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
12342#else
Jeff Johnson295189b2012-06-20 16:38:30 -070012343 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012344#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012345 const char *ie =
12346 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
12347 unsigned int freq;
12348 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053012349 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012350 struct cfg80211_bss *bss_status = NULL;
12351 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
12352 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070012353 hdd_context_t *pHddCtx;
12354 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070012355#ifdef WLAN_OPEN_SOURCE
12356 struct timespec ts;
12357#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012358
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012359
Wilson Yangf80a0542013-10-07 13:02:37 -070012360 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12361 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070012362 if (0 != status)
12363 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070012364 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070012365 }
12366
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053012367 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070012368 if (!mgmt)
12369 {
12370 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12371 "%s: memory allocation failed ", __func__);
12372 return NULL;
12373 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070012374
Jeff Johnson295189b2012-06-20 16:38:30 -070012375 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070012376
12377#ifdef WLAN_OPEN_SOURCE
12378 /* Android does not want the timestamp from the frame.
12379 Instead it wants a monotonic increasing value */
12380 get_monotonic_boottime(&ts);
12381 mgmt->u.probe_resp.timestamp =
12382 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
12383#else
12384 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070012385 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
12386 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070012387
12388#endif
12389
Jeff Johnson295189b2012-06-20 16:38:30 -070012390 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
12391 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012392
12393#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
12394 /* GPS Requirement: need age ie per entry. Using vendor specific. */
12395 /* Assuming this is the last IE, copy at the end */
12396 ie_length -=sizeof(qcom_ie_age);
12397 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
12398 qie_age->element_id = QCOM_VENDOR_IE_ID;
12399 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
12400 qie_age->oui_1 = QCOM_OUI1;
12401 qie_age->oui_2 = QCOM_OUI2;
12402 qie_age->oui_3 = QCOM_OUI3;
12403 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
Selvaraj, Sridhar4b3a8362016-10-12 12:34:08 +053012404 /* Lowi expects the timestamp of bss in units of 1/10 ms. In driver all
12405 * bss related timestamp is in units of ms. Due to this when scan results
12406 * are sent to lowi the scan age is high.To address this, send age in units
12407 * of 1/10 ms.
12408 */
12409 qie_age->age = (vos_timer_get_system_time() -
12410 bss_desc->nReceivedTime)/10;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012411#endif
12412
Jeff Johnson295189b2012-06-20 16:38:30 -070012413 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053012414 if (bss_desc->fProbeRsp)
12415 {
12416 mgmt->frame_control |=
12417 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
12418 }
12419 else
12420 {
12421 mgmt->frame_control |=
12422 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
12423 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012424
12425#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012426 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070012427 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
12428 {
12429 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
12430 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012431 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070012432 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
12433
12434 {
12435 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
12436 }
12437 else
12438 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012439 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
12440 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070012441 kfree(mgmt);
12442 return NULL;
12443 }
12444#else
12445 freq = ieee80211_channel_to_frequency(chan_no);
12446#endif
12447 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080012448 /*when the band is changed on the fly using the GUI, three things are done
12449 * 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)
12450 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
12451 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
12452 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
12453 * and discards the channels correponding to previous band and calls back with zero bss results.
12454 * 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
12455 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
12456 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
12457 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
12458 * So drop the bss and continue to next bss.
12459 */
12460 if(chan == NULL)
12461 {
Deepthi Gowri306657b2016-04-28 17:10:41 +053012462 hddLog(VOS_TRACE_LEVEL_ERROR,
12463 FL("chan pointer is NULL, chan_no: %d freq: %d"),
12464 chan_no, freq);
Chilam Ngc4244af2013-04-01 15:37:32 -070012465 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080012466 return NULL;
12467 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053012468 /*To keep the rssi icon of the connected AP in the scan window
12469 *and the rssi icon of the wireless networks in sync
12470 * */
12471 if (( eConnectionState_Associated ==
12472 pAdapter->sessionCtx.station.conn_info.connState ) &&
12473 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
12474 pAdapter->sessionCtx.station.conn_info.bssId,
12475 WNI_CFG_BSSID_LEN)) &&
12476 (pHddCtx->hdd_wlan_suspended == FALSE))
12477 {
12478 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
12479 rssi = (pAdapter->rssi * 100);
12480 }
12481 else
12482 {
12483 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
12484 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012485
Nirav Shah20ac06f2013-12-12 18:14:06 +053012486 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053012487 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
12488 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053012489
Jeff Johnson295189b2012-06-20 16:38:30 -070012490 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
12491 frame_len, rssi, GFP_KERNEL);
12492 kfree(mgmt);
12493 return bss_status;
12494}
12495
12496/*
12497 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
12498 * This function is used to update the BSS data base of CFG8011
12499 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012500struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012501 tCsrRoamInfo *pRoamInfo
12502 )
12503{
12504 tCsrRoamConnectedProfile roamProfile;
12505 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12506 struct cfg80211_bss *bss = NULL;
12507
12508 ENTER();
12509
12510 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
12511 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
12512
12513 if (NULL != roamProfile.pBssDesc)
12514 {
Girish Gowlif4b68022014-08-28 23:18:57 +053012515 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
12516 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070012517
12518 if (NULL == bss)
12519 {
12520 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
12521 __func__);
12522 }
12523
12524 sme_RoamFreeConnectProfile(hHal, &roamProfile);
12525 }
12526 else
12527 {
12528 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
12529 __func__);
12530 }
12531 return bss;
12532}
12533
12534/*
12535 * FUNCTION: wlan_hdd_cfg80211_update_bss
12536 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012537static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
12538 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070012539 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012540{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012541 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012542 tCsrScanResultInfo *pScanResult;
12543 eHalStatus status = 0;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012544 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012545 tScanResultHandle pResult;
12546 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070012547 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012548 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070012549 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012550
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012551 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12552 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
12553 NO_SESSION, pAdapter->sessionId));
12554
Wilson Yangf80a0542013-10-07 13:02:37 -070012555 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012556 ret = wlan_hdd_validate_context(pHddCtx);
12557 if (0 != ret)
Jeff Johnson295189b2012-06-20 16:38:30 -070012558 {
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012559 return ret;
Wilson Yangf80a0542013-10-07 13:02:37 -070012560 }
12561
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012562 if (pAdapter->request != NULL)
12563 {
12564 if ((pAdapter->request->n_ssids == 1)
12565 && (pAdapter->request->ssids != NULL)
12566 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
12567 is_p2p_scan = true;
12568 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012569 /*
12570 * start getting scan results and populate cgf80211 BSS database
12571 */
12572 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
12573
12574 /* no scan results */
12575 if (NULL == pResult)
12576 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012577 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
12578 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053012579 wlan_hdd_get_frame_logs(pAdapter,
12580 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070012581 return status;
12582 }
12583
12584 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
12585
12586 while (pScanResult)
12587 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012588 /*
12589 * cfg80211_inform_bss() is not updating ie field of bss entry, if
12590 * entry already exists in bss data base of cfg80211 for that
12591 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
12592 * bss entry instead of cfg80211_inform_bss, But this call expects
12593 * mgmt packet as input. As of now there is no possibility to get
12594 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070012595 * ieee80211_mgmt(probe response) and passing to c
12596 * fg80211_inform_bss_frame.
12597 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012598 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
12599 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
12600 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012601 pScanResult = sme_ScanResultGetNext(hHal, pResult);
12602 continue; //Skip the non p2p bss entries
12603 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012604 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
12605 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012606
Jeff Johnson295189b2012-06-20 16:38:30 -070012607
12608 if (NULL == bss_status)
12609 {
12610 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012611 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012612 }
12613 else
12614 {
Yue Maf49ba872013-08-19 12:04:25 -070012615 cfg80211_put_bss(
12616#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
12617 wiphy,
12618#endif
12619 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070012620 }
12621
12622 pScanResult = sme_ScanResultGetNext(hHal, pResult);
12623 }
12624
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012625 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012626 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012627 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012628}
12629
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012630void
12631hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
12632{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012633 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080012634 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012635} /****** end hddPrintMacAddr() ******/
12636
12637void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070012638hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012639{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012640 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012641 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070012642 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
12643 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
12644 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012645} /****** end hddPrintPmkId() ******/
12646
12647//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
12648//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
12649
12650//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
12651//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
12652
12653#define dump_bssid(bssid) \
12654 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070012655 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
12656 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012657 }
12658
12659#define dump_pmkid(pMac, pmkid) \
12660 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070012661 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
12662 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012663 }
12664
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070012665#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012666/*
12667 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
12668 * This function is used to notify the supplicant of a new PMKSA candidate.
12669 */
12670int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012671 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012672 int index, bool preauth )
12673{
Jeff Johnsone7245742012-09-05 17:12:55 -070012674#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012675 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012676 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012677
12678 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070012679 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012680
12681 if( NULL == pRoamInfo )
12682 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012683 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012684 return -EINVAL;
12685 }
12686
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012687 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
12688 {
12689 dump_bssid(pRoamInfo->bssid);
12690 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012691 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012692 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012693#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012694 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012695}
12696#endif //FEATURE_WLAN_LFR
12697
Yue Maef608272013-04-08 23:09:17 -070012698#ifdef FEATURE_WLAN_LFR_METRICS
12699/*
12700 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
12701 * 802.11r/LFR metrics reporting function to report preauth initiation
12702 *
12703 */
12704#define MAX_LFR_METRICS_EVENT_LENGTH 100
12705VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
12706 tCsrRoamInfo *pRoamInfo)
12707{
12708 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12709 union iwreq_data wrqu;
12710
12711 ENTER();
12712
12713 if (NULL == pAdapter)
12714 {
12715 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12716 return VOS_STATUS_E_FAILURE;
12717 }
12718
12719 /* create the event */
12720 memset(&wrqu, 0, sizeof(wrqu));
12721 memset(metrics_notification, 0, sizeof(metrics_notification));
12722
12723 wrqu.data.pointer = metrics_notification;
12724 wrqu.data.length = scnprintf(metrics_notification,
12725 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
12726 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
12727
12728 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12729
12730 EXIT();
12731
12732 return VOS_STATUS_SUCCESS;
12733}
12734
12735/*
12736 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
12737 * 802.11r/LFR metrics reporting function to report preauth completion
12738 * or failure
12739 */
12740VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
12741 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
12742{
12743 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12744 union iwreq_data wrqu;
12745
12746 ENTER();
12747
12748 if (NULL == pAdapter)
12749 {
12750 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12751 return VOS_STATUS_E_FAILURE;
12752 }
12753
12754 /* create the event */
12755 memset(&wrqu, 0, sizeof(wrqu));
12756 memset(metrics_notification, 0, sizeof(metrics_notification));
12757
12758 scnprintf(metrics_notification, sizeof(metrics_notification),
12759 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
12760 MAC_ADDR_ARRAY(pRoamInfo->bssid));
12761
12762 if (1 == preauth_status)
12763 strncat(metrics_notification, " TRUE", 5);
12764 else
12765 strncat(metrics_notification, " FALSE", 6);
12766
12767 wrqu.data.pointer = metrics_notification;
12768 wrqu.data.length = strlen(metrics_notification);
12769
12770 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12771
12772 EXIT();
12773
12774 return VOS_STATUS_SUCCESS;
12775}
12776
12777/*
12778 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
12779 * 802.11r/LFR metrics reporting function to report handover initiation
12780 *
12781 */
12782VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
12783 tCsrRoamInfo *pRoamInfo)
12784{
12785 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12786 union iwreq_data wrqu;
12787
12788 ENTER();
12789
12790 if (NULL == pAdapter)
12791 {
12792 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12793 return VOS_STATUS_E_FAILURE;
12794 }
12795
12796 /* create the event */
12797 memset(&wrqu, 0, sizeof(wrqu));
12798 memset(metrics_notification, 0, sizeof(metrics_notification));
12799
12800 wrqu.data.pointer = metrics_notification;
12801 wrqu.data.length = scnprintf(metrics_notification,
12802 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
12803 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
12804
12805 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12806
12807 EXIT();
12808
12809 return VOS_STATUS_SUCCESS;
12810}
12811#endif
12812
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053012813
12814/**
12815 * wlan_hdd_cfg80211_validate_scan_req - validate scan request
12816 * @scan_req: scan request to be checked
12817 *
12818 * Return: true or false
12819 */
12820#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
12821static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
12822 cfg80211_scan_request
12823 *scan_req)
12824{
12825 if (!scan_req || !scan_req->wiphy) {
12826 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
12827 return false;
12828 }
12829 if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HDD, NULL)) {
12830 hddLog(VOS_TRACE_LEVEL_ERROR, "Load/Unload in progress");
12831 return false;
12832 }
12833 return true;
12834}
12835#else
12836static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
12837 cfg80211_scan_request
12838 *scan_req)
12839{
12840 if (!scan_req || !scan_req->wiphy) {
12841 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
12842 return false;
12843 }
12844 return true;
12845}
12846#endif
12847
12848
Jeff Johnson295189b2012-06-20 16:38:30 -070012849/*
12850 * FUNCTION: hdd_cfg80211_scan_done_callback
12851 * scanning callback function, called after finishing scan
12852 *
12853 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012854static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070012855 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
12856{
12857 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012858 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070012859 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012860 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070012861 struct cfg80211_scan_request *req = NULL;
12862 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012863 bool aborted = false;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012864#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
12865 bool iface_down = false;
12866#endif
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012867 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012868 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012869 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012870
12871 ENTER();
12872
c_manjee1b4ab9a2016-10-26 11:36:55 +053012873 if (!pAdapter || pAdapter->magic != WLAN_HDD_ADAPTER_MAGIC ||
12874 !pAdapter->dev) {
12875 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Adapter is not valid"));
12876 return 0;
12877 }
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012878 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053012879 if (NULL == pHddCtx) {
12880 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012881 return 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012882 }
12883
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053012884#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
12885 if (!(pAdapter->dev->flags & IFF_UP))
12886 {
12887 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Interface is down"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012888 iface_down = true;
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053012889 }
12890#endif
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012891 pScanInfo = &pHddCtx->scan_info;
12892
Jeff Johnson295189b2012-06-20 16:38:30 -070012893 hddLog(VOS_TRACE_LEVEL_INFO,
12894 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080012895 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012896 __func__, halHandle, pContext, (int) scanId, (int) status);
12897
Kiet Lamac06e2c2013-10-23 16:25:07 +053012898 pScanInfo->mScanPendingCounter = 0;
12899
Jeff Johnson295189b2012-06-20 16:38:30 -070012900 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012901 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070012902 &pScanInfo->scan_req_completion_event,
12903 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012904 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070012905 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012906 hddLog(VOS_TRACE_LEVEL_ERROR,
12907 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070012908 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070012909 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070012910 }
12911
Yue Maef608272013-04-08 23:09:17 -070012912 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070012913 {
12914 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070012915 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070012916 }
12917
12918 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012919 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070012920 {
12921 hddLog(VOS_TRACE_LEVEL_INFO,
12922 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080012923 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070012924 (int) scanId);
12925 }
12926
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053012927#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012928 if (!iface_down)
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053012929#endif
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012930 {
12931 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
12932 pAdapter);
12933 if (0 > ret)
12934 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053012935 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012936
Jeff Johnson295189b2012-06-20 16:38:30 -070012937 /* If any client wait scan result through WEXT
12938 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012939 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070012940 {
12941 /* The other scan request waiting for current scan finish
12942 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012943 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070012944 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012945 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070012946 }
12947 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012948 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070012949 {
12950 struct net_device *dev = pAdapter->dev;
12951 union iwreq_data wrqu;
12952 int we_event;
12953 char *msg;
12954
12955 memset(&wrqu, '\0', sizeof(wrqu));
12956 we_event = SIOCGIWSCAN;
12957 msg = NULL;
12958 wireless_send_event(dev, we_event, &wrqu, msg);
12959 }
12960 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012961 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012962
12963 /* Get the Scan Req */
12964 req = pAdapter->request;
mukul sharmae7041822015-12-03 15:09:21 +053012965 pAdapter->request = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012966
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012967 /* Scan is no longer pending */
12968 pScanInfo->mScanPending = VOS_FALSE;
12969
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053012970 if (!wlan_hdd_cfg80211_validate_scan_req(req))
Jeff Johnson295189b2012-06-20 16:38:30 -070012971 {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053012972#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
12973 hddLog(VOS_TRACE_LEVEL_ERROR, FL("interface state %s"),
12974 iface_down ? "up" : "down");
12975#endif
12976
12977 if (pAdapter->dev) {
12978 hddLog(VOS_TRACE_LEVEL_ERROR, FL("device name %s"),
12979 pAdapter->dev->name);
12980 }
mukul sharmae7041822015-12-03 15:09:21 +053012981 complete(&pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -070012982 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070012983 }
12984
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012985 /* last_scan_timestamp is used to decide if new scan
12986 * is needed or not on station interface. If last station
12987 * scan time and new station scan time is less then
12988 * last_scan_timestamp ; driver will return cached scan.
12989 */
12990 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
12991 {
12992 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
12993
12994 if ( req->n_channels )
12995 {
12996 for (i = 0; i < req->n_channels ; i++ )
12997 {
12998 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
12999 }
13000 /* store no of channel scanned */
13001 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
13002 }
13003
13004 }
13005
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070013006 /*
13007 * cfg80211_scan_done informing NL80211 about completion
13008 * of scanning
13009 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053013010 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
13011 {
13012 aborted = true;
13013 }
mukul sharmae7041822015-12-03 15:09:21 +053013014
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013015#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
13016 if (!iface_down)
13017#endif
13018 cfg80211_scan_done(req, aborted);
mukul sharmae7041822015-12-03 15:09:21 +053013019
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080013020 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070013021
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013022allow_suspend:
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053013023 if ((pHddCtx->cfg_ini->enableMacSpoofing == MAC_ADDR_SPOOFING_FW_HOST_ENABLE
13024 ) && (pHddCtx->spoofMacAddr.isEnabled
13025 || pHddCtx->spoofMacAddr.isReqDeferred)) {
Siddharth Bhal76972212014-10-15 16:22:51 +053013026 /* Generate new random mac addr for next scan */
13027 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +053013028
13029 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
13030 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhal76972212014-10-15 16:22:51 +053013031 }
13032
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070013033 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013034 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070013035
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070013036 /* Acquire wakelock to handle the case where APP's tries to suspend
13037 * immediatly after the driver gets connect request(i.e after scan)
13038 * from supplicant, this result in app's is suspending and not able
13039 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013040 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070013041
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013042#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
13043 if (!iface_down)
13044#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070013045#ifdef FEATURE_WLAN_TDLS
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013046 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070013047#endif
13048
Jeff Johnson295189b2012-06-20 16:38:30 -070013049 EXIT();
13050 return 0;
13051}
13052
13053/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053013054 * FUNCTION: hdd_isConnectionInProgress
13055 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013056 *
13057 */
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013058v_BOOL_t hdd_isConnectionInProgress(hdd_context_t *pHddCtx, v_U8_t *session_id,
13059 scan_reject_states *reason)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013060{
13061 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
13062 hdd_station_ctx_t *pHddStaCtx = NULL;
13063 hdd_adapter_t *pAdapter = NULL;
13064 VOS_STATUS status = 0;
13065 v_U8_t staId = 0;
13066 v_U8_t *staMac = NULL;
13067
13068 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
13069
13070 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
13071 {
13072 pAdapter = pAdapterNode->pAdapter;
13073
13074 if( pAdapter )
13075 {
13076 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013077 "%s: Adapter with device mode %s (%d) exists",
13078 __func__, hdd_device_modetoString(pAdapter->device_mode),
13079 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013080 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053013081 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
13082 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
13083 (eConnectionState_Connecting ==
13084 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
13085 {
13086 hddLog(VOS_TRACE_LEVEL_ERROR,
13087 "%s: %p(%d) Connection is in progress", __func__,
13088 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013089 if (session_id && reason)
13090 {
13091 *session_id = pAdapter->sessionId;
13092 *reason = eHDD_CONNECTION_IN_PROGRESS;
13093 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053013094 return VOS_TRUE;
13095 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013096 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053013097 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013098 {
13099 hddLog(VOS_TRACE_LEVEL_ERROR,
13100 "%s: %p(%d) Reassociation is in progress", __func__,
13101 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013102 if (session_id && reason)
13103 {
13104 *session_id = pAdapter->sessionId;
13105 *reason = eHDD_REASSOC_IN_PROGRESS;
13106 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013107 return VOS_TRUE;
13108 }
13109 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013110 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
13111 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013112 {
13113 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13114 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013115 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013116 {
13117 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
13118 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080013119 "%s: client " MAC_ADDRESS_STR
13120 " is in the middle of WPS/EAPOL exchange.", __func__,
13121 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013122 if (session_id && reason)
13123 {
13124 *session_id = pAdapter->sessionId;
13125 *reason = eHDD_EAPOL_IN_PROGRESS;
13126 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053013127 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013128 }
13129 }
13130 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
13131 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
13132 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013133 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
13134 ptSapContext pSapCtx = NULL;
13135 pSapCtx = VOS_GET_SAP_CB(pVosContext);
13136 if(pSapCtx == NULL){
13137 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13138 FL("psapCtx is NULL"));
13139 return VOS_FALSE;
13140 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013141 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
13142 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013143 if ((pSapCtx->aStaInfo[staId].isUsed) &&
13144 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013145 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013146 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013147
13148 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080013149 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
13150 "middle of WPS/EAPOL exchange.", __func__,
13151 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013152 if (session_id && reason)
13153 {
13154 *session_id = pAdapter->sessionId;
13155 *reason = eHDD_SAP_EAPOL_IN_PROGRESS;
13156 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053013157 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013158 }
13159 }
13160 }
13161 }
13162 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13163 pAdapterNode = pNext;
13164 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053013165 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013166}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013167
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053013168/**
13169 * csr_scan_request_assign_bssid() - Set the BSSID received from Supplicant
13170 * to the Scan request
13171 * @scanRequest: Pointer to the csr scan request
13172 * @request: Pointer to the scan request from supplicant
13173 *
13174 * Return: None
13175 */
13176#ifdef CFG80211_SCAN_BSSID
13177static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
13178 struct cfg80211_scan_request *request)
13179{
13180 vos_mem_copy(scanRequest->bssid, request->bssid, VOS_MAC_ADDR_SIZE);
13181}
13182#else
13183static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
13184 struct cfg80211_scan_request *request)
13185{
13186}
13187#endif
13188
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013189/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013190 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070013191 * this scan respond to scan trigger and update cfg80211 scan database
13192 * later, scan dump command can be used to recieve scan results
13193 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013194int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080013195#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13196 struct net_device *dev,
13197#endif
13198 struct cfg80211_scan_request *request)
13199{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013200 hdd_adapter_t *pAdapter = NULL;
13201 hdd_context_t *pHddCtx = NULL;
13202 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013203 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013204 tCsrScanRequest scanRequest;
13205 tANI_U8 *channelList = NULL, i;
13206 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013207 int status;
13208 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013209 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013210 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053013211 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013212 bool is_p2p_scan = false;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013213 v_U8_t curr_session_id;
13214 scan_reject_states curr_reason;
Jeff Johnson295189b2012-06-20 16:38:30 -070013215
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013216#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
13217 struct net_device *dev = NULL;
13218 if (NULL == request)
13219 {
13220 hddLog(VOS_TRACE_LEVEL_ERROR,
13221 "%s: scan req param null", __func__);
13222 return -EINVAL;
13223 }
13224 dev = request->wdev->netdev;
13225#endif
13226
13227 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
13228 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
13229 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13230
Jeff Johnson295189b2012-06-20 16:38:30 -070013231 ENTER();
13232
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013233 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13234 __func__, hdd_device_modetoString(pAdapter->device_mode),
13235 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013236
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013237 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013238 if (0 != status)
13239 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013240 return status;
13241 }
13242
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013243 if (NULL == pwextBuf)
13244 {
13245 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
13246 __func__);
13247 return -EIO;
13248 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013249 cfg_param = pHddCtx->cfg_ini;
13250 pScanInfo = &pHddCtx->scan_info;
13251
Jeff Johnson295189b2012-06-20 16:38:30 -070013252#ifdef WLAN_BTAMP_FEATURE
13253 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013254 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070013255 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080013256 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013257 "%s: No scanning when AMP is on", __func__);
13258 return -EOPNOTSUPP;
13259 }
13260#endif
13261 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013262 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070013263 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013264 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013265 "%s: Not scanning on device_mode = %s (%d)",
13266 __func__, hdd_device_modetoString(pAdapter->device_mode),
13267 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013268 return -EOPNOTSUPP;
13269 }
13270
13271 if (TRUE == pScanInfo->mScanPending)
13272 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053013273 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
13274 {
13275 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
13276 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013277 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070013278 }
13279
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053013280 // Don't allow scan if PNO scan is going on.
13281 if (pHddCtx->isPnoEnable)
13282 {
13283 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13284 FL("pno scan in progress"));
13285 return -EBUSY;
13286 }
13287
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013288 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070013289 //Channel and action frame is pending
13290 //Otherwise Cancel Remain On Channel and allow Scan
13291 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013292 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070013293 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053013294 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070013295 return -EBUSY;
13296 }
13297
Jeff Johnson295189b2012-06-20 16:38:30 -070013298 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
13299 {
13300 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080013301 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013302 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013303 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013304 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
13305 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013306 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013307 "%s: MAX TM Level Scan not allowed", __func__);
13308 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013309 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070013310 }
13311 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
13312
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013313 /* Check if scan is allowed at this point of time.
13314 */
Hanumanth Reddy Pothulaec960842016-09-14 19:04:26 +053013315 if (TRUE == pHddCtx->btCoexModeSet)
13316 {
13317 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13318 FL("BTCoex Mode operation in progress"));
13319 return -EBUSY;
13320 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013321 if (hdd_isConnectionInProgress(pHddCtx, &curr_session_id, &curr_reason))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013322 {
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053013323 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Scan not allowed"));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013324 if (pHddCtx->last_scan_reject_session_id != curr_session_id ||
13325 pHddCtx->last_scan_reject_reason != curr_reason ||
13326 !pHddCtx->last_scan_reject_timestamp)
13327 {
13328 pHddCtx->last_scan_reject_session_id = curr_session_id;
13329 pHddCtx->last_scan_reject_reason = curr_reason;
Sreelakshmi Konamkif0646d52016-12-09 12:35:31 +053013330 pHddCtx->last_scan_reject_timestamp = jiffies_to_msecs(jiffies);
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053013331 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013332 else {
Sreelakshmi Konamkif0646d52016-12-09 12:35:31 +053013333 if ((jiffies_to_msecs(jiffies) -
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013334 pHddCtx->last_scan_reject_timestamp) >=
13335 SCAN_REJECT_THRESHOLD_TIME)
13336 {
13337 pHddCtx->last_scan_reject_timestamp = 0;
13338 if (pHddCtx->cfg_ini->enableFatalEvent)
13339 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
13340 WLAN_LOG_INDICATOR_HOST_DRIVER,
13341 WLAN_LOG_REASON_SCAN_NOT_ALLOWED,
13342 FALSE, FALSE);
13343 else
13344 {
13345 hddLog(LOGE, FL("Triggering SSR"));
13346 vos_wlanRestart();
13347 }
13348 }
13349 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013350 return -EBUSY;
13351 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013352 pHddCtx->last_scan_reject_timestamp = 0;
13353 pHddCtx->last_scan_reject_session_id = 0xFF;
13354 pHddCtx->last_scan_reject_reason = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013355
Jeff Johnson295189b2012-06-20 16:38:30 -070013356 vos_mem_zero( &scanRequest, sizeof(scanRequest));
13357
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013358 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
13359 * Becasue of this, driver is assuming that this is not wildcard scan and so
13360 * is not aging out the scan results.
13361 */
13362 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070013363 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013364 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013365 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013366
13367 if ((request->ssids) && (0 < request->n_ssids))
13368 {
13369 tCsrSSIDInfo *SsidInfo;
13370 int j;
13371 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
13372 /* Allocate num_ssid tCsrSSIDInfo structure */
13373 SsidInfo = scanRequest.SSIDs.SSIDList =
13374 ( tCsrSSIDInfo *)vos_mem_malloc(
13375 request->n_ssids*sizeof(tCsrSSIDInfo));
13376
13377 if(NULL == scanRequest.SSIDs.SSIDList)
13378 {
13379 hddLog(VOS_TRACE_LEVEL_ERROR,
13380 "%s: memory alloc failed SSIDInfo buffer", __func__);
13381 return -ENOMEM;
13382 }
13383
13384 /* copy all the ssid's and their length */
13385 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
13386 {
13387 /* get the ssid length */
13388 SsidInfo->SSID.length = request->ssids[j].ssid_len;
13389 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
13390 SsidInfo->SSID.length);
13391 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
13392 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
13393 j, SsidInfo->SSID.ssId);
13394 }
13395 /* set the scan type to active */
13396 scanRequest.scanType = eSIR_ACTIVE_SCAN;
13397 }
13398 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070013399 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013400 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13401 TRACE_CODE_HDD_CFG80211_SCAN,
13402 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070013403 /* set the scan type to active */
13404 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070013405 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013406 else
13407 {
13408 /*Set the scan type to default type, in this case it is ACTIVE*/
13409 scanRequest.scanType = pScanInfo->scan_mode;
13410 }
13411 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
13412 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070013413
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053013414 csr_scan_request_assign_bssid(&scanRequest, request);
13415
Jeff Johnson295189b2012-06-20 16:38:30 -070013416 /* set BSSType to default type */
13417 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
13418
13419 /*TODO: scan the requested channels only*/
13420
13421 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013422 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070013423 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013424 hddLog(VOS_TRACE_LEVEL_WARN,
13425 "No of Scan Channels exceeded limit: %d", request->n_channels);
13426 request->n_channels = MAX_CHANNEL;
13427 }
13428
13429 hddLog(VOS_TRACE_LEVEL_INFO,
13430 "No of Scan Channels: %d", request->n_channels);
13431
13432
13433 if( request->n_channels )
13434 {
13435 char chList [(request->n_channels*5)+1];
13436 int len;
13437 channelList = vos_mem_malloc( request->n_channels );
13438 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053013439 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013440 hddLog(VOS_TRACE_LEVEL_ERROR,
13441 "%s: memory alloc failed channelList", __func__);
13442 status = -ENOMEM;
13443 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053013444 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013445
13446 for( i = 0, len = 0; i < request->n_channels ; i++ )
13447 {
13448 channelList[i] = request->channels[i]->hw_value;
13449 len += snprintf(chList+len, 5, "%d ", channelList[i]);
13450 }
13451
Nirav Shah20ac06f2013-12-12 18:14:06 +053013452 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013453 "Channel-List: %s ", chList);
13454 }
c_hpothu53512302014-04-15 18:49:53 +053013455
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013456 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
13457 scanRequest.ChannelInfo.ChannelList = channelList;
13458
13459 /* set requestType to full scan */
13460 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
13461
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013462 /* if there is back to back scan happening in driver with in
13463 * nDeferScanTimeInterval interval driver should defer new scan request
13464 * and should provide last cached scan results instead of new channel list.
13465 * This rule is not applicable if scan is p2p scan.
13466 * This condition will work only in case when last request no of channels
13467 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053013468 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053013469 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013470 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013471
Sushant Kaushik86592172015-04-27 16:35:03 +053013472 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
13473 /* if wps ie is NULL , then only defer scan */
13474 if ( pWpsIe == NULL &&
13475 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053013476 {
13477 if ( pScanInfo->last_scan_timestamp !=0 &&
13478 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
13479 {
13480 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
13481 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
13482 vos_mem_compare(pScanInfo->last_scan_channelList,
13483 channelList, pScanInfo->last_scan_numChannels))
13484 {
13485 hddLog(VOS_TRACE_LEVEL_WARN,
13486 " New and old station scan time differ is less then %u",
13487 pHddCtx->cfg_ini->nDeferScanTimeInterval);
13488
13489 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013490 pAdapter);
13491
Agarwal Ashish57e84372014-12-05 18:26:53 +053013492 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053013493 "Return old cached scan as all channels and no of channels are same");
13494
Agarwal Ashish57e84372014-12-05 18:26:53 +053013495 if (0 > ret)
13496 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013497
Agarwal Ashish57e84372014-12-05 18:26:53 +053013498 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053013499
13500 status = eHAL_STATUS_SUCCESS;
13501 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053013502 }
13503 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013504 }
13505
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013506 /* Flush the scan results(only p2p beacons) for STA scan and P2P
13507 * search (Flush on both full scan and social scan but not on single
13508 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
13509 */
13510
13511 /* Supplicant does single channel scan after 8-way handshake
13512 * and in that case driver shoudnt flush scan results. If
13513 * driver flushes the scan results here and unfortunately if
13514 * the AP doesnt respond to our probe req then association
13515 * fails which is not desired
13516 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013517 if ((request->n_ssids == 1)
13518 && (request->ssids != NULL)
13519 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
13520 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013521
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013522 if( is_p2p_scan ||
13523 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013524 {
13525 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
13526 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
13527 pAdapter->sessionId );
13528 }
13529
13530 if( request->ie_len )
13531 {
13532 /* save this for future association (join requires this) */
13533 /*TODO: Array needs to be converted to dynamic allocation,
13534 * as multiple ie.s can be sent in cfg80211_scan_request structure
13535 * CR 597966
13536 */
13537 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
13538 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
13539 pScanInfo->scanAddIE.length = request->ie_len;
13540
13541 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
13542 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
13543 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070013544 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013545 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070013546 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013547 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
13548 memcpy( pwextBuf->roamProfile.addIEScan,
13549 request->ie, request->ie_len);
13550 }
13551 else
13552 {
13553 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
13554 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013555 }
13556
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013557 }
13558 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
13559 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
13560
13561 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
13562 request->ie_len);
13563 if (pP2pIe != NULL)
13564 {
13565#ifdef WLAN_FEATURE_P2P_DEBUG
13566 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
13567 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
13568 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053013569 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013570 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
13571 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
13572 "Go nego completed to Connection is started");
13573 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
13574 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053013575 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013576 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
13577 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070013578 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013579 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
13580 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
13581 "Disconnected state to Connection is started");
13582 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
13583 "for 4way Handshake");
13584 }
13585#endif
13586
13587 /* no_cck will be set during p2p find to disable 11b rates */
13588 if(TRUE == request->no_cck)
13589 {
13590 hddLog(VOS_TRACE_LEVEL_INFO,
13591 "%s: This is a P2P Search", __func__);
13592 scanRequest.p2pSearch = 1;
13593
13594 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053013595 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013596 /* set requestType to P2P Discovery */
13597 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
13598 }
13599
13600 /*
13601 Skip Dfs Channel in case of P2P Search
13602 if it is set in ini file
13603 */
13604 if(cfg_param->skipDfsChnlInP2pSearch)
13605 {
13606 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053013607 }
13608 else
13609 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013610 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053013611 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013612
Agarwal Ashish4f616132013-12-30 23:32:50 +053013613 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013614 }
13615 }
13616
13617 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
13618
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013619#ifdef FEATURE_WLAN_TDLS
13620 /* if tdls disagree scan right now, return immediately.
13621 tdls will schedule the scan when scan is allowed. (return SUCCESS)
13622 or will reject the scan if any TDLS is in progress. (return -EBUSY)
13623 */
13624 status = wlan_hdd_tdls_scan_callback (pAdapter,
13625 wiphy,
13626#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13627 dev,
13628#endif
13629 request);
Abhishek Singhe2b63952016-01-05 18:27:29 +053013630 if (status <= 0)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013631 {
Abhishek Singhe2b63952016-01-05 18:27:29 +053013632 if (!status)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013633 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
13634 "scan rejected %d", __func__, status);
13635 else
13636 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
13637 __func__, status);
Abhishek Singhe2b63952016-01-05 18:27:29 +053013638 hdd_wlan_block_scan_by_tdls();
Gupta, Kapil2ebf3e02016-03-17 19:45:19 +053013639 goto free_mem;
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013640 }
13641#endif
13642
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070013643 /* acquire the wakelock to avoid the apps suspend during the scan. To
13644 * address the following issues.
13645 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
13646 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
13647 * for long time, this result in apps running at full power for long time.
13648 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
13649 * be stuck in full power because of resume BMPS
13650 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013651 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070013652
Nirav Shah20ac06f2013-12-12 18:14:06 +053013653 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
13654 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013655 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
13656 scanRequest.requestType, scanRequest.scanType,
13657 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053013658 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
13659
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053013660 if (pHddCtx->spoofMacAddr.isEnabled &&
13661 pHddCtx->cfg_ini->enableMacSpoofing == 1)
Siddharth Bhal76972212014-10-15 16:22:51 +053013662 {
13663 hddLog(VOS_TRACE_LEVEL_INFO,
13664 "%s: MAC Spoofing enabled for current scan", __func__);
13665 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
13666 * to fill TxBds for probe request during current scan
13667 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013668 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053013669 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013670
13671 if(status != VOS_STATUS_SUCCESS)
13672 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013673 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013674 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053013675#ifdef FEATURE_WLAN_TDLS
13676 wlan_hdd_tdls_scan_done_callback(pAdapter);
13677#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013678 goto free_mem;
13679 }
Siddharth Bhal76972212014-10-15 16:22:51 +053013680 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053013681 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070013682 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013683 pAdapter->sessionId, &scanRequest, &scanId,
13684 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070013685
Jeff Johnson295189b2012-06-20 16:38:30 -070013686 if (eHAL_STATUS_SUCCESS != status)
13687 {
13688 hddLog(VOS_TRACE_LEVEL_ERROR,
13689 "%s: sme_ScanRequest returned error %d", __func__, status);
13690 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070013691 if(eHAL_STATUS_RESOURCES == status)
13692 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013693 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
13694 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070013695 status = -EBUSY;
13696 } else {
13697 status = -EIO;
13698 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013699 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013700
13701#ifdef FEATURE_WLAN_TDLS
13702 wlan_hdd_tdls_scan_done_callback(pAdapter);
13703#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013704 goto free_mem;
13705 }
13706
13707 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053013708 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070013709 pAdapter->request = request;
13710 pScanInfo->scanId = scanId;
13711
13712 complete(&pScanInfo->scan_req_completion_event);
13713
13714free_mem:
13715 if( scanRequest.SSIDs.SSIDList )
13716 {
13717 vos_mem_free(scanRequest.SSIDs.SSIDList);
13718 }
13719
13720 if( channelList )
13721 vos_mem_free( channelList );
13722
13723 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013724 return status;
13725}
13726
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013727int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
13728#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13729 struct net_device *dev,
13730#endif
13731 struct cfg80211_scan_request *request)
13732{
13733 int ret;
13734
13735 vos_ssr_protect(__func__);
13736 ret = __wlan_hdd_cfg80211_scan(wiphy,
13737#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13738 dev,
13739#endif
13740 request);
13741 vos_ssr_unprotect(__func__);
13742
13743 return ret;
13744}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013745
13746void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
13747{
13748 v_U8_t iniDot11Mode =
13749 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
13750 eHddDot11Mode hddDot11Mode = iniDot11Mode;
13751
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013752 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
13753 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013754 switch ( iniDot11Mode )
13755 {
13756 case eHDD_DOT11_MODE_AUTO:
13757 case eHDD_DOT11_MODE_11ac:
13758 case eHDD_DOT11_MODE_11ac_ONLY:
13759#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053013760 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
13761 sme_IsFeatureSupportedByFW(DOT11AC) )
13762 hddDot11Mode = eHDD_DOT11_MODE_11ac;
13763 else
13764 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013765#else
13766 hddDot11Mode = eHDD_DOT11_MODE_11n;
13767#endif
13768 break;
13769 case eHDD_DOT11_MODE_11n:
13770 case eHDD_DOT11_MODE_11n_ONLY:
13771 hddDot11Mode = eHDD_DOT11_MODE_11n;
13772 break;
13773 default:
13774 hddDot11Mode = iniDot11Mode;
13775 break;
13776 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053013777#ifdef WLAN_FEATURE_AP_HT40_24G
13778 if (operationChannel > SIR_11B_CHANNEL_END)
13779#endif
13780 {
13781 /* This call decides required channel bonding mode */
13782 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013783 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
13784 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053013785 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013786}
13787
Jeff Johnson295189b2012-06-20 16:38:30 -070013788/*
13789 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013790 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070013791 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013792int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013793 const u8 *ssid, size_t ssid_len, const u8 *bssid,
13794 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070013795{
13796 int status = 0;
13797 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080013798 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013799 v_U32_t roamId;
13800 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070013801 eCsrAuthType RSNAuthType;
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013802 const u8 *pValidBssid = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013803
13804 ENTER();
13805
13806 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080013807 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13808
13809 status = wlan_hdd_validate_context(pHddCtx);
13810 if (status)
13811 {
Yue Mae36e3552014-03-05 17:06:20 -080013812 return status;
13813 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013814
Jeff Johnson295189b2012-06-20 16:38:30 -070013815 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
13816 {
13817 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
13818 return -EINVAL;
13819 }
13820
13821 pRoamProfile = &pWextState->roamProfile;
13822
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013823 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070013824 {
Jeff Johnsone7245742012-09-05 17:12:55 -070013825 hdd_station_ctx_t *pHddStaCtx;
13826 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013827
Siddharth Bhalda0d1622015-04-24 15:47:49 +053013828 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
13829
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013830 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070013831 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
13832 {
13833 /*QoS not enabled in cfg file*/
13834 pRoamProfile->uapsd_mask = 0;
13835 }
13836 else
13837 {
13838 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013839 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070013840 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
13841 }
13842
13843 pRoamProfile->SSIDs.numOfSSIDs = 1;
13844 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
13845 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013846 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070013847 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
13848 ssid, ssid_len);
13849
13850 if (bssid)
13851 {
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013852 pValidBssid = bssid;
13853 }
13854 else if (bssid_hint)
13855 {
13856 pValidBssid = bssid_hint;
13857 }
13858 if (pValidBssid)
13859 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013860 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013861 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), pValidBssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070013862 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013863 /* Save BSSID in seperate variable as well, as RoamProfile
13864 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070013865 case of join failure we should send valid BSSID to supplicant
13866 */
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013867 vos_mem_copy((void *)(pWextState->req_bssId), pValidBssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070013868 WNI_CFG_BSSID_LEN);
13869 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070013870 else
13871 {
13872 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
13873 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013874
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013875 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
13876 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070013877 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
13878 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013879 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013880 /*set gen ie*/
13881 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
13882 /*set auth*/
13883 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
13884 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013885#ifdef FEATURE_WLAN_WAPI
13886 if (pAdapter->wapi_info.nWapiMode)
13887 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013888 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013889 switch (pAdapter->wapi_info.wapiAuthMode)
13890 {
13891 case WAPI_AUTH_MODE_PSK:
13892 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013893 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013894 pAdapter->wapi_info.wapiAuthMode);
13895 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
13896 break;
13897 }
13898 case WAPI_AUTH_MODE_CERT:
13899 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013900 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013901 pAdapter->wapi_info.wapiAuthMode);
13902 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
13903 break;
13904 }
13905 } // End of switch
13906 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
13907 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
13908 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013909 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013910 pRoamProfile->AuthType.numEntries = 1;
13911 pRoamProfile->EncryptionType.numEntries = 1;
13912 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
13913 pRoamProfile->mcEncryptionType.numEntries = 1;
13914 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
13915 }
13916 }
13917#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013918#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013919 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013920 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
13921 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
13922 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013923 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
13924 sizeof (tSirGtkOffloadParams));
13925 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013926 }
13927#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013928 pRoamProfile->csrPersona = pAdapter->device_mode;
13929
Jeff Johnson32d95a32012-09-10 13:15:23 -070013930 if( operatingChannel )
13931 {
13932 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
13933 pRoamProfile->ChannelInfo.numOfChannels = 1;
13934 }
Chet Lanctot186b5732013-03-18 10:26:30 -070013935 else
13936 {
13937 pRoamProfile->ChannelInfo.ChannelList = NULL;
13938 pRoamProfile->ChannelInfo.numOfChannels = 0;
13939 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013940 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
13941 {
13942 hdd_select_cbmode(pAdapter,operatingChannel);
13943 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013944
Agarwal Ashish40f9b872015-09-01 16:17:35 +053013945 /*
13946 * Change conn_state to connecting before sme_RoamConnect(),
13947 * because sme_RoamConnect() has a direct path to call
13948 * hdd_smeRoamCallback(), which will change the conn_state
13949 * If direct path, conn_state will be accordingly changed
13950 * to NotConnected or Associated by either
13951 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
13952 * in sme_RoamCallback()
13953 * if sme_RomConnect is to be queued,
13954 * Connecting state will remain until it is completed.
13955 * If connection state is not changed,
13956 * connection state will remain in eConnectionState_NotConnected state.
13957 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
13958 * if conn state is eConnectionState_NotConnected.
13959 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
13960 * informed of connect result indication which is an issue.
13961 */
13962
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053013963 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
13964 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053013965 {
13966 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053013967 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080013968 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
13969 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053013970 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013971 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013972 pAdapter->sessionId, pRoamProfile, &roamId);
13973
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053013974 if ((eHAL_STATUS_SUCCESS != status) &&
13975 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
13976 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053013977
13978 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053013979 hddLog(VOS_TRACE_LEVEL_ERROR,
13980 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
13981 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080013982 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053013983 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080013984 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053013985 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080013986
13987 pRoamProfile->ChannelInfo.ChannelList = NULL;
13988 pRoamProfile->ChannelInfo.numOfChannels = 0;
13989
Jeff Johnson295189b2012-06-20 16:38:30 -070013990 }
13991 else
13992 {
13993 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
13994 return -EINVAL;
13995 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080013996 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013997 return status;
13998}
13999
14000/*
14001 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
14002 * This function is used to set the authentication type (OPEN/SHARED).
14003 *
14004 */
14005static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
14006 enum nl80211_auth_type auth_type)
14007{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014008 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014009 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14010
14011 ENTER();
14012
14013 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014014 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070014015 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014016 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053014017 hddLog(VOS_TRACE_LEVEL_INFO,
14018 "%s: set authentication type to AUTOSWITCH", __func__);
14019 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
14020 break;
14021
14022 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014023#ifdef WLAN_FEATURE_VOWIFI_11R
14024 case NL80211_AUTHTYPE_FT:
14025#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014026 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070014027 "%s: set authentication type to OPEN", __func__);
14028 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
14029 break;
14030
14031 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014032 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070014033 "%s: set authentication type to SHARED", __func__);
14034 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
14035 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080014036#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070014037 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014038 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070014039 "%s: set authentication type to CCKM WPA", __func__);
14040 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
14041 break;
14042#endif
14043
14044
14045 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014046 hddLog(VOS_TRACE_LEVEL_ERROR,
14047 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014048 auth_type);
14049 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
14050 return -EINVAL;
14051 }
14052
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014053 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070014054 pHddStaCtx->conn_info.authType;
14055 return 0;
14056}
14057
14058/*
14059 * FUNCTION: wlan_hdd_set_akm_suite
14060 * This function is used to set the key mgmt type(PSK/8021x).
14061 *
14062 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014063static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014064 u32 key_mgmt
14065 )
14066{
14067 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
14068 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053014069 /* Should be in ieee802_11_defs.h */
14070#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
14071#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070014072 /*set key mgmt type*/
14073 switch(key_mgmt)
14074 {
14075 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053014076 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053014077#ifdef WLAN_FEATURE_VOWIFI_11R
14078 case WLAN_AKM_SUITE_FT_PSK:
14079#endif
14080 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070014081 __func__);
14082 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
14083 break;
14084
14085 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053014086 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053014087#ifdef WLAN_FEATURE_VOWIFI_11R
14088 case WLAN_AKM_SUITE_FT_8021X:
14089#endif
14090 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070014091 __func__);
14092 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
14093 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080014094#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070014095#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
14096#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
14097 case WLAN_AKM_SUITE_CCKM:
14098 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
14099 __func__);
14100 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
14101 break;
14102#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070014103#ifndef WLAN_AKM_SUITE_OSEN
14104#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
14105 case WLAN_AKM_SUITE_OSEN:
14106 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
14107 __func__);
14108 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
14109 break;
14110#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014111
14112 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014113 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014114 __func__, key_mgmt);
14115 return -EINVAL;
14116
14117 }
14118 return 0;
14119}
14120
14121/*
14122 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014123 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070014124 * (NONE/WEP40/WEP104/TKIP/CCMP).
14125 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014126static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
14127 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070014128 bool ucast
14129 )
14130{
14131 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014132 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014133 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14134
14135 ENTER();
14136
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014137 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070014138 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053014139 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070014140 __func__, cipher);
14141 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
14142 }
14143 else
14144 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014145
Jeff Johnson295189b2012-06-20 16:38:30 -070014146 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014147 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070014148 {
14149 case IW_AUTH_CIPHER_NONE:
14150 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
14151 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014152
Jeff Johnson295189b2012-06-20 16:38:30 -070014153 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053014154 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070014155 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014156
Jeff Johnson295189b2012-06-20 16:38:30 -070014157 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053014158 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070014159 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014160
Jeff Johnson295189b2012-06-20 16:38:30 -070014161 case WLAN_CIPHER_SUITE_TKIP:
14162 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
14163 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014164
Jeff Johnson295189b2012-06-20 16:38:30 -070014165 case WLAN_CIPHER_SUITE_CCMP:
14166 encryptionType = eCSR_ENCRYPT_TYPE_AES;
14167 break;
14168#ifdef FEATURE_WLAN_WAPI
14169 case WLAN_CIPHER_SUITE_SMS4:
14170 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
14171 break;
14172#endif
14173
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080014174#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070014175 case WLAN_CIPHER_SUITE_KRK:
14176 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
14177 break;
14178#endif
14179 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014180 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014181 __func__, cipher);
14182 return -EOPNOTSUPP;
14183 }
14184 }
14185
14186 if (ucast)
14187 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014188 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014189 __func__, encryptionType);
14190 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
14191 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014192 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070014193 encryptionType;
14194 }
14195 else
14196 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014197 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014198 __func__, encryptionType);
14199 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
14200 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
14201 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
14202 }
14203
14204 return 0;
14205}
14206
14207
14208/*
14209 * FUNCTION: wlan_hdd_cfg80211_set_ie
14210 * This function is used to parse WPA/RSN IE's.
14211 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014212int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014213#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14214 const u8 *ie,
14215#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014216 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014217#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014218 size_t ie_len
14219 )
14220{
14221 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014222#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14223 const u8 *genie = ie;
14224#else
Jeff Johnson295189b2012-06-20 16:38:30 -070014225 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014226#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014227 v_U16_t remLen = ie_len;
14228#ifdef FEATURE_WLAN_WAPI
14229 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
14230 u16 *tmp;
14231 v_U16_t akmsuiteCount;
14232 int *akmlist;
14233#endif
14234 ENTER();
14235
14236 /* clear previous assocAddIE */
14237 pWextState->assocAddIE.length = 0;
14238 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070014239 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014240
14241 while (remLen >= 2)
14242 {
14243 v_U16_t eLen = 0;
14244 v_U8_t elementId;
14245 elementId = *genie++;
14246 eLen = *genie++;
14247 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014248
Arif Hussain6d2a3322013-11-17 19:50:10 -080014249 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070014250 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014251
14252 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070014253 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014254 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014255 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 -070014256 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014257 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014258 "%s: Invalid WPA IE", __func__);
14259 return -EINVAL;
14260 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014261 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070014262 {
14263 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014264 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070014265 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014266
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014267 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070014268 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014269 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
14270 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070014271 VOS_ASSERT(0);
14272 return -ENOMEM;
14273 }
14274 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
14275 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14276 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014277
Jeff Johnson295189b2012-06-20 16:38:30 -070014278 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
14279 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14280 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14281 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014282 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
14283 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014284 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
14285 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
14286 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
14287 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
14288 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
14289 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014290 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053014291 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070014292 {
14293 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014294 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070014295 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014296
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014297 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070014298 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014299 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14300 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070014301 VOS_ASSERT(0);
14302 return -ENOMEM;
14303 }
14304 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
14305 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14306 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014307
Jeff Johnson295189b2012-06-20 16:38:30 -070014308 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14309 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14310 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014311#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014312 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
14313 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070014314 /*Consider WFD IE, only for P2P Client */
14315 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
14316 {
14317 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014318 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070014319 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014320
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014321 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070014322 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014323 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14324 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070014325 VOS_ASSERT(0);
14326 return -ENOMEM;
14327 }
14328 // WFD IE is saved to Additional IE ; it should be accumulated to handle
14329 // WPS IE + P2P IE + WFD IE
14330 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14331 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014332
Jeff Johnson295189b2012-06-20 16:38:30 -070014333 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14334 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14335 }
14336#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014337 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014338 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014339 HS20_OUI_TYPE_SIZE)) )
14340 {
14341 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014342 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014343 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014344
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014345 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014346 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014347 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14348 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014349 VOS_ASSERT(0);
14350 return -ENOMEM;
14351 }
14352 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14353 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014354
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014355 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14356 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14357 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070014358 /* Appending OSEN Information Element in Assiciation Request */
14359 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
14360 OSEN_OUI_TYPE_SIZE)) )
14361 {
14362 v_U16_t curAddIELen = pWextState->assocAddIE.length;
14363 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
14364 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014365
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014366 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070014367 {
14368 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14369 "Need bigger buffer space");
14370 VOS_ASSERT(0);
14371 return -ENOMEM;
14372 }
14373 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14374 pWextState->assocAddIE.length += eLen + 2;
14375
14376 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
14377 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14378 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14379 }
14380
Abhishek Singh4322e622015-06-10 15:42:54 +053014381 /* Update only for WPA IE */
14382 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
14383 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070014384
14385 /* populating as ADDIE in beacon frames */
14386 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014387 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070014388 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
14389 {
14390 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
14391 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
14392 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
14393 {
14394 hddLog(LOGE,
14395 "Coldn't pass "
14396 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
14397 }
14398 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
14399 else
14400 hddLog(LOGE,
14401 "Could not pass on "
14402 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
14403
14404 /* IBSS mode doesn't contain params->proberesp_ies still
14405 beaconIE's need to be populated in probe response frames */
14406 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
14407 {
14408 u16 rem_probe_resp_ie_len = eLen + 2;
14409 u8 probe_rsp_ie_len[3] = {0};
14410 u8 counter = 0;
14411
14412 /* Check Probe Resp Length if it is greater then 255 then
14413 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
14414 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
14415 not able Store More then 255 bytes into One Variable */
14416
14417 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
14418 {
14419 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
14420 {
14421 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
14422 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
14423 }
14424 else
14425 {
14426 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
14427 rem_probe_resp_ie_len = 0;
14428 }
14429 }
14430
14431 rem_probe_resp_ie_len = 0;
14432
14433 if (probe_rsp_ie_len[0] > 0)
14434 {
14435 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
14436 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
14437 (tANI_U8*)(genie - 2),
14438 probe_rsp_ie_len[0], NULL,
14439 eANI_BOOLEAN_FALSE)
14440 == eHAL_STATUS_FAILURE)
14441 {
14442 hddLog(LOGE,
14443 "Could not pass"
14444 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
14445 }
14446 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
14447 }
14448
14449 if (probe_rsp_ie_len[1] > 0)
14450 {
14451 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
14452 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
14453 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
14454 probe_rsp_ie_len[1], NULL,
14455 eANI_BOOLEAN_FALSE)
14456 == eHAL_STATUS_FAILURE)
14457 {
14458 hddLog(LOGE,
14459 "Could not pass"
14460 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
14461 }
14462 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
14463 }
14464
14465 if (probe_rsp_ie_len[2] > 0)
14466 {
14467 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
14468 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
14469 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
14470 probe_rsp_ie_len[2], NULL,
14471 eANI_BOOLEAN_FALSE)
14472 == eHAL_STATUS_FAILURE)
14473 {
14474 hddLog(LOGE,
14475 "Could not pass"
14476 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
14477 }
14478 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
14479 }
14480
14481 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
14482 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
14483 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
14484 {
14485 hddLog(LOGE,
14486 "Could not pass"
14487 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
14488 }
14489 }
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070014490 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070014491 break;
14492 case DOT11F_EID_RSN:
14493 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
14494 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
14495 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
14496 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
14497 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
14498 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053014499
Abhishek Singhb16f3562016-01-20 11:08:32 +053014500 /* Appending extended capabilities with Interworking or
14501 * bsstransition bit set in Assoc Req.
Abhishek Singh15d95602015-03-24 15:52:57 +053014502 *
14503 * In assoc req this EXT Cap will only be taken into account if
Abhishek Singhb16f3562016-01-20 11:08:32 +053014504 * interworkingService or bsstransition bit is set to 1.
14505 * Driver is only interested in interworkingService and
14506 * bsstransition capability from supplicant.
14507 * If in future any other EXT Cap info is
Abhishek Singh15d95602015-03-24 15:52:57 +053014508 * required from supplicat, it needs to be handled while
14509 * sending Assoc Req in LIM.
14510 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014511 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014512 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014513 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014514 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014515 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014516
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014517 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014518 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014519 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14520 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014521 VOS_ASSERT(0);
14522 return -ENOMEM;
14523 }
14524 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14525 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014526
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014527 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14528 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14529 break;
14530 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014531#ifdef FEATURE_WLAN_WAPI
14532 case WLAN_EID_WAPI:
14533 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070014534 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070014535 pAdapter->wapi_info.nWapiMode);
14536 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014537 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070014538 akmsuiteCount = WPA_GET_LE16(tmp);
14539 tmp = tmp + 1;
14540 akmlist = (int *)(tmp);
14541 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
14542 {
14543 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
14544 }
14545 else
14546 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014547 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070014548 VOS_ASSERT(0);
14549 return -EINVAL;
14550 }
14551
14552 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
14553 {
14554 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014555 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014556 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014557 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014558 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014559 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014560 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014561 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014562 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
14563 }
14564 break;
14565#endif
14566 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014567 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014568 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014569 /* when Unknown IE is received we should break and continue
14570 * to the next IE in the buffer instead we were returning
14571 * so changing this to break */
14572 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070014573 }
14574 genie += eLen;
14575 remLen -= eLen;
14576 }
14577 EXIT();
14578 return 0;
14579}
14580
14581/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053014582 * FUNCTION: hdd_isWPAIEPresent
14583 * Parse the received IE to find the WPA IE
14584 *
14585 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014586static bool hdd_isWPAIEPresent(
14587#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
14588 const u8 *ie,
14589#else
14590 u8 *ie,
14591#endif
14592 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053014593{
14594 v_U8_t eLen = 0;
14595 v_U16_t remLen = ie_len;
14596 v_U8_t elementId = 0;
14597
14598 while (remLen >= 2)
14599 {
14600 elementId = *ie++;
14601 eLen = *ie++;
14602 remLen -= 2;
14603 if (eLen > remLen)
14604 {
14605 hddLog(VOS_TRACE_LEVEL_ERROR,
14606 "%s: IE length is wrong %d", __func__, eLen);
14607 return FALSE;
14608 }
14609 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
14610 {
14611 /* OUI - 0x00 0X50 0XF2
14612 WPA Information Element - 0x01
14613 WPA version - 0x01*/
14614 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
14615 return TRUE;
14616 }
14617 ie += eLen;
14618 remLen -= eLen;
14619 }
14620 return FALSE;
14621}
14622
14623/*
Jeff Johnson295189b2012-06-20 16:38:30 -070014624 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014625 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070014626 * parameters during connect operation.
14627 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014628int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014629 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014630 )
Jeff Johnson295189b2012-06-20 16:38:30 -070014631{
14632 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014633 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014634 ENTER();
14635
14636 /*set wpa version*/
14637 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
14638
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014639 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070014640 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053014641 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070014642 {
14643 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
14644 }
14645 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
14646 {
14647 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
14648 }
14649 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014650
14651 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014652 pWextState->wpaVersion);
14653
14654 /*set authentication type*/
14655 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
14656
14657 if (0 > status)
14658 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014659 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014660 "%s: failed to set authentication type ", __func__);
14661 return status;
14662 }
14663
14664 /*set key mgmt type*/
14665 if (req->crypto.n_akm_suites)
14666 {
14667 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
14668 if (0 > status)
14669 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014670 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070014671 __func__);
14672 return status;
14673 }
14674 }
14675
14676 /*set pairwise cipher type*/
14677 if (req->crypto.n_ciphers_pairwise)
14678 {
14679 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
14680 req->crypto.ciphers_pairwise[0], true);
14681 if (0 > status)
14682 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014683 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014684 "%s: failed to set unicast cipher type", __func__);
14685 return status;
14686 }
14687 }
14688 else
14689 {
14690 /*Reset previous cipher suite to none*/
14691 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
14692 if (0 > status)
14693 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014694 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014695 "%s: failed to set unicast cipher type", __func__);
14696 return status;
14697 }
14698 }
14699
14700 /*set group cipher type*/
14701 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
14702 false);
14703
14704 if (0 > status)
14705 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014706 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070014707 __func__);
14708 return status;
14709 }
14710
Chet Lanctot186b5732013-03-18 10:26:30 -070014711#ifdef WLAN_FEATURE_11W
14712 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
14713#endif
14714
Jeff Johnson295189b2012-06-20 16:38:30 -070014715 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
14716 if (req->ie_len)
14717 {
14718 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
14719 if ( 0 > status)
14720 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014721 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070014722 __func__);
14723 return status;
14724 }
14725 }
14726
14727 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014728 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070014729 {
14730 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
14731 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
14732 )
14733 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014734 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070014735 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
14736 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014737 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070014738 __func__);
14739 return -EOPNOTSUPP;
14740 }
14741 else
14742 {
14743 u8 key_len = req->key_len;
14744 u8 key_idx = req->key_idx;
14745
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014746 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070014747 && (CSR_MAX_NUM_KEY > key_idx)
14748 )
14749 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014750 hddLog(VOS_TRACE_LEVEL_INFO,
14751 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070014752 __func__, key_idx, key_len);
14753 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014754 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070014755 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014756 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070014757 (u8)key_len;
14758 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
14759 }
14760 }
14761 }
14762 }
14763
14764 return status;
14765}
14766
14767/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014768 * FUNCTION: wlan_hdd_try_disconnect
14769 * This function is used to disconnect from previous
14770 * connection
14771 */
14772static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
14773{
14774 long ret = 0;
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014775 int status, result = 0;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014776 hdd_station_ctx_t *pHddStaCtx;
14777 eMib_dot11DesiredBssType connectedBssType;
Abhishek Singh19a7dd92015-12-30 16:31:51 +053014778 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014779
Abhishek Singh19a7dd92015-12-30 16:31:51 +053014780 ret = wlan_hdd_validate_context(pHddCtx);
14781 if (0 != ret)
14782 {
14783 return ret;
14784 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014785 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14786
14787 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
14788
14789 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
14790 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
Abhishek Singh630ff592016-01-07 18:15:53 +053014791 (eConnectionState_Connecting == pHddStaCtx->conn_info.connState) ||
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014792 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
14793 {
Abhishek Singh19a7dd92015-12-30 16:31:51 +053014794 spin_lock_bh(&pAdapter->lock_for_active_session);
14795 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
14796 {
14797 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
14798 }
14799 spin_unlock_bh(&pAdapter->lock_for_active_session);
Abhishek Singhf7962582015-10-23 10:54:06 +053014800 hdd_connSetConnectionState(pHddStaCtx,
14801 eConnectionState_Disconnecting);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014802 /* Issue disconnect to CSR */
14803 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014804 status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014805 pAdapter->sessionId,
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014806 eCSR_DISCONNECT_REASON_UNSPECIFIED);
14807 if(eHAL_STATUS_CMD_NOT_QUEUED == status) {
14808 hddLog(LOG1,
14809 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
14810 } else if ( 0 != status ) {
14811 hddLog(LOGE,
14812 FL("csrRoamDisconnect failure, returned %d"),
14813 (int)status );
14814 result = -EINVAL;
14815 goto disconnected;
14816 }
14817 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014818 &pAdapter->disconnect_comp_var,
14819 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014820 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status)) {
14821 hddLog(LOGE,
14822 "%s: Failed to disconnect, timed out", __func__);
14823 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014824 }
14825 }
14826 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
14827 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014828 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014829 &pAdapter->disconnect_comp_var,
14830 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014831 if (!ret)
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014832 {
14833 hddLog(LOGE, FL("Failed to receive disconnect event"));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014834 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014835 }
14836 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014837disconnected:
14838 hddLog(LOG1,
14839 FL("Set HDD connState to eConnectionState_NotConnected"));
14840 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
14841 return result;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014842}
14843
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053014844/**
14845 * wlan_hdd_reassoc_bssid_hint() - Start reassociation if bssid is present
14846 * @adapter: Pointer to the HDD adapter
14847 * @req: Pointer to the structure cfg_connect_params receieved from user space
14848 *
14849 * This function will start reassociation if bssid hint, channel hint and
14850 * previous bssid parameters are present in the connect request
14851 *
14852 * Return: success if reassociation is happening
14853 * Error code if reassociation is not permitted or not happening
14854 */
14855#ifdef CFG80211_CONNECT_PREV_BSSID
14856static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
14857 struct cfg80211_connect_params *req)
14858{
14859 int status = -EPERM;
14860 if (req->bssid_hint && req->channel_hint && req->prev_bssid) {
14861 hddLog(VOS_TRACE_LEVEL_INFO,
14862 FL("REASSOC Attempt on channel %d to "MAC_ADDRESS_STR),
14863 req->channel_hint->hw_value,
14864 MAC_ADDR_ARRAY(req->bssid_hint));
14865 status = hdd_reassoc(adapter, req->bssid_hint,
14866 req->channel_hint->hw_value,
14867 CONNECT_CMD_USERSPACE);
14868 }
14869 return status;
14870}
14871#else
14872static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
14873 struct cfg80211_connect_params *req)
14874{
14875 return -EPERM;
14876}
14877#endif
14878
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014879/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053014880 * FUNCTION: __wlan_hdd_cfg80211_connect
14881 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070014882 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014883static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014884 struct net_device *ndev,
14885 struct cfg80211_connect_params *req
14886 )
14887{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014888 int status;
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053014889 u16 channel;
Edhar, Mahesh Kumar496c7f72016-03-18 12:47:44 +053014890#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) || \
14891 defined(CFG80211_BSSID_HINT_BACKPORT)
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053014892 const u8 *bssid_hint = req->bssid_hint;
14893#else
14894 const u8 *bssid_hint = NULL;
14895#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014896 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070014897 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053014898 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014899
14900 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014901
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014902 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14903 TRACE_CODE_HDD_CFG80211_CONNECT,
14904 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014905 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014906 "%s: device_mode = %s (%d)", __func__,
14907 hdd_device_modetoString(pAdapter->device_mode),
14908 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070014909
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014910 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080014911 if (!pHddCtx)
14912 {
14913 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14914 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053014915 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080014916 }
14917
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014918 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014919 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070014920 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014921 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014922 }
14923
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053014924 status = wlan_hdd_reassoc_bssid_hint(pAdapter, req);
14925 if (0 == status)
14926 return status;
14927
Agarwal Ashish51325b52014-06-16 16:50:49 +053014928
Jeff Johnson295189b2012-06-20 16:38:30 -070014929#ifdef WLAN_BTAMP_FEATURE
14930 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014931 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070014932 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014933 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014934 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080014935 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070014936 }
14937#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014938
14939 //If Device Mode is Station Concurrent Sessions Exit BMps
14940 //P2P Mode will be taken care in Open/close adapter
14941 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053014942 (vos_concurrent_open_sessions_running())) {
14943 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
14944 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014945 }
14946
14947 /*Try disconnecting if already in connected state*/
14948 status = wlan_hdd_try_disconnect(pAdapter);
14949 if ( 0 > status)
14950 {
14951 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
14952 " connection"));
14953 return -EALREADY;
14954 }
Agrawal Ashish559530c2015-12-01 18:04:20 +053014955 /* Check for max concurrent connections after doing disconnect if any*/
14956 if (vos_max_concurrent_connections_reached()) {
14957 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
14958 return -ECONNREFUSED;
14959 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014960
Jeff Johnson295189b2012-06-20 16:38:30 -070014961 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014962 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070014963
14964 if ( 0 > status)
14965 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014966 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070014967 __func__);
14968 return status;
14969 }
Sravan Kumar Kairam589c5722016-01-27 20:28:53 +053014970
14971 if (pHddCtx->spoofMacAddr.isEnabled)
14972 {
14973 hddLog(VOS_TRACE_LEVEL_INFO,
14974 "%s: MAC Spoofing enabled ", __func__);
14975 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
14976 * to fill TxBds for probe request during SSID scan which may happen
14977 * as part of connect command
14978 */
14979 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
14980 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
14981 if (status != VOS_STATUS_SUCCESS)
14982 return -ECONNREFUSED;
14983 }
14984
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053014985 if (req->channel)
14986 channel = req->channel->hw_value;
Mohit Khanna765234a2012-09-11 15:08:35 -070014987 else
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053014988 channel = 0;
Kapil Gupta312028a2016-10-25 14:15:20 +053014989
14990 /* Abort if any scan is going on */
14991 status = wlan_hdd_scan_abort(pAdapter);
14992 if (0 != status)
14993 hddLog(VOS_TRACE_LEVEL_ERROR, FL("scan abort failed"));
14994
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053014995 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
14996 req->ssid_len, req->bssid,
14997 bssid_hint, channel);
Jeff Johnson295189b2012-06-20 16:38:30 -070014998
Sushant Kaushikd7083982015-03-18 14:33:24 +053014999 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070015000 {
15001 //ReEnable BMPS if disabled
15002 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
15003 (NULL != pHddCtx))
15004 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053015005 if (pHddCtx->hdd_wlan_suspended)
15006 {
15007 hdd_set_pwrparams(pHddCtx);
15008 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015009 //ReEnable Bmps and Imps back
15010 hdd_enable_bmps_imps(pHddCtx);
15011 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053015012 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070015013 return status;
15014 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015015 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015016 EXIT();
15017 return status;
15018}
15019
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015020static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
15021 struct net_device *ndev,
15022 struct cfg80211_connect_params *req)
15023{
15024 int ret;
15025 vos_ssr_protect(__func__);
15026 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
15027 vos_ssr_unprotect(__func__);
15028
15029 return ret;
15030}
Jeff Johnson295189b2012-06-20 16:38:30 -070015031
15032/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015033 * FUNCTION: wlan_hdd_disconnect
15034 * This function is used to issue a disconnect request to SME
15035 */
15036int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
15037{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015038 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015039 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015040 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053015041 long ret;
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053015042 eConnectionState prev_conn_state;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015043
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015044 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015045
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015046 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015047 if (0 != status)
15048 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015049 return status;
15050 }
Abhishek Singh07e4a892015-11-23 11:29:57 +053015051 /* Indicate sme of disconnect so that in progress connection or preauth
15052 * can be aborted
15053 */
15054 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
Sushant Kaushikb4834d22015-07-15 15:29:05 +053015055 pAdapter->sessionId);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015056 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053015057
Agarwal Ashish47d18112014-08-04 19:55:07 +053015058 /* Need to apply spin lock before decreasing active sessions
15059 * as there can be chance for double decrement if context switch
15060 * Calls hdd_DisConnectHandler.
15061 */
15062
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053015063 prev_conn_state = pHddStaCtx->conn_info.connState;
15064
Agarwal Ashish47d18112014-08-04 19:55:07 +053015065 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053015066 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
15067 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053015068 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
15069 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053015070 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
15071 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053015072
Abhishek Singhf4669da2014-05-26 15:07:49 +053015073 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053015074 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
15075
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015076 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015077
Mihir Shete182a0b22014-08-18 16:08:48 +053015078 /*
15079 * stop tx queues before deleting STA/BSS context from the firmware.
15080 * tx has to be disabled because the firmware can get busy dropping
15081 * the tx frames after BSS/STA has been deleted and will not send
15082 * back a response resulting in WDI timeout
15083 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053015084 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053015085 netif_tx_disable(pAdapter->dev);
15086 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015087
Mihir Shete182a0b22014-08-18 16:08:48 +053015088 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015089 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
15090 pAdapter->sessionId, reason);
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053015091 if((eHAL_STATUS_CMD_NOT_QUEUED == status) &&
15092 prev_conn_state != eConnectionState_Connecting)
15093 {
15094 hddLog(LOG1,
15095 FL("status = %d, already disconnected"), status);
15096 result = 0;
15097 goto disconnected;
15098 }
15099 /*
15100 * Wait here instead of returning directly, this will block the next
15101 * connect command and allow processing of the scan for ssid and
15102 * the previous connect command in CSR. Else we might hit some
15103 * race conditions leading to SME and HDD out of sync.
15104 */
15105 else if(eHAL_STATUS_CMD_NOT_QUEUED == status)
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015106 {
15107 hddLog(LOG1,
15108 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053015109 }
15110 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015111 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015112 hddLog(LOGE,
15113 FL("csrRoamDisconnect failure, returned %d"),
15114 (int)status);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015115 result = -EINVAL;
15116 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015117 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015118 ret = wait_for_completion_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015119 &pAdapter->disconnect_comp_var,
15120 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015121 if (!ret && (eHAL_STATUS_CMD_NOT_QUEUED != status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015122 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015123 hddLog(LOGE,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053015124 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015125 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053015126 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015127disconnected:
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015128 hddLog(LOG1,
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053015129 FL("Set HDD connState to eConnectionState_NotConnected"));
15130 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Mahesh A Saptasagar936ffc32016-05-25 11:27:43 +053015131#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
15132 /* Sending disconnect event to userspace for kernel version < 3.11
15133 * is handled by __cfg80211_disconnect call to __cfg80211_disconnected
15134 */
15135 hddLog(LOG1, FL("Send disconnected event to userspace"));
15136
Mahesh A Saptasagarf5859b12016-06-01 17:17:50 +053015137 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, true,
Mahesh A Saptasagar936ffc32016-05-25 11:27:43 +053015138 WLAN_REASON_UNSPECIFIED);
15139#endif
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053015140
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015141 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015142 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015143}
15144
15145
15146/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015147 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070015148 * This function is used to issue a disconnect request to SME
15149 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015150static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015151 struct net_device *dev,
15152 u16 reason
15153 )
15154{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015155 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015156 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053015157 tCsrRoamProfile *pRoamProfile;
15158 hdd_station_ctx_t *pHddStaCtx;
15159 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015160#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015161 tANI_U8 staIdx;
15162#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015163
Jeff Johnson295189b2012-06-20 16:38:30 -070015164 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015165
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053015166 if (!pAdapter) {
15167 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
15168 return -EINVAL;
15169 }
15170
15171 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15172 if (!pHddStaCtx) {
15173 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
15174 return -EINVAL;
15175 }
15176
15177 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15178 status = wlan_hdd_validate_context(pHddCtx);
15179 if (0 != status)
15180 {
15181 return status;
15182 }
15183
15184 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
15185
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015186 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15187 TRACE_CODE_HDD_CFG80211_DISCONNECT,
15188 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015189 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
15190 __func__, hdd_device_modetoString(pAdapter->device_mode),
15191 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015192
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015193 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
15194 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070015195
Jeff Johnson295189b2012-06-20 16:38:30 -070015196 if (NULL != pRoamProfile)
15197 {
15198 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053015199 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
15200 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070015201 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015202 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070015203 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015204 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070015205 switch(reason)
15206 {
15207 case WLAN_REASON_MIC_FAILURE:
15208 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
15209 break;
15210
15211 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
15212 case WLAN_REASON_DISASSOC_AP_BUSY:
15213 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
15214 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
15215 break;
15216
15217 case WLAN_REASON_PREV_AUTH_NOT_VALID:
15218 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053015219 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070015220 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
15221 break;
15222
Jeff Johnson295189b2012-06-20 16:38:30 -070015223 default:
15224 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
15225 break;
15226 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015227 pScanInfo = &pHddCtx->scan_info;
15228 if (pScanInfo->mScanPending)
15229 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053015230 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015231 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053015232 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053015233 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015234 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053015235 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015236#ifdef FEATURE_WLAN_TDLS
15237 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080015238 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015239 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080015240 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
15241 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015242 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015243 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080015244 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015245 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015246 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080015247 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015248 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015249 status = sme_DeleteTdlsPeerSta(
15250 WLAN_HDD_GET_HAL_CTX(pAdapter),
15251 pAdapter->sessionId,
15252 mac);
15253 if (status != eHAL_STATUS_SUCCESS) {
15254 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
15255 return -EPERM;
15256 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015257 }
15258 }
15259#endif
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053015260
15261 hddLog(LOG1, FL("Disconnecting with reasoncode:%u connState %d"),
15262 reasonCode,
15263 pHddStaCtx->conn_info.connState);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015264 status = wlan_hdd_disconnect(pAdapter, reasonCode);
15265 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070015266 {
15267 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080015268 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015269 __func__, (int)status );
15270 return -EINVAL;
15271 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015272 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053015273 else
15274 {
15275 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
15276 "called while in %d state", __func__,
15277 pHddStaCtx->conn_info.connState);
15278 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015279 }
15280 else
15281 {
15282 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
15283 }
15284
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015285 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015286 return status;
15287}
15288
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015289static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
15290 struct net_device *dev,
15291 u16 reason
15292 )
15293{
15294 int ret;
15295 vos_ssr_protect(__func__);
15296 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
15297 vos_ssr_unprotect(__func__);
15298
15299 return ret;
15300}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015301
Jeff Johnson295189b2012-06-20 16:38:30 -070015302/*
15303 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015304 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070015305 * settings in IBSS mode.
15306 */
15307static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015308 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070015309 struct cfg80211_ibss_params *params
15310 )
15311{
15312 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015313 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070015314 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
15315 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015316
Jeff Johnson295189b2012-06-20 16:38:30 -070015317 ENTER();
15318
15319 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070015320 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070015321
15322 if (params->ie_len && ( NULL != params->ie) )
15323 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015324 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
15325 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070015326 {
15327 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
15328 encryptionType = eCSR_ENCRYPT_TYPE_AES;
15329 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015330 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070015331 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070015332 tDot11fIEWPA dot11WPAIE;
15333 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015334 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070015335
Wilson Yang00256342013-10-10 23:13:38 -070015336 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015337 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
15338 params->ie_len, DOT11F_EID_WPA);
15339 if ( NULL != ie )
15340 {
15341 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
15342 // Unpack the WPA IE
15343 //Skip past the EID byte and length byte - and four byte WiFi OUI
15344 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
15345 &ie[2+4],
15346 ie[1] - 4,
15347 &dot11WPAIE);
15348 /*Extract the multicast cipher, the encType for unicast
15349 cipher for wpa-none is none*/
15350 encryptionType =
15351 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
15352 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015353 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015354
Jeff Johnson295189b2012-06-20 16:38:30 -070015355 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
15356
15357 if (0 > status)
15358 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015359 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070015360 __func__);
15361 return status;
15362 }
15363 }
15364
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015365 pWextState->roamProfile.AuthType.authType[0] =
15366 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070015367 eCSR_AUTH_TYPE_OPEN_SYSTEM;
15368
15369 if (params->privacy)
15370 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015371 /* Security enabled IBSS, At this time there is no information available
15372 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070015373 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015374 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070015375 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015376 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070015377 *enable privacy bit in beacons */
15378
15379 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
15380 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070015381 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
15382 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070015383 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
15384 pWextState->roamProfile.EncryptionType.numEntries = 1;
15385 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070015386 return status;
15387}
15388
15389/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015390 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015391 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070015392 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015393static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015394 struct net_device *dev,
15395 struct cfg80211_ibss_params *params
15396 )
15397{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015398 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070015399 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15400 tCsrRoamProfile *pRoamProfile;
15401 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015402 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15403 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015404 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070015405
15406 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015407
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015408 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15409 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
15410 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015411 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015412 "%s: device_mode = %s (%d)", __func__,
15413 hdd_device_modetoString(pAdapter->device_mode),
15414 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015415
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015416 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015417 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070015418 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015419 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015420 }
15421
15422 if (NULL == pWextState)
15423 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015424 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070015425 __func__);
15426 return -EIO;
15427 }
15428
Agarwal Ashish51325b52014-06-16 16:50:49 +053015429 if (vos_max_concurrent_connections_reached()) {
15430 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
15431 return -ECONNREFUSED;
15432 }
15433
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015434 /*Try disconnecting if already in connected state*/
15435 status = wlan_hdd_try_disconnect(pAdapter);
15436 if ( 0 > status)
15437 {
15438 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
15439 " IBSS connection"));
15440 return -EALREADY;
15441 }
15442
Jeff Johnson295189b2012-06-20 16:38:30 -070015443 pRoamProfile = &pWextState->roamProfile;
15444
15445 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
15446 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015447 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080015448 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015449 return -EINVAL;
15450 }
15451
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070015452 /* BSSID is provided by upper layers hence no need to AUTO generate */
15453 if (NULL != params->bssid) {
15454 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
15455 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
15456 hddLog (VOS_TRACE_LEVEL_ERROR,
15457 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
15458 return -EIO;
15459 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015460 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070015461 }
krunal sonie9002db2013-11-25 14:24:17 -080015462 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
15463 {
15464 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
15465 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
15466 {
15467 hddLog (VOS_TRACE_LEVEL_ERROR,
15468 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
15469 return -EIO;
15470 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015471
15472 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080015473 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015474 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080015475 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070015476
Jeff Johnson295189b2012-06-20 16:38:30 -070015477 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070015478 if (NULL !=
15479#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
15480 params->chandef.chan)
15481#else
15482 params->channel)
15483#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015484 {
15485 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015486 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
15487 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
15488 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
15489 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070015490
15491 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015492 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070015493 ieee80211_frequency_to_channel(
15494#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
15495 params->chandef.chan->center_freq);
15496#else
15497 params->channel->center_freq);
15498#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015499
15500 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
15501 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070015502 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015503 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
15504 __func__);
15505 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070015506 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015507
15508 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070015509 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015510 if (channelNum == validChan[indx])
15511 {
15512 break;
15513 }
15514 }
15515 if (indx >= numChans)
15516 {
15517 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015518 __func__, channelNum);
15519 return -EINVAL;
15520 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015521 /* Set the Operational Channel */
15522 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
15523 channelNum);
15524 pRoamProfile->ChannelInfo.numOfChannels = 1;
15525 pHddStaCtx->conn_info.operationChannel = channelNum;
15526 pRoamProfile->ChannelInfo.ChannelList =
15527 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070015528 }
15529
15530 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015531 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070015532 if (status < 0)
15533 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015534 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070015535 __func__);
15536 return status;
15537 }
15538
15539 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015540 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Abhishek Singh4d924682015-11-17 15:23:06 +053015541 params->ssid_len, (const u8 *)&bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015542 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070015543
15544 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070015545 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015546
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015547 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015548 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015549}
15550
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015551static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
15552 struct net_device *dev,
15553 struct cfg80211_ibss_params *params
15554 )
15555{
15556 int ret = 0;
15557
15558 vos_ssr_protect(__func__);
15559 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
15560 vos_ssr_unprotect(__func__);
15561
15562 return ret;
15563}
15564
Jeff Johnson295189b2012-06-20 16:38:30 -070015565/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015566 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015567 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070015568 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015569static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015570 struct net_device *dev
15571 )
15572{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015573 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015574 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15575 tCsrRoamProfile *pRoamProfile;
15576 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015577 int status;
Abhishek Singh69de3302016-11-11 16:44:32 +053015578 eHalStatus hal_status;
Abhishek Singh7cd040e2016-01-07 10:51:04 +053015579#ifdef WLAN_FEATURE_RMC
15580 tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN] = {0};
15581#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015582
15583 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015584
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015585 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15586 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
15587 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015588 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015589 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015590 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015591 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015592 }
15593
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015594 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
15595 hdd_device_modetoString(pAdapter->device_mode),
15596 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015597 if (NULL == pWextState)
15598 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015599 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070015600 __func__);
15601 return -EIO;
15602 }
15603
15604 pRoamProfile = &pWextState->roamProfile;
15605
15606 /* Issue disconnect only if interface type is set to IBSS */
15607 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
15608 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015609 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070015610 __func__);
15611 return -EINVAL;
15612 }
15613
Abhishek Singh7cd040e2016-01-07 10:51:04 +053015614#ifdef WLAN_FEATURE_RMC
15615 /* Clearing add IE of beacon */
15616 if (ccmCfgSetStr(pHddCtx->hHal,
15617 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0],
15618 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN,
15619 NULL, eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
15620 {
15621 hddLog (VOS_TRACE_LEVEL_ERROR,
15622 "%s: unable to clear PROBE_RSP_BCN_ADDNIE_DATA", __func__);
15623 return -EINVAL;
15624 }
15625 if (ccmCfgSetInt(pHddCtx->hHal,
15626 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0, NULL,
15627 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
15628 {
15629 hddLog (VOS_TRACE_LEVEL_ERROR,
15630 "%s: unable to clear WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
15631 __func__);
15632 return -EINVAL;
15633 }
15634
15635 // Reset WNI_CFG_PROBE_RSP Flags
15636 wlan_hdd_reset_prob_rspies(pAdapter);
15637
15638 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
15639 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 0,NULL,
15640 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
15641 {
15642 hddLog (VOS_TRACE_LEVEL_ERROR,
15643 "%s: unable to clear WNI_CFG_PROBE_RSP_ADDNIE_FLAG",
15644 __func__);
15645 return -EINVAL;
15646 }
15647#endif
15648
Jeff Johnson295189b2012-06-20 16:38:30 -070015649 /* Issue Disconnect request */
15650 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singh69de3302016-11-11 16:44:32 +053015651 hal_status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
15652 pAdapter->sessionId,
15653 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
15654 if (!HAL_STATUS_SUCCESS(hal_status)) {
15655 hddLog(LOGE,
15656 FL("sme_RoamDisconnect failed hal_status(%d)"),
15657 hal_status);
15658 return -EAGAIN;
15659 }
15660 status = wait_for_completion_timeout(
15661 &pAdapter->disconnect_comp_var,
15662 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
15663 if (!status) {
15664 hddLog(LOGE,
15665 FL("wait on disconnect_comp_var failed"));
15666 return -ETIMEDOUT;
15667 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015668
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015669 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015670 return 0;
15671}
15672
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015673static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
15674 struct net_device *dev
15675 )
15676{
15677 int ret = 0;
15678
15679 vos_ssr_protect(__func__);
15680 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
15681 vos_ssr_unprotect(__func__);
15682
15683 return ret;
15684}
15685
Jeff Johnson295189b2012-06-20 16:38:30 -070015686/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015687 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070015688 * This function is used to set the phy parameters
15689 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
15690 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015691static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015692 u32 changed)
15693{
15694 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
15695 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015696 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015697
15698 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015699
15700 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015701 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
15702 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015703
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015704 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015705 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015706 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015707 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015708 }
15709
Jeff Johnson295189b2012-06-20 16:38:30 -070015710 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
15711 {
15712 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
15713 WNI_CFG_RTS_THRESHOLD_STAMAX :
15714 wiphy->rts_threshold;
15715
15716 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015717 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070015718 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015719 hddLog(VOS_TRACE_LEVEL_ERROR,
15720 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015721 __func__, rts_threshold);
15722 return -EINVAL;
15723 }
15724
15725 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
15726 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015727 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015728 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015729 hddLog(VOS_TRACE_LEVEL_ERROR,
15730 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015731 __func__, rts_threshold);
15732 return -EIO;
15733 }
15734
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015735 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015736 rts_threshold);
15737 }
15738
15739 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
15740 {
15741 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
15742 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
15743 wiphy->frag_threshold;
15744
15745 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015746 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015747 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015748 hddLog(VOS_TRACE_LEVEL_ERROR,
15749 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015750 frag_threshold);
15751 return -EINVAL;
15752 }
15753
15754 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
15755 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015756 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015757 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015758 hddLog(VOS_TRACE_LEVEL_ERROR,
15759 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015760 __func__, frag_threshold);
15761 return -EIO;
15762 }
15763
15764 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
15765 frag_threshold);
15766 }
15767
15768 if ((changed & WIPHY_PARAM_RETRY_SHORT)
15769 || (changed & WIPHY_PARAM_RETRY_LONG))
15770 {
15771 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
15772 wiphy->retry_short :
15773 wiphy->retry_long;
15774
15775 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
15776 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
15777 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015778 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015779 __func__, retry_value);
15780 return -EINVAL;
15781 }
15782
15783 if (changed & WIPHY_PARAM_RETRY_SHORT)
15784 {
15785 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
15786 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015787 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015788 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015789 hddLog(VOS_TRACE_LEVEL_ERROR,
15790 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015791 __func__, retry_value);
15792 return -EIO;
15793 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015794 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015795 __func__, retry_value);
15796 }
15797 else if (changed & WIPHY_PARAM_RETRY_SHORT)
15798 {
15799 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
15800 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015801 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015802 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015803 hddLog(VOS_TRACE_LEVEL_ERROR,
15804 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015805 __func__, retry_value);
15806 return -EIO;
15807 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015808 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015809 __func__, retry_value);
15810 }
15811 }
15812
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015813 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015814 return 0;
15815}
15816
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015817static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
15818 u32 changed)
15819{
15820 int ret;
15821
15822 vos_ssr_protect(__func__);
15823 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
15824 vos_ssr_unprotect(__func__);
15825
15826 return ret;
15827}
15828
Jeff Johnson295189b2012-06-20 16:38:30 -070015829/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015830 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070015831 * This function is used to set the txpower
15832 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015833static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070015834#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15835 struct wireless_dev *wdev,
15836#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015837#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015838 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070015839#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015840 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070015841#endif
15842 int dbm)
15843{
15844 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015845 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015846 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
15847 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015848 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015849
15850 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015851
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015852 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15853 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
15854 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015855 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015856 if (0 != status)
15857 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015858 return status;
15859 }
15860
15861 hHal = pHddCtx->hHal;
15862
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015863 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
15864 dbm, ccmCfgSetCallback,
15865 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015866 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015867 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015868 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
15869 return -EIO;
15870 }
15871
15872 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
15873 dbm);
15874
15875 switch(type)
15876 {
15877 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
15878 /* Fall through */
15879 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
15880 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
15881 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015882 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
15883 __func__);
15884 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070015885 }
15886 break;
15887 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015888 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070015889 __func__);
15890 return -EOPNOTSUPP;
15891 break;
15892 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015893 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
15894 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070015895 return -EIO;
15896 }
15897
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015898 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015899 return 0;
15900}
15901
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015902static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
15903#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15904 struct wireless_dev *wdev,
15905#endif
15906#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
15907 enum tx_power_setting type,
15908#else
15909 enum nl80211_tx_power_setting type,
15910#endif
15911 int dbm)
15912{
15913 int ret;
15914 vos_ssr_protect(__func__);
15915 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
15916#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15917 wdev,
15918#endif
15919#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
15920 type,
15921#else
15922 type,
15923#endif
15924 dbm);
15925 vos_ssr_unprotect(__func__);
15926
15927 return ret;
15928}
15929
Jeff Johnson295189b2012-06-20 16:38:30 -070015930/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015931 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070015932 * This function is used to read the txpower
15933 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015934static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070015935#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15936 struct wireless_dev *wdev,
15937#endif
15938 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070015939{
15940
15941 hdd_adapter_t *pAdapter;
15942 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015943 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015944
Jeff Johnsone7245742012-09-05 17:12:55 -070015945 ENTER();
15946
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015947 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015948 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015949 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015950 *dbm = 0;
15951 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015952 }
15953
Jeff Johnson295189b2012-06-20 16:38:30 -070015954 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
15955 if (NULL == pAdapter)
15956 {
15957 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
15958 return -ENOENT;
15959 }
15960
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053015961 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15962 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
15963 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070015964 wlan_hdd_get_classAstats(pAdapter);
15965 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
15966
Jeff Johnsone7245742012-09-05 17:12:55 -070015967 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015968 return 0;
15969}
15970
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015971static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
15972#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15973 struct wireless_dev *wdev,
15974#endif
15975 int *dbm)
15976{
15977 int ret;
15978
15979 vos_ssr_protect(__func__);
15980 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
15981#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15982 wdev,
15983#endif
15984 dbm);
15985 vos_ssr_unprotect(__func__);
15986
15987 return ret;
15988}
15989
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015990static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015991#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15992 const u8* mac,
15993#else
15994 u8* mac,
15995#endif
15996 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070015997{
15998 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
15999 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16000 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053016001 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070016002
16003 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
16004 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070016005
16006 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
16007 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
16008 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
16009 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
16010 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
16011 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
16012 tANI_U16 maxRate = 0;
16013 tANI_U16 myRate;
16014 tANI_U16 currentRate = 0;
16015 tANI_U8 maxSpeedMCS = 0;
16016 tANI_U8 maxMCSIdx = 0;
16017 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053016018 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070016019 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016020 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016021
Leo Chang6f8870f2013-03-26 18:11:36 -070016022#ifdef WLAN_FEATURE_11AC
16023 tANI_U32 vht_mcs_map;
16024 eDataRate11ACMaxMcs vhtMaxMcs;
16025#endif /* WLAN_FEATURE_11AC */
16026
Jeff Johnsone7245742012-09-05 17:12:55 -070016027 ENTER();
16028
Jeff Johnson295189b2012-06-20 16:38:30 -070016029 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
16030 (0 == ssidlen))
16031 {
16032 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
16033 " Invalid ssidlen, %d", __func__, ssidlen);
16034 /*To keep GUI happy*/
16035 return 0;
16036 }
16037
Mukul Sharma811205f2014-07-09 21:07:30 +053016038 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
16039 {
16040 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16041 "%s: Roaming in progress, so unable to proceed this request", __func__);
Sachin Ahuja81ab1812016-08-19 21:35:58 +053016042 /* return a cached value */
16043 sinfo->signal = pAdapter->rssi;
Mukul Sharma811205f2014-07-09 21:07:30 +053016044 return 0;
16045 }
16046
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016047 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016048 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016049 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016050 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016051 }
16052
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053016053 wlan_hdd_get_station_stats(pAdapter);
16054 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070016055
Kiet Lam3b17fc82013-09-27 05:24:08 +053016056 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
16057 sinfo->filled |= STATION_INFO_SIGNAL;
16058
c_hpothu09f19542014-05-30 21:53:31 +053016059 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053016060 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
16061 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053016062 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053016063 {
16064 rate_flags = pAdapter->maxRateFlags;
16065 }
c_hpothu44ff4e02014-05-08 00:13:57 +053016066
Jeff Johnson295189b2012-06-20 16:38:30 -070016067 //convert to the UI units of 100kbps
16068 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
16069
16070#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070016071 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 -070016072 sinfo->signal,
16073 pCfg->reportMaxLinkSpeed,
16074 myRate,
16075 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070016076 (int) pCfg->linkSpeedRssiMid,
16077 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070016078 (int) rate_flags,
16079 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070016080#endif //LINKSPEED_DEBUG_ENABLED
16081
16082 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
16083 {
16084 // we do not want to necessarily report the current speed
16085 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
16086 {
16087 // report the max possible speed
16088 rssidx = 0;
16089 }
16090 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
16091 {
16092 // report the max possible speed with RSSI scaling
16093 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
16094 {
16095 // report the max possible speed
16096 rssidx = 0;
16097 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070016098 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070016099 {
16100 // report middle speed
16101 rssidx = 1;
16102 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070016103 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
16104 {
16105 // report middle speed
16106 rssidx = 2;
16107 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016108 else
16109 {
16110 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070016111 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070016112 }
16113 }
16114 else
16115 {
16116 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
16117 hddLog(VOS_TRACE_LEVEL_ERROR,
16118 "%s: Invalid value for reportMaxLinkSpeed: %u",
16119 __func__, pCfg->reportMaxLinkSpeed);
16120 rssidx = 0;
16121 }
16122
16123 maxRate = 0;
16124
16125 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053016126 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
16127 OperationalRates, &ORLeng))
16128 {
16129 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
16130 /*To keep GUI happy*/
16131 return 0;
16132 }
16133
Jeff Johnson295189b2012-06-20 16:38:30 -070016134 for (i = 0; i < ORLeng; i++)
16135 {
Jeff Johnsone7245742012-09-05 17:12:55 -070016136 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070016137 {
16138 /* Validate Rate Set */
16139 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
16140 {
16141 currentRate = supported_data_rate[j].supported_rate[rssidx];
16142 break;
16143 }
16144 }
16145 /* Update MAX rate */
16146 maxRate = (currentRate > maxRate)?currentRate:maxRate;
16147 }
16148
16149 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053016150 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
16151 ExtendedRates, &ERLeng))
16152 {
16153 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
16154 /*To keep GUI happy*/
16155 return 0;
16156 }
16157
Jeff Johnson295189b2012-06-20 16:38:30 -070016158 for (i = 0; i < ERLeng; i++)
16159 {
Jeff Johnsone7245742012-09-05 17:12:55 -070016160 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070016161 {
16162 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
16163 {
16164 currentRate = supported_data_rate[j].supported_rate[rssidx];
16165 break;
16166 }
16167 }
16168 /* Update MAX rate */
16169 maxRate = (currentRate > maxRate)?currentRate:maxRate;
16170 }
c_hpothu79aab322014-07-14 21:11:01 +053016171
Kiet Lamb69f8dc2013-11-15 15:34:27 +053016172 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053016173 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053016174 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053016175 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070016176 {
c_hpothu79aab322014-07-14 21:11:01 +053016177 if (rate_flags & eHAL_TX_RATE_VHT80)
16178 mode = 2;
16179 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
16180 mode = 1;
16181 else
16182 mode = 0;
16183
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053016184 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
16185 MCSRates, &MCSLeng))
16186 {
16187 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
16188 /*To keep GUI happy*/
16189 return 0;
16190 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016191 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070016192#ifdef WLAN_FEATURE_11AC
16193 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016194 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070016195 {
Leo Chang6f8870f2013-03-26 18:11:36 -070016196 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016197 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070016198 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070016199 {
Leo Chang6f8870f2013-03-26 18:11:36 -070016200 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070016201 }
Leo Chang6f8870f2013-03-26 18:11:36 -070016202 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070016203 {
Leo Chang6f8870f2013-03-26 18:11:36 -070016204 maxMCSIdx = 7;
16205 }
16206 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
16207 {
16208 maxMCSIdx = 8;
16209 }
16210 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
16211 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016212 //VHT20 is supporting 0~8
16213 if (rate_flags & eHAL_TX_RATE_VHT20)
16214 maxMCSIdx = 8;
16215 else
16216 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070016217 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016218
c_hpothu79aab322014-07-14 21:11:01 +053016219 if (0 != rssidx)/*check for scaled */
16220 {
16221 //get middle rate MCS index if rssi=1/2
16222 for (i=0; i <= maxMCSIdx; i++)
16223 {
16224 if (sinfo->signal <= rssiMcsTbl[mode][i])
16225 {
16226 maxMCSIdx = i;
16227 break;
16228 }
16229 }
16230 }
16231
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016232 if (rate_flags & eHAL_TX_RATE_VHT80)
16233 {
16234 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
16235 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
16236 }
16237 else if (rate_flags & eHAL_TX_RATE_VHT40)
16238 {
16239 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
16240 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
16241 }
16242 else if (rate_flags & eHAL_TX_RATE_VHT20)
16243 {
16244 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
16245 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
16246 }
16247
Leo Chang6f8870f2013-03-26 18:11:36 -070016248 maxSpeedMCS = 1;
16249 if (currentRate > maxRate)
16250 {
16251 maxRate = currentRate;
16252 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016253
Leo Chang6f8870f2013-03-26 18:11:36 -070016254 }
16255 else
16256#endif /* WLAN_FEATURE_11AC */
16257 {
16258 if (rate_flags & eHAL_TX_RATE_HT40)
16259 {
16260 rateFlag |= 1;
16261 }
16262 if (rate_flags & eHAL_TX_RATE_SGI)
16263 {
16264 rateFlag |= 2;
16265 }
16266
Girish Gowli01abcee2014-07-31 20:18:55 +053016267 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053016268 if (rssidx == 1 || rssidx == 2)
16269 {
16270 //get middle rate MCS index if rssi=1/2
16271 for (i=0; i <= 7; i++)
16272 {
16273 if (sinfo->signal <= rssiMcsTbl[mode][i])
16274 {
16275 temp = i+1;
16276 break;
16277 }
16278 }
16279 }
c_hpothu79aab322014-07-14 21:11:01 +053016280
16281 for (i = 0; i < MCSLeng; i++)
16282 {
Leo Chang6f8870f2013-03-26 18:11:36 -070016283 for (j = 0; j < temp; j++)
16284 {
16285 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
16286 {
16287 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053016288 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070016289 break;
16290 }
16291 }
16292 if ((j < temp) && (currentRate > maxRate))
16293 {
16294 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070016295 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016296 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053016297 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070016298 }
16299 }
16300
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016301 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
16302 {
16303 maxRate = myRate;
16304 maxSpeedMCS = 1;
16305 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
16306 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016307 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053016308 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070016309 {
16310 maxRate = myRate;
16311 if (rate_flags & eHAL_TX_RATE_LEGACY)
16312 {
16313 maxSpeedMCS = 0;
16314 }
16315 else
16316 {
16317 maxSpeedMCS = 1;
16318 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
16319 }
16320 }
16321
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016322 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070016323 {
16324 sinfo->txrate.legacy = maxRate;
16325#ifdef LINKSPEED_DEBUG_ENABLED
16326 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
16327#endif //LINKSPEED_DEBUG_ENABLED
16328 }
16329 else
16330 {
16331 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070016332#ifdef WLAN_FEATURE_11AC
16333 sinfo->txrate.nss = 1;
16334 if (rate_flags & eHAL_TX_RATE_VHT80)
16335 {
16336 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016337 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070016338 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016339 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070016340 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016341 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
16342 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
16343 }
16344 else if (rate_flags & eHAL_TX_RATE_VHT20)
16345 {
16346 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
16347 }
16348#endif /* WLAN_FEATURE_11AC */
16349 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
16350 {
16351 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
16352 if (rate_flags & eHAL_TX_RATE_HT40)
16353 {
16354 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
16355 }
Leo Chang6f8870f2013-03-26 18:11:36 -070016356 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016357 if (rate_flags & eHAL_TX_RATE_SGI)
16358 {
16359 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
16360 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016361
Jeff Johnson295189b2012-06-20 16:38:30 -070016362#ifdef LINKSPEED_DEBUG_ENABLED
16363 pr_info("Reporting MCS rate %d flags %x\n",
16364 sinfo->txrate.mcs,
16365 sinfo->txrate.flags );
16366#endif //LINKSPEED_DEBUG_ENABLED
16367 }
16368 }
16369 else
16370 {
16371 // report current rate instead of max rate
16372
16373 if (rate_flags & eHAL_TX_RATE_LEGACY)
16374 {
16375 //provide to the UI in units of 100kbps
16376 sinfo->txrate.legacy = myRate;
16377#ifdef LINKSPEED_DEBUG_ENABLED
16378 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
16379#endif //LINKSPEED_DEBUG_ENABLED
16380 }
16381 else
16382 {
16383 //must be MCS
16384 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070016385#ifdef WLAN_FEATURE_11AC
16386 sinfo->txrate.nss = 1;
16387 if (rate_flags & eHAL_TX_RATE_VHT80)
16388 {
16389 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
16390 }
16391 else
16392#endif /* WLAN_FEATURE_11AC */
16393 {
16394 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
16395 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016396 if (rate_flags & eHAL_TX_RATE_SGI)
16397 {
16398 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
16399 }
16400 if (rate_flags & eHAL_TX_RATE_HT40)
16401 {
16402 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
16403 }
Leo Chang6f8870f2013-03-26 18:11:36 -070016404#ifdef WLAN_FEATURE_11AC
16405 else if (rate_flags & eHAL_TX_RATE_VHT80)
16406 {
16407 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
16408 }
16409#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070016410#ifdef LINKSPEED_DEBUG_ENABLED
16411 pr_info("Reporting actual MCS rate %d flags %x\n",
16412 sinfo->txrate.mcs,
16413 sinfo->txrate.flags );
16414#endif //LINKSPEED_DEBUG_ENABLED
16415 }
16416 }
16417 sinfo->filled |= STATION_INFO_TX_BITRATE;
16418
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070016419 sinfo->tx_packets =
16420 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
16421 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
16422 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
16423 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
16424
16425 sinfo->tx_retries =
16426 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
16427 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
16428 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
16429 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
16430
16431 sinfo->tx_failed =
16432 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
16433 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
16434 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
16435 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
16436
16437 sinfo->filled |=
16438 STATION_INFO_TX_PACKETS |
16439 STATION_INFO_TX_RETRIES |
16440 STATION_INFO_TX_FAILED;
16441
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053016442 sinfo->rx_packets = pAdapter->hdd_stats.summary_stat.rx_frm_cnt;
16443 sinfo->filled |= STATION_INFO_RX_PACKETS;
16444
16445 if (rate_flags & eHAL_TX_RATE_LEGACY)
16446 hddLog(LOG1, FL("Reporting RSSI:%d legacy rate %d pkt cnt tx %d rx %d"),
16447 sinfo->signal, sinfo->txrate.legacy, sinfo->tx_packets,
16448 sinfo->rx_packets);
16449 else
16450 hddLog(LOG1,
16451 FL("Reporting RSSI:%d MCS rate %d flags 0x%x pkt cnt tx %d rx %d"),
16452 sinfo->signal, sinfo->txrate.mcs, sinfo->txrate.flags,
16453 sinfo->tx_packets, sinfo->rx_packets);
16454
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016455 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16456 TRACE_CODE_HDD_CFG80211_GET_STA,
16457 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070016458 EXIT();
16459 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070016460}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016461#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16462static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
16463 const u8* mac, struct station_info *sinfo)
16464#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016465static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
16466 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016467#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016468{
16469 int ret;
16470
16471 vos_ssr_protect(__func__);
16472 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
16473 vos_ssr_unprotect(__func__);
16474
16475 return ret;
16476}
16477
16478static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070016479 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070016480{
16481 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016482 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070016483 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016484 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016485
Jeff Johnsone7245742012-09-05 17:12:55 -070016486 ENTER();
16487
Jeff Johnson295189b2012-06-20 16:38:30 -070016488 if (NULL == pAdapter)
16489 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016490 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016491 return -ENODEV;
16492 }
16493
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016494 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16495 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
16496 pAdapter->sessionId, timeout));
16497
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016498 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016499 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016500 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016501 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016502 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016503 }
16504
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016505 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
16506 (TRUE == pHddCtx->hdd_wlan_suspended) &&
16507 (pHddCtx->cfg_ini->fhostArpOffload) &&
16508 (eConnectionState_Associated ==
16509 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
16510 {
Amar Singhald53568e2013-09-26 11:03:45 -070016511
16512 hddLog(VOS_TRACE_LEVEL_INFO,
16513 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053016514 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016515 if (!VOS_IS_STATUS_SUCCESS(vos_status))
16516 {
16517 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080016518 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016519 __func__, vos_status);
16520 }
16521 }
16522
Jeff Johnson295189b2012-06-20 16:38:30 -070016523 /**The get power cmd from the supplicant gets updated by the nl only
16524 *on successful execution of the function call
16525 *we are oppositely mapped w.r.t mode in the driver
16526 **/
16527 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
16528
16529 if (VOS_STATUS_E_FAILURE == vos_status)
16530 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016531 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16532 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016533 return -EINVAL;
16534 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016535 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016536 return 0;
16537}
16538
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016539static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
16540 struct net_device *dev, bool mode, int timeout)
16541{
16542 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070016543
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016544 vos_ssr_protect(__func__);
16545 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
16546 vos_ssr_unprotect(__func__);
16547
16548 return ret;
16549}
Sushant Kaushik084f6592015-09-10 13:11:56 +053016550
Jeff Johnson295189b2012-06-20 16:38:30 -070016551#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016552static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
16553 struct net_device *netdev,
16554 u8 key_index)
16555{
16556 ENTER();
16557 return 0;
16558}
16559
Jeff Johnson295189b2012-06-20 16:38:30 -070016560static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016561 struct net_device *netdev,
16562 u8 key_index)
16563{
16564 int ret;
16565 vos_ssr_protect(__func__);
16566 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
16567 vos_ssr_unprotect(__func__);
16568 return ret;
16569}
16570#endif //LINUX_VERSION_CODE
16571
16572#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
16573static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
16574 struct net_device *dev,
16575 struct ieee80211_txq_params *params)
16576{
16577 ENTER();
16578 return 0;
16579}
16580#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
16581static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
16582 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070016583{
Jeff Johnsone7245742012-09-05 17:12:55 -070016584 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070016585 return 0;
16586}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016587#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070016588
16589#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
16590static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016591 struct net_device *dev,
16592 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070016593{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016594 int ret;
16595
16596 vos_ssr_protect(__func__);
16597 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
16598 vos_ssr_unprotect(__func__);
16599 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070016600}
16601#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
16602static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
16603 struct ieee80211_txq_params *params)
16604{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016605 int ret;
16606
16607 vos_ssr_protect(__func__);
16608 ret = __wlan_hdd_set_txq_params(wiphy, params);
16609 vos_ssr_unprotect(__func__);
16610 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070016611}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016612#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016613
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016614static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016615 struct net_device *dev,
16616 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070016617{
16618 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016619 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016620 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016621 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016622 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016623 v_CONTEXT_t pVosContext = NULL;
16624 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016625
Jeff Johnsone7245742012-09-05 17:12:55 -070016626 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016627
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016628 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070016629 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016630 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016631 return -EINVAL;
16632 }
16633
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016634 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16635 TRACE_CODE_HDD_CFG80211_DEL_STA,
16636 pAdapter->sessionId, pAdapter->device_mode));
16637
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016638 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16639 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016640 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016641 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016642 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016643 }
16644
Jeff Johnson295189b2012-06-20 16:38:30 -070016645 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070016646 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070016647 )
16648 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016649 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
16650 pSapCtx = VOS_GET_SAP_CB(pVosContext);
16651 if(pSapCtx == NULL){
16652 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16653 FL("psapCtx is NULL"));
16654 return -ENOENT;
16655 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016656 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070016657 {
16658 v_U16_t i;
16659 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
16660 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016661 if ((pSapCtx->aStaInfo[i].isUsed) &&
16662 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070016663 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016664 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016665 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016666 ETHER_ADDR_LEN);
16667
Jeff Johnson295189b2012-06-20 16:38:30 -070016668 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016669 "%s: Delete STA with MAC::"
16670 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016671 __func__,
16672 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
16673 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070016674 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016675 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070016676 }
16677 }
16678 }
16679 else
16680 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016681
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016682 vos_status = hdd_softap_GetStaId(pAdapter,
16683 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016684 if (!VOS_IS_STATUS_SUCCESS(vos_status))
16685 {
16686 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016687 "%s: Skip this DEL STA as this is not used::"
16688 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016689 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016690 return -ENOENT;
16691 }
16692
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016693 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016694 {
16695 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016696 "%s: Skip this DEL STA as deauth is in progress::"
16697 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016698 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016699 return -ENOENT;
16700 }
16701
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016702 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016703
Jeff Johnson295189b2012-06-20 16:38:30 -070016704 hddLog(VOS_TRACE_LEVEL_INFO,
16705 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080016706 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016707 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016708 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016709
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016710 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016711 if (!VOS_IS_STATUS_SUCCESS(vos_status))
16712 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016713 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016714 hddLog(VOS_TRACE_LEVEL_INFO,
16715 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080016716 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016717 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016718 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016719 return -ENOENT;
16720 }
16721
Jeff Johnson295189b2012-06-20 16:38:30 -070016722 }
16723 }
16724
16725 EXIT();
16726
16727 return 0;
16728}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016729
16730#ifdef CFG80211_DEL_STA_V2
16731static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
16732 struct net_device *dev,
16733 struct station_del_parameters *param)
16734#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016735#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16736static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
16737 struct net_device *dev, const u8 *mac)
16738#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016739static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
16740 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016741#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016742#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016743{
16744 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016745 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070016746
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016747 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016748
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016749#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016750 if (NULL == param) {
16751 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016752 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016753 return -EINVAL;
16754 }
16755
16756 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
16757 param->subtype, &delStaParams);
16758
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016759#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053016760 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016761 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016762#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016763 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
16764
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016765 vos_ssr_unprotect(__func__);
16766
16767 return ret;
16768}
16769
16770static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016771 struct net_device *dev,
16772#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16773 const u8 *mac,
16774#else
16775 u8 *mac,
16776#endif
16777 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016778{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016779 hdd_adapter_t *pAdapter;
16780 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016781 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016782#ifdef FEATURE_WLAN_TDLS
16783 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016784
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016785 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016786
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016787 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16788 if (NULL == pAdapter)
16789 {
16790 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16791 "%s: Adapter is NULL",__func__);
16792 return -EINVAL;
16793 }
16794 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16795 status = wlan_hdd_validate_context(pHddCtx);
16796 if (0 != status)
16797 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016798 return status;
16799 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016800
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016801 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16802 TRACE_CODE_HDD_CFG80211_ADD_STA,
16803 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016804 mask = params->sta_flags_mask;
16805
16806 set = params->sta_flags_set;
16807
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053016808 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016809 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
16810 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016811
16812 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
16813 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080016814 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016815 }
16816 }
16817#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016818 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016819 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016820}
16821
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016822#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16823static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
16824 struct net_device *dev, const u8 *mac,
16825 struct station_parameters *params)
16826#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016827static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
16828 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016829#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016830{
16831 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016832
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016833 vos_ssr_protect(__func__);
16834 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
16835 vos_ssr_unprotect(__func__);
16836
16837 return ret;
16838}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016839#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070016840
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016841static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070016842 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016843{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016844 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16845 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016846 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016847 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016848 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016849 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070016850
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016851 ENTER();
16852
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016853 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016854 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016855 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016856 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016857 return -EINVAL;
16858 }
16859
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016860 if (!pmksa) {
16861 hddLog(LOGE, FL("pmksa is NULL"));
16862 return -EINVAL;
16863 }
16864
16865 if (!pmksa->bssid || !pmksa->pmkid) {
16866 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
16867 pmksa->bssid, pmksa->pmkid);
16868 return -EINVAL;
16869 }
16870
16871 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
16872 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
16873
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016874 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16875 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016876 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016877 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016878 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016879 }
16880
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016881 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016882 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16883
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016884 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
16885 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016886
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016887 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016888 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016889 &pmk_id, 1, FALSE);
16890
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016891 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16892 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
16893 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016894
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016895 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016896 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016897}
16898
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016899static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
16900 struct cfg80211_pmksa *pmksa)
16901{
16902 int ret;
16903
16904 vos_ssr_protect(__func__);
16905 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
16906 vos_ssr_unprotect(__func__);
16907
16908 return ret;
16909}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016910
Wilson Yang6507c4e2013-10-01 20:11:19 -070016911
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016912static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070016913 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016914{
Wilson Yang6507c4e2013-10-01 20:11:19 -070016915 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16916 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016917 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080016918 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016919
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016920 ENTER();
16921
Wilson Yang6507c4e2013-10-01 20:11:19 -070016922 /* Validate pAdapter */
16923 if (NULL == pAdapter)
16924 {
16925 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
16926 return -EINVAL;
16927 }
16928
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016929 if (!pmksa) {
16930 hddLog(LOGE, FL("pmksa is NULL"));
16931 return -EINVAL;
16932 }
16933
16934 if (!pmksa->bssid) {
16935 hddLog(LOGE, FL("pmksa->bssid is NULL"));
16936 return -EINVAL;
16937 }
16938
Kiet Lam98c46a12014-10-31 15:34:57 -070016939 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
16940 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
16941
Wilson Yang6507c4e2013-10-01 20:11:19 -070016942 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16943 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070016944 if (0 != status)
16945 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070016946 return status;
16947 }
16948
16949 /*Retrieve halHandle*/
16950 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16951
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016952 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16953 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
16954 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016955 /* Delete the PMKID CSR cache */
16956 if (eHAL_STATUS_SUCCESS !=
16957 sme_RoamDelPMKIDfromCache(halHandle,
16958 pAdapter->sessionId, pmksa->bssid, FALSE)) {
16959 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
16960 MAC_ADDR_ARRAY(pmksa->bssid));
16961 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016962 }
16963
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016964 EXIT();
16965 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016966}
16967
Wilson Yang6507c4e2013-10-01 20:11:19 -070016968
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016969static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
16970 struct cfg80211_pmksa *pmksa)
16971{
16972 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016973
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016974 vos_ssr_protect(__func__);
16975 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
16976 vos_ssr_unprotect(__func__);
16977
16978 return ret;
16979
16980}
16981
16982static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016983{
Wilson Yang6507c4e2013-10-01 20:11:19 -070016984 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16985 tHalHandle halHandle;
16986 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080016987 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016988
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016989 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070016990
16991 /* Validate pAdapter */
16992 if (NULL == pAdapter)
16993 {
16994 hddLog(VOS_TRACE_LEVEL_ERROR,
16995 "%s: Invalid Adapter" ,__func__);
16996 return -EINVAL;
16997 }
16998
16999 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17000 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070017001 if (0 != status)
17002 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070017003 return status;
17004 }
17005
17006 /*Retrieve halHandle*/
17007 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
17008
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017009 /* Flush the PMKID cache in CSR */
17010 if (eHAL_STATUS_SUCCESS !=
17011 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
17012 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
17013 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017014 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017015 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080017016 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017017}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017018
17019static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
17020{
17021 int ret;
17022
17023 vos_ssr_protect(__func__);
17024 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
17025 vos_ssr_unprotect(__func__);
17026
17027 return ret;
17028}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017029#endif
17030
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017031#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017032static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
17033 struct net_device *dev,
17034 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017035{
17036 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17037 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017038 hdd_context_t *pHddCtx;
17039 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017040
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017041 ENTER();
17042
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017043 if (NULL == pAdapter)
17044 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017045 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017046 return -ENODEV;
17047 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017048 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17049 ret = wlan_hdd_validate_context(pHddCtx);
17050 if (0 != ret)
17051 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017052 return ret;
17053 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017054 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017055 if (NULL == pHddStaCtx)
17056 {
17057 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
17058 return -EINVAL;
17059 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017060
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017061 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17062 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
17063 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017064 // Added for debug on reception of Re-assoc Req.
17065 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
17066 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017067 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017068 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080017069 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017070 }
17071
17072#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080017073 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017074 ftie->ie_len);
17075#endif
17076
17077 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053017078 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
17079 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017080 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017081
17082 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017083 return 0;
17084}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017085
17086static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
17087 struct net_device *dev,
17088 struct cfg80211_update_ft_ies_params *ftie)
17089{
17090 int ret;
17091
17092 vos_ssr_protect(__func__);
17093 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
17094 vos_ssr_unprotect(__func__);
17095
17096 return ret;
17097}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017098#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017099
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017100#ifdef FEATURE_WLAN_SCAN_PNO
17101
17102void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
17103 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
17104{
17105 int ret;
17106 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
17107 hdd_context_t *pHddCtx;
17108
Nirav Shah80830bf2013-12-31 16:35:12 +053017109 ENTER();
17110
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017111 if (NULL == pAdapter)
17112 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053017113 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017114 "%s: HDD adapter is Null", __func__);
17115 return ;
17116 }
17117
17118 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17119 if (NULL == pHddCtx)
17120 {
17121 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17122 "%s: HDD context is Null!!!", __func__);
17123 return ;
17124 }
17125
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017126 spin_lock(&pHddCtx->schedScan_lock);
17127 if (TRUE == pHddCtx->isWiphySuspended)
17128 {
17129 pHddCtx->isSchedScanUpdatePending = TRUE;
17130 spin_unlock(&pHddCtx->schedScan_lock);
17131 hddLog(VOS_TRACE_LEVEL_INFO,
17132 "%s: Update cfg80211 scan database after it resume", __func__);
17133 return ;
17134 }
17135 spin_unlock(&pHddCtx->schedScan_lock);
17136
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017137 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
17138
17139 if (0 > ret)
17140 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagarfb49cdd2015-10-16 18:41:59 +053017141 else
17142 {
17143 /* Acquire wakelock to handle the case where APP's tries to suspend
17144 * immediatly after the driver gets connect request(i.e after pno)
17145 * from supplicant, this result in app's is suspending and not able
17146 * to process the connect request to AP */
17147 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
17148 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017149 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017150 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17151 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017152}
17153
17154/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017155 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053017156 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017157 */
17158static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
17159{
17160 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
17161 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017162 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017163 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17164 int status = 0;
17165 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
17166
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053017167 /* The current firmware design does not allow PNO during any
17168 * active sessions. Hence, determine the active sessions
17169 * and return a failure.
17170 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017171 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
17172 {
17173 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017174 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017175
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017176 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
17177 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
17178 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
17179 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
17180 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053017181 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017182 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017183 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017184 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017185 }
17186 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
17187 pAdapterNode = pNext;
17188 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017189 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017190}
17191
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017192void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
17193{
17194 hdd_adapter_t *pAdapter = callbackContext;
17195 hdd_context_t *pHddCtx;
17196
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017197 ENTER();
17198
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017199 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
17200 {
17201 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17202 FL("Invalid adapter or adapter has invalid magic"));
17203 return;
17204 }
17205
17206 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17207 if (0 != wlan_hdd_validate_context(pHddCtx))
17208 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017209 return;
17210 }
17211
c_hpothub53c45d2014-08-18 16:53:14 +053017212 if (VOS_STATUS_SUCCESS != status)
17213 {
17214 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017215 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053017216 pHddCtx->isPnoEnable = FALSE;
17217 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017218
17219 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
17220 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017221 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017222}
17223
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017224#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) || \
17225 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
17226/**
17227 * hdd_config_sched_scan_plan() - configures the sched scan plans
17228 * from the framework.
17229 * @pno_req: pointer to PNO scan request
17230 * @request: pointer to scan request from framework
17231 *
17232 * Return: None
17233 */
17234static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
17235 struct cfg80211_sched_scan_request *request,
17236 hdd_context_t *hdd_ctx)
17237{
17238 v_U32_t i = 0;
17239
17240 pno_req.scanTimers.ucScanTimersCount = n_scan_plans;
17241 for (i = 0; i < request->n_scan_plans; i++)
17242 {
17243 pno_req.scanTimers.aTimerValues[i].uTimerRepeat =
17244 request->scan_plans[i]->iterations;
17245 pno_req.scanTimers.aTimerValues[i].uTimerValue =
17246 request->scan_plans[i]->interval;
17247 }
17248}
17249#else
17250static void hdd_config_sched_scan_plan(tSirPNOScanReq pno_req,
17251 struct cfg80211_sched_scan_request *request,
17252 hdd_context_t *hdd_ctx)
17253{
17254 v_U32_t i, temp_int;
17255 /* Driver gets only one time interval which is hardcoded in
17256 * supplicant for 10000ms. Taking power consumption into account 6
17257 * timers will be used, Timervalue is increased exponentially
17258 * i.e 10,20,40, 80,160,320 secs. And number of scan cycle for each
17259 * timer is configurable through INI param gPNOScanTimerRepeatValue.
17260 * If it is set to 0 only one timer will be used and PNO scan cycle
17261 * will be repeated after each interval specified by supplicant
17262 * till PNO is disabled.
17263 */
17264 if (0 == hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue)
17265 pno_req.scanTimers.ucScanTimersCount =
17266 HDD_PNO_SCAN_TIMERS_SET_ONE;
17267 else
17268 pno_req.scanTimers.ucScanTimersCount =
17269 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
17270
17271 temp_int = (request->interval)/1000;
17272 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17273 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
17274 temp_int, hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue);
17275 for ( i = 0; i < pno_req.scanTimers.ucScanTimersCount; i++)
17276 {
17277 pno_req.scanTimers.aTimerValues[i].uTimerRepeat =
17278 hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue;
17279 pno_req.scanTimers.aTimerValues[i].uTimerValue = temp_int;
17280 temp_int *= 2;
17281 }
17282 //Repeat last timer until pno disabled.
17283 pno_req.scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
17284}
17285#endif
17286
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017287/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017288 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
17289 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017290 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017291static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017292 struct net_device *dev, struct cfg80211_sched_scan_request *request)
17293{
17294 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017295 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017296 hdd_context_t *pHddCtx;
17297 tHalHandle hHal;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017298 v_U32_t i, indx, num_ch, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053017299 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
17300 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017301 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
17302 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017303 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053017304 hdd_config_t *pConfig = NULL;
17305 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017306
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017307 ENTER();
17308
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017309 if (NULL == pAdapter)
17310 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017311 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017312 "%s: HDD adapter is Null", __func__);
17313 return -ENODEV;
17314 }
17315
17316 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017317 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017318
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017319 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017320 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017321 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017322 }
17323
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053017324 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017325 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
17326 if (NULL == hHal)
17327 {
17328 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17329 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017330 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017331 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017332 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17333 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
17334 pAdapter->sessionId, pAdapter->device_mode));
Sushant Kaushik2fe89932014-09-03 10:58:09 +053017335 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053017336 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053017337 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053017338 {
17339 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17340 "%s: aborting the existing scan is unsuccessfull", __func__);
17341 return -EBUSY;
17342 }
17343
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017344 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017345 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053017346 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017347 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017348 return -EBUSY;
17349 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017350
c_hpothu37f21312014-04-09 21:49:54 +053017351 if (TRUE == pHddCtx->isPnoEnable)
17352 {
17353 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
17354 FL("already PNO is enabled"));
17355 return -EBUSY;
17356 }
c_hpothu225aa7c2014-10-22 17:45:13 +053017357
17358 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
17359 {
17360 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17361 "%s: abort ROC failed ", __func__);
17362 return -EBUSY;
17363 }
17364
c_hpothu37f21312014-04-09 21:49:54 +053017365 pHddCtx->isPnoEnable = TRUE;
17366
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017367 pnoRequest.enable = 1; /*Enable PNO */
17368 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017369
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017370 if (( !pnoRequest.ucNetworksCount ) ||
17371 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017372 {
17373 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053017374 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017375 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053017376 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017377 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017378 goto error;
17379 }
17380
17381 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
17382 {
17383 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053017384 "%s: Incorrect number of channels %d",
17385 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017386 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017387 goto error;
17388 }
17389
17390 /* Framework provides one set of channels(all)
17391 * common for all saved profile */
17392 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
17393 channels_allowed, &num_channels_allowed))
17394 {
17395 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17396 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017397 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017398 goto error;
17399 }
17400 /* Checking each channel against allowed channel list */
17401 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053017402 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017403 {
Nirav Shah80830bf2013-12-31 16:35:12 +053017404 char chList [(request->n_channels*5)+1];
17405 int len;
17406 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017407 {
Nirav Shah80830bf2013-12-31 16:35:12 +053017408 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017409 {
Nirav Shah80830bf2013-12-31 16:35:12 +053017410 if (request->channels[i]->hw_value == channels_allowed[indx])
17411 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053017412 if ((!pConfig->enableDFSPnoChnlScan) &&
17413 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
17414 {
17415 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17416 "%s : Dropping DFS channel : %d",
17417 __func__,channels_allowed[indx]);
17418 num_ignore_dfs_ch++;
17419 break;
17420 }
17421
Nirav Shah80830bf2013-12-31 16:35:12 +053017422 valid_ch[num_ch++] = request->channels[i]->hw_value;
17423 len += snprintf(chList+len, 5, "%d ",
17424 request->channels[i]->hw_value);
17425 break ;
17426 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017427 }
17428 }
Nirav Shah80830bf2013-12-31 16:35:12 +053017429 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017430
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053017431 /*If all channels are DFS and dropped, then ignore the PNO request*/
17432 if (num_ignore_dfs_ch == request->n_channels)
17433 {
17434 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17435 "%s : All requested channels are DFS channels", __func__);
17436 ret = -EINVAL;
17437 goto error;
17438 }
17439 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017440
17441 pnoRequest.aNetworks =
17442 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
17443 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017444 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017445 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
17446 FL("failed to allocate memory aNetworks %u"),
17447 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
17448 goto error;
17449 }
17450 vos_mem_zero(pnoRequest.aNetworks,
17451 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
17452
17453 /* Filling per profile params */
17454 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
17455 {
17456 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017457 request->match_sets[i].ssid.ssid_len;
17458
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017459 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
17460 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017461 {
17462 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053017463 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017464 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017465 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017466 goto error;
17467 }
17468
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017469 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017470 request->match_sets[i].ssid.ssid,
17471 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053017472 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17473 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017474 i, pnoRequest.aNetworks[i].ssId.ssId);
17475 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
17476 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
17477 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017478
17479 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017480 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
17481 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017482
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017483 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017484 }
17485
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017486 for (i = 0; i < request->n_ssids; i++)
17487 {
17488 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017489 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017490 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017491 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017492 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017493 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017494 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017495 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017496 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017497 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017498 break;
17499 }
17500 j++;
17501 }
17502 }
17503 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17504 "Number of hidden networks being Configured = %d",
17505 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053017506 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080017507 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017508
17509 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
17510 if (pnoRequest.p24GProbeTemplate == NULL)
17511 {
17512 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
17513 FL("failed to allocate memory p24GProbeTemplate %u"),
17514 SIR_PNO_MAX_PB_REQ_SIZE);
17515 goto error;
17516 }
17517
17518 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
17519 if (pnoRequest.p5GProbeTemplate == NULL)
17520 {
17521 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
17522 FL("failed to allocate memory p5GProbeTemplate %u"),
17523 SIR_PNO_MAX_PB_REQ_SIZE);
17524 goto error;
17525 }
17526
17527 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
17528 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
17529
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053017530 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
17531 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053017532 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017533 pnoRequest.us24GProbeTemplateLen = request->ie_len;
17534 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
17535 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053017536
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017537 pnoRequest.us5GProbeTemplateLen = request->ie_len;
17538 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
17539 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053017540 }
17541
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017542 hdd_config_sched_scan_plan(pnoRequest, request, pHddCtx);
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017543
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017544 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017545
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017546 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017547 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
17548 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017549 pAdapter->pno_req_status = 0;
17550
Nirav Shah80830bf2013-12-31 16:35:12 +053017551 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17552 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017553 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
17554 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053017555
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017556 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017557 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017558 hdd_cfg80211_sched_scan_done_callback, pAdapter);
17559 if (eHAL_STATUS_SUCCESS != status)
17560 {
17561 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053017562 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017563 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017564 goto error;
17565 }
17566
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017567 ret = wait_for_completion_timeout(
17568 &pAdapter->pno_comp_var,
17569 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
17570 if (0 >= ret)
17571 {
17572 // Did not receive the response for PNO enable in time.
17573 // Assuming the PNO enable was success.
17574 // Returning error from here, because we timeout, results
17575 // in side effect of Wifi (Wifi Setting) not to work.
17576 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17577 FL("Timed out waiting for PNO to be Enabled"));
17578 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017579 }
17580
17581 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053017582 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017583
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017584error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017585 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17586 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053017587 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017588 if (pnoRequest.aNetworks)
17589 vos_mem_free(pnoRequest.aNetworks);
17590 if (pnoRequest.p24GProbeTemplate)
17591 vos_mem_free(pnoRequest.p24GProbeTemplate);
17592 if (pnoRequest.p5GProbeTemplate)
17593 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017594
17595 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017596 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017597}
17598
17599/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017600 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
17601 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017602 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017603static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
17604 struct net_device *dev, struct cfg80211_sched_scan_request *request)
17605{
17606 int ret;
17607
17608 vos_ssr_protect(__func__);
17609 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
17610 vos_ssr_unprotect(__func__);
17611
17612 return ret;
17613}
17614
17615/*
17616 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
17617 * Function to disable PNO
17618 */
17619static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017620 struct net_device *dev)
17621{
17622 eHalStatus status = eHAL_STATUS_FAILURE;
17623 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17624 hdd_context_t *pHddCtx;
17625 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017626 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017627 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017628
17629 ENTER();
17630
17631 if (NULL == pAdapter)
17632 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017633 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017634 "%s: HDD adapter is Null", __func__);
17635 return -ENODEV;
17636 }
17637
17638 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017639
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017640 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017641 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017642 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017643 "%s: HDD context is Null", __func__);
17644 return -ENODEV;
17645 }
17646
17647 /* The return 0 is intentional when isLogpInProgress and
17648 * isLoadUnloadInProgress. We did observe a crash due to a return of
17649 * failure in sched_scan_stop , especially for a case where the unload
17650 * of the happens at the same time. The function __cfg80211_stop_sched_scan
17651 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
17652 * success. If it returns a failure , then its next invocation due to the
17653 * clean up of the second interface will have the dev pointer corresponding
17654 * to the first one leading to a crash.
17655 */
17656 if (pHddCtx->isLogpInProgress)
17657 {
17658 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17659 "%s: LOGP in Progress. Ignore!!!", __func__);
Mahesh A Saptasagar0c11d822015-10-08 19:54:08 +053017660 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017661 return ret;
17662 }
17663
Mihir Shete18156292014-03-11 15:38:30 +053017664 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017665 {
17666 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17667 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
17668 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017669 }
17670
17671 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
17672 if (NULL == hHal)
17673 {
17674 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17675 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017676 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017677 }
17678
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017679 pnoRequest.enable = 0; /* Disable PNO */
17680 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017681
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017682 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17683 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
17684 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053017685
17686 INIT_COMPLETION(pAdapter->pno_comp_var);
17687 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
17688 pnoRequest.callbackContext = pAdapter;
17689 pAdapter->pno_req_status = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017690 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017691 pAdapter->sessionId,
17692 NULL, pAdapter);
17693 if (eHAL_STATUS_SUCCESS != status)
17694 {
17695 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17696 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017697 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017698 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017699 }
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053017700 ret = wait_for_completion_timeout(
17701 &pAdapter->pno_comp_var,
17702 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
17703 if (0 >= ret)
17704 {
17705 // Did not receive the response for PNO disable in time.
17706 // Assuming the PNO disable was success.
17707 // Returning error from here, because we timeout, results
17708 // in side effect of Wifi (Wifi Setting) not to work.
Anurag Chouhan96b41cb2016-09-28 18:54:47 +053017709 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053017710 FL("Timed out waiting for PNO to be disabled"));
17711 ret = 0;
17712 }
17713
17714 ret = pAdapter->pno_req_status;
17715 pHddCtx->isPnoEnable = (ret == 0) ? FALSE : TRUE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017716
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017717error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017718 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017719 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017720
17721 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017722 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017723}
17724
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017725/*
17726 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
17727 * NL interface to disable PNO
17728 */
17729static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
17730 struct net_device *dev)
17731{
17732 int ret;
17733
17734 vos_ssr_protect(__func__);
17735 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
17736 vos_ssr_unprotect(__func__);
17737
17738 return ret;
17739}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017740#endif /*FEATURE_WLAN_SCAN_PNO*/
17741
17742
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017743#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017744#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017745static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17746 struct net_device *dev,
17747 u8 *peer, u8 action_code,
17748 u8 dialog_token,
17749 u16 status_code, u32 peer_capability,
17750 const u8 *buf, size_t len)
17751#else /* TDLS_MGMT_VERSION2 */
17752#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
17753static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17754 struct net_device *dev,
17755 const u8 *peer, u8 action_code,
17756 u8 dialog_token, u16 status_code,
17757 u32 peer_capability, bool initiator,
17758 const u8 *buf, size_t len)
17759#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
17760static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17761 struct net_device *dev,
17762 const u8 *peer, u8 action_code,
17763 u8 dialog_token, u16 status_code,
17764 u32 peer_capability, const u8 *buf,
17765 size_t len)
17766#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
17767static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17768 struct net_device *dev,
17769 u8 *peer, u8 action_code,
17770 u8 dialog_token,
17771 u16 status_code, u32 peer_capability,
17772 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017773#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017774static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17775 struct net_device *dev,
17776 u8 *peer, u8 action_code,
17777 u8 dialog_token,
17778 u16 status_code, const u8 *buf,
17779 size_t len)
17780#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017781#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017782{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017783 hdd_adapter_t *pAdapter;
17784 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017785 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070017786 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080017787 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070017788 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017789 int ret;
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053017790 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017791#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017792 u32 peer_capability = 0;
17793#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017794 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017795 hdd_station_ctx_t *pHddStaCtx = NULL;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017796
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017797 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17798 if (NULL == pAdapter)
17799 {
17800 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17801 "%s: Adapter is NULL",__func__);
17802 return -EINVAL;
17803 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017804 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17805 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
17806 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017807
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017808 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017809 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017810 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017811 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017812 "Invalid arguments");
17813 return -EINVAL;
17814 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017815
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017816 if (pHddCtx->isLogpInProgress)
17817 {
17818 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17819 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053017820 wlan_hdd_tdls_set_link_status(pAdapter,
17821 peer,
17822 eTDLS_LINK_IDLE,
17823 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017824 return -EBUSY;
17825 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017826
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017827 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
17828 {
17829 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17830 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
17831 return -EAGAIN;
17832 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017833
Hoonki Lee27511902013-03-14 18:19:06 -070017834 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017835 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017836 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070017837 "%s: TDLS mode is disabled OR not enabled in FW."
17838 MAC_ADDRESS_STR " action %d declined.",
17839 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017840 return -ENOTSUPP;
17841 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080017842
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017843 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17844
17845 if( NULL == pHddStaCtx )
17846 {
17847 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17848 "%s: HDD station context NULL ",__func__);
17849 return -EINVAL;
17850 }
17851
17852 /* STA should be connected and authenticated
17853 * before sending any TDLS frames
17854 */
17855 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
17856 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
17857 {
17858 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17859 "STA is not connected or unauthenticated. "
17860 "connState %u, uIsAuthenticated %u",
17861 pHddStaCtx->conn_info.connState,
17862 pHddStaCtx->conn_info.uIsAuthenticated);
17863 return -EAGAIN;
17864 }
17865
Hoonki Lee27511902013-03-14 18:19:06 -070017866 /* other than teardown frame, other mgmt frames are not sent if disabled */
17867 if (SIR_MAC_TDLS_TEARDOWN != action_code)
17868 {
17869 /* if tdls_mode is disabled to respond to peer's request */
17870 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
17871 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017872 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070017873 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070017874 " TDLS mode is disabled. action %d declined.",
17875 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070017876
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017877 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070017878 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053017879
17880 if (vos_max_concurrent_connections_reached())
17881 {
17882 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
17883 return -EINVAL;
17884 }
Hoonki Lee27511902013-03-14 18:19:06 -070017885 }
17886
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017887 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
17888 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053017889 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017890 {
17891 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017892 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070017893 " TDLS setup is ongoing. action %d declined.",
17894 __func__, MAC_ADDR_ARRAY(peer), action_code);
17895 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017896 }
17897 }
17898
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017899 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
17900 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080017901 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017902 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
17903 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080017904 {
17905 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
17906 we return error code at 'add_station()'. Hence we have this
17907 check again in addtion to add_station().
17908 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017909 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080017910 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017911 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17912 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017913 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
17914 __func__, MAC_ADDR_ARRAY(peer), action_code,
17915 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053017916 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080017917 }
17918 else
17919 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017920 /* maximum reached. tweak to send error code to peer and return
17921 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080017922 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017923 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17924 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017925 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
17926 __func__, MAC_ADDR_ARRAY(peer), status_code,
17927 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070017928 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017929 /* fall through to send setup resp with failure status
17930 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080017931 }
17932 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017933 else
17934 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017935 mutex_lock(&pHddCtx->tdls_lock);
17936 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070017937 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017938 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017939 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017940 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070017941 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
17942 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017943 return -EPERM;
17944 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017945 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017946 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080017947 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017948
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017949 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053017950 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017951 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
17952 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017953
Hoonki Leea34dd892013-02-05 22:56:02 -080017954 /*Except teardown responder will not be used so just make 0*/
17955 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017956 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080017957 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017958
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017959 mutex_lock(&pHddCtx->tdls_lock);
17960 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017961
17962 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
17963 responder = pTdlsPeer->is_responder;
17964 else
Hoonki Leea34dd892013-02-05 22:56:02 -080017965 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017966 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053017967 "%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 -070017968 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
17969 dialog_token, status_code, len);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017970 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017971 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080017972 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017973 mutex_unlock(&pHddCtx->tdls_lock);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017974 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017975
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053017976 /* Discard TDLS setup if peer is removed by user app */
17977 if ((pHddCtx->cfg_ini->fTDLSExternalControl) &&
17978 ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
17979 (SIR_MAC_TDLS_SETUP_CNF == action_code) ||
17980 (SIR_MAC_TDLS_DIS_REQ == action_code))) {
17981
17982 mutex_lock(&pHddCtx->tdls_lock);
17983 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
17984 if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) {
17985 mutex_unlock(&pHddCtx->tdls_lock);
17986 hddLog(LOGE, FL("TDLS External Control enabled, but peer "
17987 MAC_ADDRESS_STR " is not forced, so reject the action code %d"),
17988 MAC_ADDR_ARRAY(peer), action_code);
17989 return -EINVAL;
17990 }
17991 mutex_unlock(&pHddCtx->tdls_lock);
17992 }
17993
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053017994 /* For explicit trigger of DIS_REQ come out of BMPS for
17995 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070017996 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Deepthi Gowrif78f1f72016-03-21 13:13:28 +053017997 (SIR_MAC_TDLS_SETUP_CNF== action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053017998 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
17999 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070018000 {
18001 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
18002 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018003 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053018004 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018005 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
18006 if (status != VOS_STATUS_SUCCESS) {
18007 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
18008 }
Hoonki Lee14621352013-04-16 17:51:19 -070018009 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018010 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018011 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018012 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
18013 }
18014 }
Hoonki Lee14621352013-04-16 17:51:19 -070018015 }
18016
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018017 /* make sure doesn't call send_mgmt() while it is pending */
18018 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
18019 {
18020 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080018021 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018022 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018023 ret = -EBUSY;
18024 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018025 }
18026
18027 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018028 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
18029
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018030 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
18031 pAdapter->sessionId, peer, action_code, dialog_token,
18032 status_code, peer_capability, (tANI_U8 *)buf, len,
18033 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018034
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018035 if (VOS_STATUS_SUCCESS != status)
18036 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018037 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18038 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018039 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018040 ret = -EINVAL;
18041 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018042 }
18043
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018044 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18045 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
18046 WAIT_TIME_TDLS_MGMT);
18047
Hoonki Leed37cbb32013-04-20 00:31:14 -070018048 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
18049 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
18050
18051 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018052 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070018053 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070018054 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070018055 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018056 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080018057
18058 if (pHddCtx->isLogpInProgress)
18059 {
18060 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18061 "%s: LOGP in Progress. Ignore!!!", __func__);
18062 return -EAGAIN;
18063 }
Abhishek Singh837adf22015-10-01 17:37:37 +053018064 if (rc <= 0)
18065 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
18066 WLAN_LOG_INDICATOR_HOST_DRIVER,
18067 WLAN_LOG_REASON_HDD_TIME_OUT,
18068 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080018069
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018070 ret = -EINVAL;
18071 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018072 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018073 else
18074 {
18075 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18076 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
18077 __func__, rc, pAdapter->mgmtTxCompletionStatus);
18078 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018079
Gopichand Nakkala05922802013-03-14 12:23:19 -070018080 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070018081 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018082 ret = max_sta_failed;
18083 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070018084 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018085
Hoonki Leea34dd892013-02-05 22:56:02 -080018086 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
18087 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018088 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018089 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
18090 }
Hoonki Leea34dd892013-02-05 22:56:02 -080018091 }
18092 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
18093 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018094 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018095 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
18096 }
Hoonki Leea34dd892013-02-05 22:56:02 -080018097 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018098
18099 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018100
18101tx_failed:
18102 /* add_station will be called before sending TDLS_SETUP_REQ and
18103 * TDLS_SETUP_RSP and as part of add_station driver will enable
18104 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
18105 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
18106 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
18107 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
18108 */
18109
18110 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
18111 (SIR_MAC_TDLS_SETUP_RSP == action_code))
18112 wlan_hdd_tdls_check_bmps(pAdapter);
18113 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018114}
18115
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018116#if TDLS_MGMT_VERSION2
18117static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
18118 u8 *peer, u8 action_code, u8 dialog_token,
18119 u16 status_code, u32 peer_capability,
18120 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018121#else /* TDLS_MGMT_VERSION2 */
18122#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
18123static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18124 struct net_device *dev,
18125 const u8 *peer, u8 action_code,
18126 u8 dialog_token, u16 status_code,
18127 u32 peer_capability, bool initiator,
18128 const u8 *buf, size_t len)
18129#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18130static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18131 struct net_device *dev,
18132 const u8 *peer, u8 action_code,
18133 u8 dialog_token, u16 status_code,
18134 u32 peer_capability, const u8 *buf,
18135 size_t len)
18136#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
18137static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18138 struct net_device *dev,
18139 u8 *peer, u8 action_code,
18140 u8 dialog_token,
18141 u16 status_code, u32 peer_capability,
18142 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018143#else
18144static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
18145 u8 *peer, u8 action_code, u8 dialog_token,
18146 u16 status_code, const u8 *buf, size_t len)
18147#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018148#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018149{
18150 int ret;
18151
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018152 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018153#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018154 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
18155 dialog_token, status_code,
18156 peer_capability, buf, len);
18157#else /* TDLS_MGMT_VERSION2 */
18158#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
18159 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
18160 dialog_token, status_code,
18161 peer_capability, initiator,
18162 buf, len);
18163#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
18164 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
18165 dialog_token, status_code,
18166 peer_capability, buf, len);
18167#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
18168 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
18169 dialog_token, status_code,
18170 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018171#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018172 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
18173 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018174#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018175#endif
18176 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018177
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018178 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018179}
Atul Mittal115287b2014-07-08 13:26:33 +053018180
18181int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018182#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18183 const u8 *peer,
18184#else
Atul Mittal115287b2014-07-08 13:26:33 +053018185 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018186#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018187 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053018188 cfg80211_exttdls_callback callback)
18189{
18190
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018191 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053018192 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053018193 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053018194 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18195 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
18196 __func__, MAC_ADDR_ARRAY(peer));
18197
18198 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
18199 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
18200
18201 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018202 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
18203 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
18204 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053018205 return -ENOTSUPP;
18206 }
18207
18208 /* To cater the requirement of establishing the TDLS link
18209 * irrespective of the data traffic , get an entry of TDLS peer.
18210 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053018211 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053018212 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
18213 if (pTdlsPeer == NULL) {
18214 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18215 "%s: peer " MAC_ADDRESS_STR " not existing",
18216 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053018217 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053018218 return -EINVAL;
18219 }
18220
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053018221 /* check FW TDLS Off Channel capability */
18222 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053018223 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053018224 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018225 {
18226 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
18227 pTdlsPeer->peerParams.global_operating_class =
18228 tdls_peer_params->global_operating_class;
18229 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
18230 pTdlsPeer->peerParams.min_bandwidth_kbps =
18231 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053018232 /* check configured channel is valid, non dfs and
18233 * not current operating channel */
18234 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
18235 tdls_peer_params->channel)) &&
18236 (pHddStaCtx) &&
18237 (tdls_peer_params->channel !=
18238 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018239 {
18240 pTdlsPeer->isOffChannelConfigured = TRUE;
18241 }
18242 else
18243 {
18244 pTdlsPeer->isOffChannelConfigured = FALSE;
18245 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18246 "%s: Configured Tdls Off Channel is not valid", __func__);
18247
18248 }
18249 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053018250 "%s: tdls_off_channel %d isOffChannelConfigured %d "
18251 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018252 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053018253 pTdlsPeer->isOffChannelConfigured,
18254 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018255 }
18256 else
18257 {
18258 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053018259 "%s: TDLS off channel FW capability %d, "
18260 "host capab %d or Invalid TDLS Peer Params", __func__,
18261 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
18262 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018263 }
18264
Atul Mittal115287b2014-07-08 13:26:33 +053018265 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
18266
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018267 mutex_unlock(&pHddCtx->tdls_lock);
18268
Atul Mittal115287b2014-07-08 13:26:33 +053018269 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18270 " %s TDLS Add Force Peer Failed",
18271 __func__);
18272 return -EINVAL;
18273 }
18274 /*EXT TDLS*/
18275
18276 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018277 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053018278 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18279 " %s TDLS set callback Failed",
18280 __func__);
18281 return -EINVAL;
18282 }
18283
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018284 mutex_unlock(&pHddCtx->tdls_lock);
18285
Atul Mittal115287b2014-07-08 13:26:33 +053018286 return(0);
18287
18288}
18289
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018290int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
18291#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18292 const u8 *peer
18293#else
18294 u8 *peer
18295#endif
18296)
Atul Mittal115287b2014-07-08 13:26:33 +053018297{
18298
18299 hddTdlsPeer_t *pTdlsPeer;
18300 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053018301
Atul Mittal115287b2014-07-08 13:26:33 +053018302 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18303 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
18304 __func__, MAC_ADDR_ARRAY(peer));
18305
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053018306 if (0 != wlan_hdd_validate_context(pHddCtx)) {
18307 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
18308 return -EINVAL;
18309 }
18310
Atul Mittal115287b2014-07-08 13:26:33 +053018311 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
18312 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
18313
18314 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018315 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
18316 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
18317 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053018318 return -ENOTSUPP;
18319 }
18320
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018321 mutex_lock(&pHddCtx->tdls_lock);
18322 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Atul Mittal115287b2014-07-08 13:26:33 +053018323
18324 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018325 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053018326 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018327 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053018328 __func__, MAC_ADDR_ARRAY(peer));
18329 return -EINVAL;
18330 }
18331 else {
18332 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
18333 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053018334 hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_EXT_CTRL,
18335 pTdlsPeer->peerMac);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018336 /* if channel switch is configured, reset
18337 the channel for this peer */
18338 if (TRUE == pTdlsPeer->isOffChannelConfigured)
18339 {
18340 pTdlsPeer->peerParams.channel = 0;
18341 pTdlsPeer->isOffChannelConfigured = FALSE;
18342 }
Atul Mittal115287b2014-07-08 13:26:33 +053018343 }
18344
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018345 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018346 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018347 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053018348 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018349 }
Atul Mittal115287b2014-07-08 13:26:33 +053018350
18351 /*EXT TDLS*/
18352
18353 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018354 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053018355 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18356 " %s TDLS set callback Failed",
18357 __func__);
18358 return -EINVAL;
18359 }
Atul Mittal115287b2014-07-08 13:26:33 +053018360
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018361 mutex_unlock(&pHddCtx->tdls_lock);
18362
18363 return(0);
Atul Mittal115287b2014-07-08 13:26:33 +053018364}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018365static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018366#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18367 const u8 *peer,
18368#else
18369 u8 *peer,
18370#endif
18371 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018372{
18373 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18374 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018375 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018376 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018377
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018378 ENTER();
18379
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053018380 if (!pAdapter) {
18381 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
18382 return -EINVAL;
18383 }
18384
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018385 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18386 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
18387 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018388 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018389 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018390 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070018391 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018392 return -EINVAL;
18393 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080018394
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018395 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018396 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080018397 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018398 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080018399 }
18400
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018401
18402 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080018403 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018404 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080018405 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018406 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
18407 "Cannot process TDLS commands",
18408 pHddCtx->cfg_ini->fEnableTDLSSupport,
18409 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018410 return -ENOTSUPP;
18411 }
18412
18413 switch (oper) {
18414 case NL80211_TDLS_ENABLE_LINK:
18415 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018416 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018417 long ret;
Hanumantha Reddy Pothulada389492016-02-11 17:29:27 +053018418 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams = { {0}, 0,
18419 0, 0, 0, 0, 0, 0, {0}, 0, {0} };
Agarwal Ashish16020c42014-12-29 22:01:11 +053018420 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018421 tANI_U16 numCurrTdlsPeers = 0;
18422 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018423 tANI_U8 suppChannelLen = 0;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018424 tSirMacAddr peerMac;
18425 int channel;
18426 tTDLSLinkStatus peer_status = eTDLS_LINK_IDLE;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018427
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018428 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18429 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
18430 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018431
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018432 mutex_lock(&pHddCtx->tdls_lock);
18433 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053018434 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053018435 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018436 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018437 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
18438 " (oper %d) not exsting. ignored",
18439 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18440 return -EINVAL;
18441 }
18442
18443 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18444 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
18445 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
18446 "NL80211_TDLS_ENABLE_LINK");
18447
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070018448 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
18449 {
18450 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
18451 MAC_ADDRESS_STR " failed",
18452 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018453 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070018454 return -EINVAL;
18455 }
18456
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053018457 /* before starting tdls connection, set tdls
18458 * off channel established status to default value */
18459 pTdlsPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018460
18461 mutex_unlock(&pHddCtx->tdls_lock);
18462
Deepthi Gowri2d85bbf2016-07-25 15:43:31 +053018463 wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018464 /* TDLS Off Channel, Disable tdls channel switch,
18465 when there are more than one tdls link */
18466 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053018467 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018468 {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018469 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018470 /* get connected peer and send disable tdls off chan */
18471 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018472 if ((connPeer) &&
18473 (connPeer->isOffChannelSupported == TRUE) &&
18474 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018475 {
18476 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18477 "%s: More then one peer connected, Disable "
18478 "TDLS channel switch", __func__);
18479
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053018480 connPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018481 vos_mem_copy(peerMac, connPeer->peerMac, sizeof (tSirMacAddr));
18482 channel = connPeer->peerParams.channel;
18483
18484 mutex_unlock(&pHddCtx->tdls_lock);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018485
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018486 ret = sme_SendTdlsChanSwitchReq(
18487 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018488 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018489 peerMac,
18490 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018491 TDLS_OFF_CHANNEL_BW_OFFSET,
18492 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018493 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018494 hddLog(VOS_TRACE_LEVEL_ERROR,
18495 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018496 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018497 }
18498 else
18499 {
18500 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18501 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018502 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018503 "isOffChannelConfigured %d",
18504 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018505 (connPeer ? (connPeer->isOffChannelSupported)
18506 : -1),
18507 (connPeer ? (connPeer->isOffChannelConfigured)
18508 : -1));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018509 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018510 }
18511 }
18512
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018513 mutex_lock(&pHddCtx->tdls_lock);
18514 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18515 if ( NULL == pTdlsPeer ) {
18516 mutex_unlock(&pHddCtx->tdls_lock);
18517 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18518 "%s: " MAC_ADDRESS_STR
18519 " (oper %d) peer got freed in other context. ignored",
18520 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18521 return -EINVAL;
18522 }
18523 peer_status = pTdlsPeer->link_status;
18524 mutex_unlock(&pHddCtx->tdls_lock);
18525
18526 if (eTDLS_LINK_CONNECTED != peer_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018527 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018528 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053018529
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018530 if (0 != wlan_hdd_tdls_get_link_establish_params(
18531 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018532 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018533 return -EINVAL;
18534 }
18535 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018536
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018537 ret = sme_SendTdlsLinkEstablishParams(
18538 WLAN_HDD_GET_HAL_CTX(pAdapter),
18539 pAdapter->sessionId, peer,
18540 &tdlsLinkEstablishParams);
18541 if (ret != VOS_STATUS_SUCCESS) {
18542 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
18543 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018544 /* Send TDLS peer UAPSD capabilities to the firmware and
18545 * register with the TL on after the response for this operation
18546 * is received .
18547 */
18548 ret = wait_for_completion_interruptible_timeout(
18549 &pAdapter->tdls_link_establish_req_comp,
18550 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
Masti, Narayanraddie1892a52015-12-15 15:01:01 +053018551
18552 mutex_lock(&pHddCtx->tdls_lock);
18553 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18554 if ( NULL == pTdlsPeer ) {
18555 mutex_unlock(&pHddCtx->tdls_lock);
18556 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18557 "%s %d: " MAC_ADDRESS_STR
18558 " (oper %d) peer got freed in other context. ignored",
18559 __func__, __LINE__, MAC_ADDR_ARRAY(peer),
18560 (int)oper);
18561 return -EINVAL;
18562 }
18563 peer_status = pTdlsPeer->link_status;
18564 mutex_unlock(&pHddCtx->tdls_lock);
18565
18566 if (ret <= 0 || (peer_status == eTDLS_LINK_TEARING))
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018567 {
18568 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018569 FL("Link Establish Request Failed Status %ld"),
18570 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018571 return -EINVAL;
18572 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018573 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018574
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018575 mutex_lock(&pHddCtx->tdls_lock);
18576 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18577 if ( NULL == pTdlsPeer ) {
18578 mutex_unlock(&pHddCtx->tdls_lock);
18579 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18580 "%s: " MAC_ADDRESS_STR
18581 " (oper %d) peer got freed in other context. ignored",
18582 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18583 return -EINVAL;
18584 }
18585
Atul Mittal115287b2014-07-08 13:26:33 +053018586 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
18587 eTDLS_LINK_CONNECTED,
18588 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053018589 staDesc.ucSTAId = pTdlsPeer->staId;
18590 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053018591
18592 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18593 "%s: tdlsLinkEstablishParams of peer "
18594 MAC_ADDRESS_STR "uapsdQueues: %d"
18595 "qos: %d maxSp: %d isBufSta: %d isOffChannelSupported: %d"
18596 "isResponder: %d peerstaId: %d",
18597 __func__,
18598 MAC_ADDR_ARRAY(tdlsLinkEstablishParams.peerMac),
18599 tdlsLinkEstablishParams.uapsdQueues,
18600 tdlsLinkEstablishParams.qos,
18601 tdlsLinkEstablishParams.maxSp,
18602 tdlsLinkEstablishParams.isBufSta,
18603 tdlsLinkEstablishParams.isOffChannelSupported,
18604 tdlsLinkEstablishParams.isResponder,
18605 pTdlsPeer->staId);
18606
18607 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18608 "%s: StaDesc ucSTAId: %d ucQosEnabled: %d",
18609 __func__,
18610 staDesc.ucSTAId,
18611 staDesc.ucQosEnabled);
18612
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018613 ret = WLANTL_UpdateTdlsSTAClient(
18614 pHddCtx->pvosContext,
18615 &staDesc);
18616 if (ret != VOS_STATUS_SUCCESS) {
18617 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
18618 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053018619
Gopichand Nakkala471708b2013-06-04 20:03:01 +053018620 /* Mark TDLS client Authenticated .*/
18621 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
18622 pTdlsPeer->staId,
18623 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070018624 if (VOS_STATUS_SUCCESS == status)
18625 {
Hoonki Lee14621352013-04-16 17:51:19 -070018626 if (pTdlsPeer->is_responder == 0)
18627 {
18628 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053018629 tdlsConnInfo_t *tdlsInfo;
18630
18631 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
18632
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053018633 if (!vos_timer_is_initialized(
18634 &pTdlsPeer->initiatorWaitTimeoutTimer))
18635 {
18636 /* Initialize initiator wait callback */
18637 vos_timer_init(
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053018638 &pTdlsPeer->initiatorWaitTimeoutTimer,
18639 VOS_TIMER_TYPE_SW,
18640 wlan_hdd_tdls_initiator_wait_cb,
18641 tdlsInfo);
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053018642 }
Hoonki Lee14621352013-04-16 17:51:19 -070018643 wlan_hdd_tdls_timer_restart(pAdapter,
18644 &pTdlsPeer->initiatorWaitTimeoutTimer,
18645 WAIT_TIME_TDLS_INITIATOR);
18646 /* suspend initiator TX until it receives direct packet from the
18647 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018648 ret = WLANTL_SuspendDataTx(
18649 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
18650 &staId, NULL);
18651 if (ret != VOS_STATUS_SUCCESS) {
18652 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
18653 }
Hoonki Lee14621352013-04-16 17:51:19 -070018654 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018655
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018656 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018657 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018658 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018659 suppChannelLen =
18660 tdlsLinkEstablishParams.supportedChannelsLen;
18661
18662 if ((suppChannelLen > 0) &&
18663 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
18664 {
18665 tANI_U8 suppPeerChannel = 0;
18666 int i = 0;
18667 for (i = 0U; i < suppChannelLen; i++)
18668 {
18669 suppPeerChannel =
18670 tdlsLinkEstablishParams.supportedChannels[i];
18671
18672 pTdlsPeer->isOffChannelSupported = FALSE;
18673 if (suppPeerChannel ==
18674 pTdlsPeer->peerParams.channel)
18675 {
18676 pTdlsPeer->isOffChannelSupported = TRUE;
18677 break;
18678 }
18679 }
18680 }
18681 else
18682 {
18683 pTdlsPeer->isOffChannelSupported = FALSE;
18684 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018685 }
18686 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18687 "%s: TDLS channel switch request for channel "
18688 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018689 "%d isOffChannelSupported %d", __func__,
18690 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018691 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018692 suppChannelLen,
18693 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018694
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018695 /* TDLS Off Channel, Enable tdls channel switch,
18696 when their is only one tdls link and it supports */
18697 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
18698 if ((numCurrTdlsPeers == 1) &&
18699 (TRUE == pTdlsPeer->isOffChannelSupported) &&
18700 (TRUE == pTdlsPeer->isOffChannelConfigured))
18701 {
18702 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18703 "%s: Send TDLS channel switch request for channel %d",
18704 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053018705
18706 pTdlsPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018707 vos_mem_copy(peerMac, pTdlsPeer->peerMac, sizeof (tSirMacAddr));
18708 channel = pTdlsPeer->peerParams.channel;
18709
18710 mutex_unlock(&pHddCtx->tdls_lock);
18711
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018712 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
18713 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018714 peerMac,
18715 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018716 TDLS_OFF_CHANNEL_BW_OFFSET,
18717 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018718 if (ret != VOS_STATUS_SUCCESS) {
18719 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
18720 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018721 }
18722 else
18723 {
18724 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18725 "%s: TDLS channel switch request not sent"
18726 " numCurrTdlsPeers %d "
18727 "isOffChannelSupported %d "
18728 "isOffChannelConfigured %d",
18729 __func__, numCurrTdlsPeers,
18730 pTdlsPeer->isOffChannelSupported,
18731 pTdlsPeer->isOffChannelConfigured);
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018732 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018733 }
18734
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070018735 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018736 else
18737 mutex_unlock(&pHddCtx->tdls_lock);
18738
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018739 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018740
18741 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053018742 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
18743 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018744 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053018745 int ac;
18746 uint8 ucAc[4] = { WLANTL_AC_VO,
18747 WLANTL_AC_VI,
18748 WLANTL_AC_BK,
18749 WLANTL_AC_BE };
18750 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
18751 for(ac=0; ac < 4; ac++)
18752 {
18753 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
18754 pTdlsPeer->staId, ucAc[ac],
18755 tlTid[ac], tlTid[ac], 0, 0,
18756 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018757 if (status != VOS_STATUS_SUCCESS) {
18758 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
18759 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053018760 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018761 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018762 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018763
Bhargav Shah66896792015-10-01 18:17:37 +053018764 /* stop TCP delack timer if TDLS is enable */
18765 set_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
18766 hdd_manage_delack_timer(pHddCtx);
Abhishek Singh67fa6bc2016-01-05 15:57:19 +053018767 hdd_wlan_tdls_enable_link_event(peer,
18768 pTdlsPeer->isOffChannelSupported,
18769 pTdlsPeer->isOffChannelConfigured,
18770 pTdlsPeer->isOffChannelEstablished);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018771 }
18772 break;
18773 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080018774 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018775 tANI_U16 numCurrTdlsPeers = 0;
18776 hddTdlsPeer_t *connPeer = NULL;
18777
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018778 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18779 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
18780 __func__, MAC_ADDR_ARRAY(peer));
18781
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018782 mutex_lock(&pHddCtx->tdls_lock);
18783 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018784
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018785
Sunil Dutt41de4e22013-11-14 18:09:02 +053018786 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018787 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018788 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
18789 " (oper %d) not exsting. ignored",
18790 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18791 return -EINVAL;
18792 }
18793
18794 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18795 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
18796 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
18797 "NL80211_TDLS_DISABLE_LINK");
18798
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018799 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080018800 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018801 long status;
18802
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053018803 /* set tdls off channel status to false for this peer */
18804 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053018805 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
18806 eTDLS_LINK_TEARING,
18807 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
18808 eTDLS_LINK_UNSPECIFIED:
18809 eTDLS_LINK_DROPPED_BY_REMOTE);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018810 mutex_unlock(&pHddCtx->tdls_lock);
18811
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018812 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
18813
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018814 status = sme_DeleteTdlsPeerSta(
18815 WLAN_HDD_GET_HAL_CTX(pAdapter),
18816 pAdapter->sessionId, peer );
18817 if (status != VOS_STATUS_SUCCESS) {
18818 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
18819 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018820
18821 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
18822 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018823
18824 mutex_lock(&pHddCtx->tdls_lock);
18825 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18826 if ( NULL == pTdlsPeer ) {
18827 mutex_unlock(&pHddCtx->tdls_lock);
18828 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
18829 " peer was freed in other context",
18830 __func__, MAC_ADDR_ARRAY(peer));
18831 return -EINVAL;
18832 }
18833
Atul Mittal271a7652014-09-12 13:18:22 +053018834 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053018835 eTDLS_LINK_IDLE,
18836 eTDLS_LINK_UNSPECIFIED);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018837 mutex_unlock(&pHddCtx->tdls_lock);
18838
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018839 if (status <= 0)
18840 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018841 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18842 "%s: Del station failed status %ld",
18843 __func__, status);
18844 return -EPERM;
18845 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018846
18847 /* TDLS Off Channel, Enable tdls channel switch,
18848 when their is only one tdls link and it supports */
18849 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
18850 if (numCurrTdlsPeers == 1)
18851 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018852 tSirMacAddr peerMac;
18853 int channel;
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053018854
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018855 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018856 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053018857
18858 if (connPeer == NULL) {
18859 mutex_unlock(&pHddCtx->tdls_lock);
18860 hddLog(VOS_TRACE_LEVEL_ERROR,
18861 "%s connPeer is NULL", __func__);
18862 return -EINVAL;
18863 }
18864
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018865 vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr));
18866 channel = connPeer->peerParams.channel;
18867
18868 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18869 "%s: TDLS channel switch "
18870 "isOffChannelSupported %d "
18871 "isOffChannelConfigured %d "
18872 "isOffChannelEstablished %d",
18873 __func__,
18874 (connPeer ? connPeer->isOffChannelSupported : -1),
18875 (connPeer ? connPeer->isOffChannelConfigured : -1),
18876 (connPeer ? connPeer->isOffChannelEstablished : -1));
18877
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018878 if ((connPeer) &&
18879 (connPeer->isOffChannelSupported == TRUE) &&
18880 (connPeer->isOffChannelConfigured == TRUE))
18881 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053018882 connPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018883 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018884 status = sme_SendTdlsChanSwitchReq(
18885 WLAN_HDD_GET_HAL_CTX(pAdapter),
18886 pAdapter->sessionId,
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018887 peerMac,
18888 channel,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018889 TDLS_OFF_CHANNEL_BW_OFFSET,
18890 TDLS_CHANNEL_SWITCH_ENABLE);
18891 if (status != VOS_STATUS_SUCCESS) {
18892 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
18893 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018894 }
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018895 else
18896 mutex_unlock(&pHddCtx->tdls_lock);
18897 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018898 else
18899 {
18900 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18901 "%s: TDLS channel switch request not sent "
18902 "numCurrTdlsPeers %d ",
18903 __func__, numCurrTdlsPeers);
18904 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018905 }
18906 else
18907 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018908 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018909 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18910 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080018911 }
Bhargav Shah66896792015-10-01 18:17:37 +053018912 if (numCurrTdlsPeers == 0) {
18913 /* start TCP delack timer if TDLS is disable */
18914 clear_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
18915 hdd_manage_delack_timer(pHddCtx);
18916 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018917 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018918 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018919 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053018920 {
Atul Mittal115287b2014-07-08 13:26:33 +053018921 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018922
Atul Mittal115287b2014-07-08 13:26:33 +053018923 if (0 != status)
18924 {
18925 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018926 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053018927 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053018928 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053018929 break;
18930 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018931 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053018932 {
Atul Mittal115287b2014-07-08 13:26:33 +053018933 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
18934 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018935 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053018936 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018937
Atul Mittal115287b2014-07-08 13:26:33 +053018938 if (0 != status)
18939 {
18940 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018941 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053018942 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053018943 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053018944 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053018945 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018946 case NL80211_TDLS_DISCOVERY_REQ:
18947 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018948 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018949 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018950 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018951 return -ENOTSUPP;
18952 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018953 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18954 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018955 return -ENOTSUPP;
18956 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018957
18958 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018959 return 0;
18960}
Chilam NG571c65a2013-01-19 12:27:36 +053018961
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018962static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018963#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18964 const u8 *peer,
18965#else
18966 u8 *peer,
18967#endif
18968 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018969{
18970 int ret;
18971
18972 vos_ssr_protect(__func__);
18973 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
18974 vos_ssr_unprotect(__func__);
18975
18976 return ret;
18977}
18978
Chilam NG571c65a2013-01-19 12:27:36 +053018979int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
18980 struct net_device *dev, u8 *peer)
18981{
Arif Hussaina7c8e412013-11-20 11:06:42 -080018982 hddLog(VOS_TRACE_LEVEL_INFO,
18983 "tdls send discover req: "MAC_ADDRESS_STR,
18984 MAC_ADDR_ARRAY(peer));
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018985#if TDLS_MGMT_VERSION2
18986 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18987 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
18988#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018989#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
18990 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18991 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
18992#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18993 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18994 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
18995#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
18996 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18997 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
18998#else
Chilam NG571c65a2013-01-19 12:27:36 +053018999 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19000 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019001#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019002#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053019003}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019004#endif
19005
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019006#ifdef WLAN_FEATURE_GTK_OFFLOAD
19007/*
19008 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
19009 * Callback rountine called upon receiving response for
19010 * get offload info
19011 */
19012void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
19013 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
19014{
19015
19016 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019017 tANI_U8 tempReplayCounter[8];
19018 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019019
19020 ENTER();
19021
19022 if (NULL == pAdapter)
19023 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053019024 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019025 "%s: HDD adapter is Null", __func__);
19026 return ;
19027 }
19028
19029 if (NULL == pGtkOffloadGetInfoRsp)
19030 {
19031 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19032 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
19033 return ;
19034 }
19035
19036 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
19037 {
19038 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19039 "%s: wlan Failed to get replay counter value",
19040 __func__);
19041 return ;
19042 }
19043
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019044 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
19045 /* Update replay counter */
19046 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
19047 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
19048
19049 {
19050 /* changing from little to big endian since supplicant
19051 * works on big endian format
19052 */
19053 int i;
19054 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
19055
19056 for (i = 0; i < 8; i++)
19057 {
19058 tempReplayCounter[7-i] = (tANI_U8)p[i];
19059 }
19060 }
19061
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019062 /* Update replay counter to NL */
19063 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019064 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019065}
19066
19067/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019068 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019069 * This function is used to offload GTK rekeying job to the firmware.
19070 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019071int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019072 struct cfg80211_gtk_rekey_data *data)
19073{
19074 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19075 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
19076 hdd_station_ctx_t *pHddStaCtx;
19077 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019078 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019079 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019080 eHalStatus status = eHAL_STATUS_FAILURE;
19081
19082 ENTER();
19083
19084 if (NULL == pAdapter)
19085 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019086 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019087 "%s: HDD adapter is Null", __func__);
19088 return -ENODEV;
19089 }
19090
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019091 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19092 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
19093 pAdapter->sessionId, pAdapter->device_mode));
19094
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019095 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019096 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019097 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019098 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019099 }
19100
19101 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
19102 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
19103 if (NULL == hHal)
19104 {
19105 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19106 "%s: HAL context is Null!!!", __func__);
19107 return -EAGAIN;
19108 }
19109
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019110 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
19111 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
19112 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
19113 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019114 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019115 {
19116 /* changing from big to little endian since driver
19117 * works on little endian format
19118 */
19119 tANI_U8 *p =
19120 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
19121 int i;
19122
19123 for (i = 0; i < 8; i++)
19124 {
19125 p[7-i] = data->replay_ctr[i];
19126 }
19127 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019128
19129 if (TRUE == pHddCtx->hdd_wlan_suspended)
19130 {
19131 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019132 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
19133 sizeof (tSirGtkOffloadParams));
19134 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019135 pAdapter->sessionId);
19136
19137 if (eHAL_STATUS_SUCCESS != status)
19138 {
19139 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19140 "%s: sme_SetGTKOffload failed, returned %d",
19141 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053019142
19143 /* Need to clear any trace of key value in the memory.
19144 * Thus zero out the memory even though it is local
19145 * variable.
19146 */
19147 vos_mem_zero(&hddGtkOffloadReqParams,
19148 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019149 return status;
19150 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019151 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19152 "%s: sme_SetGTKOffload successfull", __func__);
19153 }
19154 else
19155 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019156 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19157 "%s: wlan not suspended GTKOffload request is stored",
19158 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019159 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019160
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053019161 /* Need to clear any trace of key value in the memory.
19162 * Thus zero out the memory even though it is local
19163 * variable.
19164 */
19165 vos_mem_zero(&hddGtkOffloadReqParams,
19166 sizeof(hddGtkOffloadReqParams));
19167
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019168 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019169 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019170}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019171
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019172int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
19173 struct cfg80211_gtk_rekey_data *data)
19174{
19175 int ret;
19176
19177 vos_ssr_protect(__func__);
19178 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
19179 vos_ssr_unprotect(__func__);
19180
19181 return ret;
19182}
19183#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019184/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019185 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019186 * This function is used to set access control policy
19187 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019188static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
19189 struct net_device *dev,
19190 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019191{
19192 int i;
19193 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19194 hdd_hostapd_state_t *pHostapdState;
19195 tsap_Config_t *pConfig;
19196 v_CONTEXT_t pVosContext = NULL;
19197 hdd_context_t *pHddCtx;
19198 int status;
19199
19200 ENTER();
19201
19202 if (NULL == pAdapter)
19203 {
19204 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19205 "%s: HDD adapter is Null", __func__);
19206 return -ENODEV;
19207 }
19208
19209 if (NULL == params)
19210 {
19211 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19212 "%s: params is Null", __func__);
19213 return -EINVAL;
19214 }
19215
19216 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19217 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019218 if (0 != status)
19219 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019220 return status;
19221 }
19222
19223 pVosContext = pHddCtx->pvosContext;
19224 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
19225
19226 if (NULL == pHostapdState)
19227 {
19228 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19229 "%s: pHostapdState is Null", __func__);
19230 return -EINVAL;
19231 }
19232
19233 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
19234 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019235 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19236 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
19237 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019238
19239 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
19240 {
19241 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
19242
19243 /* default value */
19244 pConfig->num_accept_mac = 0;
19245 pConfig->num_deny_mac = 0;
19246
19247 /**
19248 * access control policy
19249 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
19250 * listed in hostapd.deny file.
19251 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
19252 * listed in hostapd.accept file.
19253 */
19254 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
19255 {
19256 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
19257 }
19258 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
19259 {
19260 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
19261 }
19262 else
19263 {
19264 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19265 "%s:Acl Policy : %d is not supported",
19266 __func__, params->acl_policy);
19267 return -ENOTSUPP;
19268 }
19269
19270 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
19271 {
19272 pConfig->num_accept_mac = params->n_acl_entries;
19273 for (i = 0; i < params->n_acl_entries; i++)
19274 {
19275 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19276 "** Add ACL MAC entry %i in WhiletList :"
19277 MAC_ADDRESS_STR, i,
19278 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
19279
19280 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
19281 sizeof(qcmacaddr));
19282 }
19283 }
19284 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
19285 {
19286 pConfig->num_deny_mac = params->n_acl_entries;
19287 for (i = 0; i < params->n_acl_entries; i++)
19288 {
19289 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19290 "** Add ACL MAC entry %i in BlackList :"
19291 MAC_ADDRESS_STR, i,
19292 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
19293
19294 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
19295 sizeof(qcmacaddr));
19296 }
19297 }
19298
19299 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
19300 {
19301 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19302 "%s: SAP Set Mac Acl fail", __func__);
19303 return -EINVAL;
19304 }
19305 }
19306 else
19307 {
19308 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053019309 "%s: Invalid device_mode = %s (%d)",
19310 __func__, hdd_device_modetoString(pAdapter->device_mode),
19311 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019312 return -EINVAL;
19313 }
19314
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019315 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019316 return 0;
19317}
19318
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019319static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
19320 struct net_device *dev,
19321 const struct cfg80211_acl_data *params)
19322{
19323 int ret;
19324 vos_ssr_protect(__func__);
19325 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
19326 vos_ssr_unprotect(__func__);
19327
19328 return ret;
19329}
19330
Leo Chang9056f462013-08-01 19:21:11 -070019331#ifdef WLAN_NL80211_TESTMODE
19332#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070019333void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070019334(
19335 void *pAdapter,
19336 void *indCont
19337)
19338{
Leo Changd9df8aa2013-09-26 13:32:26 -070019339 tSirLPHBInd *lphbInd;
19340 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053019341 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070019342
19343 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070019344 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070019345
c_hpothu73f35e62014-04-18 13:40:08 +053019346 if (pAdapter == NULL)
19347 {
19348 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19349 "%s: pAdapter is NULL\n",__func__);
19350 return;
19351 }
19352
Leo Chang9056f462013-08-01 19:21:11 -070019353 if (NULL == indCont)
19354 {
19355 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070019356 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070019357 return;
19358 }
19359
c_hpothu73f35e62014-04-18 13:40:08 +053019360 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070019361 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070019362 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053019363 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070019364 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070019365 GFP_ATOMIC);
19366 if (!skb)
19367 {
19368 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19369 "LPHB timeout, NL buffer alloc fail");
19370 return;
19371 }
19372
Leo Changac3ba772013-10-07 09:47:04 -070019373 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070019374 {
19375 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19376 "WLAN_HDD_TM_ATTR_CMD put fail");
19377 goto nla_put_failure;
19378 }
Leo Changac3ba772013-10-07 09:47:04 -070019379 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070019380 {
19381 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19382 "WLAN_HDD_TM_ATTR_TYPE put fail");
19383 goto nla_put_failure;
19384 }
Leo Changac3ba772013-10-07 09:47:04 -070019385 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070019386 sizeof(tSirLPHBInd), lphbInd))
19387 {
19388 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19389 "WLAN_HDD_TM_ATTR_DATA put fail");
19390 goto nla_put_failure;
19391 }
Leo Chang9056f462013-08-01 19:21:11 -070019392 cfg80211_testmode_event(skb, GFP_ATOMIC);
19393 return;
19394
19395nla_put_failure:
19396 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19397 "NLA Put fail");
19398 kfree_skb(skb);
19399
19400 return;
19401}
19402#endif /* FEATURE_WLAN_LPHB */
19403
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019404static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070019405{
19406 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
19407 int err = 0;
19408#ifdef FEATURE_WLAN_LPHB
19409 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070019410 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019411
19412 ENTER();
19413
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019414 err = wlan_hdd_validate_context(pHddCtx);
19415 if (0 != err)
19416 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019417 return err;
19418 }
Leo Chang9056f462013-08-01 19:21:11 -070019419#endif /* FEATURE_WLAN_LPHB */
19420
19421 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
19422 if (err)
19423 {
19424 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19425 "%s Testmode INV ATTR", __func__);
19426 return err;
19427 }
19428
19429 if (!tb[WLAN_HDD_TM_ATTR_CMD])
19430 {
19431 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19432 "%s Testmode INV CMD", __func__);
19433 return -EINVAL;
19434 }
19435
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019436 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19437 TRACE_CODE_HDD_CFG80211_TESTMODE,
19438 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070019439 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
19440 {
19441#ifdef FEATURE_WLAN_LPHB
19442 /* Low Power Heartbeat configuration request */
19443 case WLAN_HDD_TM_CMD_WLAN_HB:
19444 {
19445 int buf_len;
19446 void *buf;
19447 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080019448 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070019449
19450 if (!tb[WLAN_HDD_TM_ATTR_DATA])
19451 {
19452 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19453 "%s Testmode INV DATA", __func__);
19454 return -EINVAL;
19455 }
19456
19457 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
19458 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080019459
19460 hb_params_temp =(tSirLPHBReq *)buf;
19461 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
19462 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
19463 return -EINVAL;
19464
Leo Chang9056f462013-08-01 19:21:11 -070019465 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
19466 if (NULL == hb_params)
19467 {
19468 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19469 "%s Request Buffer Alloc Fail", __func__);
19470 return -EINVAL;
19471 }
19472
19473 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070019474 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
19475 hb_params,
19476 wlan_hdd_cfg80211_lphb_ind_handler);
19477 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070019478 {
Leo Changd9df8aa2013-09-26 13:32:26 -070019479 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19480 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070019481 vos_mem_free(hb_params);
19482 }
Leo Chang9056f462013-08-01 19:21:11 -070019483 return 0;
19484 }
19485#endif /* FEATURE_WLAN_LPHB */
19486 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019487 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19488 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070019489 return -EOPNOTSUPP;
19490 }
19491
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019492 EXIT();
19493 return err;
Leo Chang9056f462013-08-01 19:21:11 -070019494}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019495
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053019496static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
19497#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
19498 struct wireless_dev *wdev,
19499#endif
19500 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019501{
19502 int ret;
19503
19504 vos_ssr_protect(__func__);
19505 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
19506 vos_ssr_unprotect(__func__);
19507
19508 return ret;
19509}
Leo Chang9056f462013-08-01 19:21:11 -070019510#endif /* CONFIG_NL80211_TESTMODE */
19511
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053019512extern void hdd_set_wlan_suspend_mode(bool suspend);
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019513static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019514 struct net_device *dev,
19515 int idx, struct survey_info *survey)
19516{
19517 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19518 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053019519 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019520 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053019521 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019522 v_S7_t snr,rssi;
19523 int status, i, j, filled = 0;
19524
19525 ENTER();
19526
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019527 if (NULL == pAdapter)
19528 {
19529 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19530 "%s: HDD adapter is Null", __func__);
19531 return -ENODEV;
19532 }
19533
19534 if (NULL == wiphy)
19535 {
19536 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19537 "%s: wiphy is Null", __func__);
19538 return -ENODEV;
19539 }
19540
19541 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19542 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019543 if (0 != status)
19544 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019545 return status;
19546 }
19547
Mihir Sheted9072e02013-08-21 17:02:29 +053019548 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
19549
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019550 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053019551 0 != pAdapter->survey_idx ||
19552 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019553 {
19554 /* The survey dump ops when implemented completely is expected to
19555 * return a survey of all channels and the ops is called by the
19556 * kernel with incremental values of the argument 'idx' till it
19557 * returns -ENONET. But we can only support the survey for the
19558 * operating channel for now. survey_idx is used to track
19559 * that the ops is called only once and then return -ENONET for
19560 * the next iteration
19561 */
19562 pAdapter->survey_idx = 0;
19563 return -ENONET;
19564 }
19565
Mukul Sharma9d5233b2015-06-11 20:28:20 +053019566 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
19567 {
19568 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19569 "%s: Roaming in progress, hence return ", __func__);
19570 return -ENONET;
19571 }
19572
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019573 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
19574
19575 wlan_hdd_get_snr(pAdapter, &snr);
19576 wlan_hdd_get_rssi(pAdapter, &rssi);
19577
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019578 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19579 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
19580 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019581 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
19582 hdd_wlan_get_freq(channel, &freq);
19583
19584
19585 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
19586 {
19587 if (NULL == wiphy->bands[i])
19588 {
19589 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
19590 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
19591 continue;
19592 }
19593
19594 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
19595 {
19596 struct ieee80211_supported_band *band = wiphy->bands[i];
19597
19598 if (band->channels[j].center_freq == (v_U16_t)freq)
19599 {
19600 survey->channel = &band->channels[j];
19601 /* The Rx BDs contain SNR values in dB for the received frames
19602 * while the supplicant expects noise. So we calculate and
19603 * return the value of noise (dBm)
19604 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
19605 */
19606 survey->noise = rssi - snr;
19607 survey->filled = SURVEY_INFO_NOISE_DBM;
19608 filled = 1;
19609 }
19610 }
19611 }
19612
19613 if (filled)
19614 pAdapter->survey_idx = 1;
19615 else
19616 {
19617 pAdapter->survey_idx = 0;
19618 return -ENONET;
19619 }
19620
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019621 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019622 return 0;
19623}
19624
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019625static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
19626 struct net_device *dev,
19627 int idx, struct survey_info *survey)
19628{
19629 int ret;
19630
19631 vos_ssr_protect(__func__);
19632 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
19633 vos_ssr_unprotect(__func__);
19634
19635 return ret;
19636}
19637
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019638/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019639 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019640 * this is called when cfg80211 driver resume
19641 * driver updates latest sched_scan scan result(if any) to cfg80211 database
19642 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019643int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019644{
19645 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
19646 hdd_adapter_t *pAdapter;
19647 hdd_adapter_list_node_t *pAdapterNode, *pNext;
19648 VOS_STATUS status = VOS_STATUS_SUCCESS;
19649
19650 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019651
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019652 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019653 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019654 return 0;
19655 }
19656
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019657 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
19658 NO_SESSION, pHddCtx->isWiphySuspended));
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053019659
19660 if ((VOS_STA_SAP_MODE == hdd_get_conparam()) &&
19661 pHddCtx->is_ap_mode_wow_supported)
19662 {
19663 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19664 "%s: Resume SoftAP", __func__);
19665 hdd_set_wlan_suspend_mode(false);
19666 }
19667
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019668 spin_lock(&pHddCtx->schedScan_lock);
19669 pHddCtx->isWiphySuspended = FALSE;
19670 if (TRUE != pHddCtx->isSchedScanUpdatePending)
19671 {
19672 spin_unlock(&pHddCtx->schedScan_lock);
19673 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19674 "%s: Return resume is not due to PNO indication", __func__);
19675 return 0;
19676 }
19677 // Reset flag to avoid updatating cfg80211 data old results again
19678 pHddCtx->isSchedScanUpdatePending = FALSE;
19679 spin_unlock(&pHddCtx->schedScan_lock);
19680
19681 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
19682
19683 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
19684 {
19685 pAdapter = pAdapterNode->pAdapter;
19686 if ( (NULL != pAdapter) &&
19687 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
19688 {
19689 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019690 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019691 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
19692 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019693 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019694 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019695 {
19696 /* Acquire wakelock to handle the case where APP's tries to
19697 * suspend immediately after updating the scan results. Whis
19698 * results in app's is in suspended state and not able to
19699 * process the connect request to AP
19700 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053019701 hdd_prevent_suspend_timeout(2000,
19702 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019703 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019704 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019705
19706 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19707 "%s : cfg80211 scan result database updated", __func__);
19708
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019709 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019710 return 0;
19711
19712 }
19713 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
19714 pAdapterNode = pNext;
19715 }
19716
19717 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19718 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019719 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019720 return 0;
19721}
19722
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019723int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
19724{
19725 int ret;
19726
19727 vos_ssr_protect(__func__);
19728 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
19729 vos_ssr_unprotect(__func__);
19730
19731 return ret;
19732}
19733
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019734/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019735 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019736 * this is called when cfg80211 driver suspends
19737 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019738int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019739 struct cfg80211_wowlan *wow)
19740{
19741 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019742 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019743
19744 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019745
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019746 ret = wlan_hdd_validate_context(pHddCtx);
19747 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019748 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019749 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019750 }
19751
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053019752 if ((VOS_STA_SAP_MODE == hdd_get_conparam()) &&
19753 (pHddCtx->is_ap_mode_wow_supported)) {
19754 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19755 "%s: Suspend SoftAP", __func__);
19756 hdd_set_wlan_suspend_mode(true);
19757 }
19758
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019759
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019760 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19761 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
19762 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019763 pHddCtx->isWiphySuspended = TRUE;
19764
19765 EXIT();
19766
19767 return 0;
19768}
19769
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019770int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
19771 struct cfg80211_wowlan *wow)
19772{
19773 int ret;
19774
19775 vos_ssr_protect(__func__);
19776 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
19777 vos_ssr_unprotect(__func__);
19778
19779 return ret;
19780}
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019781
19782#ifdef FEATURE_OEM_DATA_SUPPORT
19783static void wlan_hdd_cfg80211_oem_data_rsp_ind_new(void *ctx,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019784 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019785{
19786 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
19787
19788 ENTER();
19789
19790 if (wlan_hdd_validate_context(pHddCtx)) {
19791 return;
19792 }
19793 if (!pMsg)
19794 {
19795 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
19796 return;
19797 }
19798
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019799 send_oem_data_rsp_msg(evLen, pMsg);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019800
19801 EXIT();
19802 return;
19803
19804}
19805
19806void wlan_hdd_cfg80211_oemdata_callback(void *ctx, const tANI_U16 evType,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019807 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019808{
19809 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
19810
19811 ENTER();
19812
19813 if (wlan_hdd_validate_context(pHddCtx)) {
19814 return;
19815 }
19816
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019817 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d) evLen %d"), evType, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019818
19819 switch(evType) {
19820 case SIR_HAL_START_OEM_DATA_RSP_IND_NEW:
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019821 wlan_hdd_cfg80211_oem_data_rsp_ind_new(ctx, pMsg, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019822 break;
19823 default:
19824 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
19825 break;
19826 }
19827 EXIT();
19828}
19829#endif
19830
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053019831#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
19832 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053019833/**
19834 * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api
19835 * @wiphy: Pointer to wiphy
19836 * @wdev: Pointer to wireless device structure
19837 *
19838 * This function is used to abort an ongoing scan
19839 *
19840 * Return: None
19841 */
19842static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
19843 struct wireless_dev *wdev)
19844{
19845 struct net_device *dev = wdev->netdev;
19846 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
19847 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
19848 int ret;
19849
19850 ENTER();
19851
19852 if (NULL == adapter) {
19853 hddLog(VOS_TRACE_LEVEL_FATAL, FL("HDD adapter is NULL"));
19854 return;
19855 }
19856
19857 ret = wlan_hdd_validate_context(hdd_ctx);
19858 if (0 != ret)
19859 return;
19860
19861 wlan_hdd_scan_abort(adapter);
19862
19863 return;
19864}
19865
19866/**
19867 * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api
19868 * @wiphy: Pointer to wiphy
19869 * @wdev: Pointer to wireless device structure
19870 *
19871 * Return: None
19872 */
19873void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
19874 struct wireless_dev *wdev)
19875{
19876 vos_ssr_protect(__func__);
19877 __wlan_hdd_cfg80211_abort_scan(wiphy, wdev);
19878 vos_ssr_unprotect(__func__);
19879
19880 return;
19881}
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053019882#endif
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053019883
Jeff Johnson295189b2012-06-20 16:38:30 -070019884/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019885static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070019886{
19887 .add_virtual_intf = wlan_hdd_add_virtual_intf,
19888 .del_virtual_intf = wlan_hdd_del_virtual_intf,
19889 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
19890 .change_station = wlan_hdd_change_station,
19891#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
19892 .add_beacon = wlan_hdd_cfg80211_add_beacon,
19893 .del_beacon = wlan_hdd_cfg80211_del_beacon,
19894 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019895#else
19896 .start_ap = wlan_hdd_cfg80211_start_ap,
19897 .change_beacon = wlan_hdd_cfg80211_change_beacon,
19898 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070019899#endif
19900 .change_bss = wlan_hdd_cfg80211_change_bss,
19901 .add_key = wlan_hdd_cfg80211_add_key,
19902 .get_key = wlan_hdd_cfg80211_get_key,
19903 .del_key = wlan_hdd_cfg80211_del_key,
19904 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080019905#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070019906 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080019907#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070019908 .scan = wlan_hdd_cfg80211_scan,
19909 .connect = wlan_hdd_cfg80211_connect,
19910 .disconnect = wlan_hdd_cfg80211_disconnect,
19911 .join_ibss = wlan_hdd_cfg80211_join_ibss,
19912 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
19913 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
19914 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
19915 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070019916 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
19917 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053019918 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070019919#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
19920 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
19921 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
19922 .set_txq_params = wlan_hdd_set_txq_params,
19923#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070019924 .get_station = wlan_hdd_cfg80211_get_station,
19925 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
19926 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019927 .add_station = wlan_hdd_cfg80211_add_station,
19928#ifdef FEATURE_WLAN_LFR
19929 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
19930 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
19931 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
19932#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019933#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
19934 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
19935#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019936#ifdef FEATURE_WLAN_TDLS
19937 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
19938 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
19939#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019940#ifdef WLAN_FEATURE_GTK_OFFLOAD
19941 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
19942#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019943#ifdef FEATURE_WLAN_SCAN_PNO
19944 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
19945 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
19946#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019947 .resume = wlan_hdd_cfg80211_resume_wlan,
19948 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019949 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070019950#ifdef WLAN_NL80211_TESTMODE
19951 .testmode_cmd = wlan_hdd_cfg80211_testmode,
19952#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019953 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053019954#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
19955 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053019956 .abort_scan = wlan_hdd_cfg80211_abort_scan,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053019957#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070019958};
19959