blob: 6b6012c3d987ff73bf350d6c2f72684fb3bac9de [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Abhishek Singhb3e376c2017-01-04 15:27:13 +05302 * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lama7f454d2014-07-24 12:04:06 -070023 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +053026 *
Kiet Lamaa8e15a2014-02-11 23:30:06 -080027 */
Kiet Lam842dad02014-02-18 18:44:02 -080028
29
Kiet Lama7f454d2014-07-24 12:04:06 -070030
31
Jeff Johnson295189b2012-06-20 16:38:30 -070032/**========================================================================
33
34 \file wlan_hdd_cfg80211.c
35
36 \brief WLAN Host Device Driver implementation
37
Jeff Johnson295189b2012-06-20 16:38:30 -070038 ========================================================================*/
39
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070040/**=========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -070041
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070042 EDIT HISTORY FOR FILE
Jeff Johnson295189b2012-06-20 16:38:30 -070043
44
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070045 This section contains comments describing changes made to the module.
46 Notice that changes are listed in reverse chronological order.
Jeff Johnson295189b2012-06-20 16:38:30 -070047
48
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070049 $Header:$ $DateTime: $ $Author: $
Jeff Johnson295189b2012-06-20 16:38:30 -070050
51
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070052 when who what, where, why
Jeff Johnson295189b2012-06-20 16:38:30 -070053 -------- --- --------------------------------------------------------
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070054 21/12/09 Ashwani Created module.
Jeff Johnson295189b2012-06-20 16:38:30 -070055
56 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070057 Ganesh K
Jeff Johnson295189b2012-06-20 16:38:30 -070058 ==========================================================================*/
59
Jeff Johnson295189b2012-06-20 16:38:30 -070060
61#include <linux/version.h>
62#include <linux/module.h>
63#include <linux/kernel.h>
64#include <linux/init.h>
65#include <linux/wireless.h>
66#include <wlan_hdd_includes.h>
67#include <net/arp.h>
68#include <net/cfg80211.h>
69#include <linux/wireless.h>
70#include <wlan_hdd_wowl.h>
71#include <aniGlobal.h>
72#include "ccmApi.h"
73#include "sirParams.h"
74#include "dot11f.h"
75#include "wlan_hdd_assoc.h"
76#include "wlan_hdd_wext.h"
77#include "sme_Api.h"
78#include "wlan_hdd_p2p.h"
79#include "wlan_hdd_cfg80211.h"
80#include "wlan_hdd_hostapd.h"
81#include "sapInternal.h"
82#include "wlan_hdd_softap_tx_rx.h"
83#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053084#include "wlan_hdd_assoc.h"
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053085#include "wlan_hdd_power.h"
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053086#include "wlan_hdd_trace.h"
87#include "vos_types.h"
88#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070089#ifdef WLAN_BTAMP_FEATURE
90#include "bap_hdd_misc.h"
91#endif
92#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080093#include "wlan_hdd_tdls.h"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053094#include "wlan_hdd_wmm.h"
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053095#include "wlan_qct_wda.h"
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053096#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070097#include "wlan_hdd_dev_pwr.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +053098#include "qwlan_version.h"
c_manjeecfd1efb2015-09-25 19:32:34 +053099#include "wlan_logging_sock_svc.h"
Agrawal Ashishcfe83282016-09-29 13:03:45 +0530100#include "wlan_hdd_misc.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +0530101
Jeff Johnson295189b2012-06-20 16:38:30 -0700102
103#define g_mode_rates_size (12)
104#define a_mode_rates_size (8)
105#define FREQ_BASE_80211G (2407)
106#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700107#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530108#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700109#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800110 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700111
112#define HDD2GHZCHAN(freq, chan, flag) { \
113 .band = IEEE80211_BAND_2GHZ, \
114 .center_freq = (freq), \
115 .hw_value = (chan),\
116 .flags = (flag), \
117 .max_antenna_gain = 0 ,\
118 .max_power = 30, \
119}
120
121#define HDD5GHZCHAN(freq, chan, flag) { \
122 .band = IEEE80211_BAND_5GHZ, \
123 .center_freq = (freq), \
124 .hw_value = (chan),\
125 .flags = (flag), \
126 .max_antenna_gain = 0 ,\
127 .max_power = 30, \
128}
129
130#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
131{\
132 .bitrate = rate, \
133 .hw_value = rate_id, \
134 .flags = flag, \
135}
136
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530137#ifdef WLAN_FEATURE_VOWIFI_11R
138#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
139#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
140#endif
141
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530142#define HDD_CHANNEL_14 14
Dasari Srinivase18b2cf2014-10-28 17:09:42 +0530143#define WLAN_HDD_MAX_FEATURE_SET 8
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530144
Sunil Duttc69bccb2014-05-26 21:30:20 +0530145#ifdef WLAN_FEATURE_LINK_LAYER_STATS
146/*
147 * Used to allocate the size of 4096 for the link layer stats.
148 * The size of 4096 is considered assuming that all data per
149 * respective event fit with in the limit.Please take a call
150 * on the limit based on the data requirements on link layer
151 * statistics.
152 */
153#define LL_STATS_EVENT_BUF_SIZE 4096
154#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +0530155#ifdef WLAN_FEATURE_EXTSCAN
156/*
157 * Used to allocate the size of 4096 for the EXTScan NL data.
158 * The size of 4096 is considered assuming that all data per
159 * respective event fit with in the limit.Please take a call
160 * on the limit based on the data requirements.
161 */
162
163#define EXTSCAN_EVENT_BUF_SIZE 4096
164#define EXTSCAN_MAX_CACHED_RESULTS_PER_IND 32
165#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +0530166
Atul Mittal115287b2014-07-08 13:26:33 +0530167/*EXT TDLS*/
168/*
169 * Used to allocate the size of 4096 for the TDLS.
170 * The size of 4096 is considered assuming that all data per
171 * respective event fit with in the limit.Please take a call
172 * on the limit based on the data requirements on link layer
173 * statistics.
174 */
175#define EXTTDLS_EVENT_BUF_SIZE 4096
176
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +0530177/*
178 * Values for Mac spoofing feature
179 *
180 */
181#define MAC_ADDR_SPOOFING_FW_HOST_DISABLE 0
182#define MAC_ADDR_SPOOFING_FW_HOST_ENABLE 1
183#define MAC_ADDR_SPOOFING_FW_ENABLE_HOST_DISABLE 2
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +0530184#define MAC_ADDR_SPOOFING_DEFER_INTERVAL 10 //in ms
185
Anurag Chouhan343af7e2016-12-16 13:11:19 +0530186/*
187 * max_sched_scan_plans defined to 10
188 */
189#define MAX_SCHED_SCAN_PLANS 10
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +0530190
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530191static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700192{
193 WLAN_CIPHER_SUITE_WEP40,
194 WLAN_CIPHER_SUITE_WEP104,
195 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800196#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700197#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
198 WLAN_CIPHER_SUITE_KRK,
199 WLAN_CIPHER_SUITE_CCMP,
200#else
201 WLAN_CIPHER_SUITE_CCMP,
202#endif
203#ifdef FEATURE_WLAN_WAPI
204 WLAN_CIPHER_SUITE_SMS4,
205#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700206#ifdef WLAN_FEATURE_11W
207 WLAN_CIPHER_SUITE_AES_CMAC,
208#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700209};
210
211static inline int is_broadcast_ether_addr(const u8 *addr)
212{
213 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
214 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
215}
216
Agrawal Ashish97dec502015-11-26 20:20:58 +0530217const static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530218{
Jeff Johnson295189b2012-06-20 16:38:30 -0700219 HDD2GHZCHAN(2412, 1, 0) ,
220 HDD2GHZCHAN(2417, 2, 0) ,
221 HDD2GHZCHAN(2422, 3, 0) ,
222 HDD2GHZCHAN(2427, 4, 0) ,
223 HDD2GHZCHAN(2432, 5, 0) ,
224 HDD2GHZCHAN(2437, 6, 0) ,
225 HDD2GHZCHAN(2442, 7, 0) ,
226 HDD2GHZCHAN(2447, 8, 0) ,
227 HDD2GHZCHAN(2452, 9, 0) ,
228 HDD2GHZCHAN(2457, 10, 0) ,
229 HDD2GHZCHAN(2462, 11, 0) ,
230 HDD2GHZCHAN(2467, 12, 0) ,
231 HDD2GHZCHAN(2472, 13, 0) ,
232 HDD2GHZCHAN(2484, 14, 0) ,
233};
234
Agrawal Ashish97dec502015-11-26 20:20:58 +0530235const static struct ieee80211_channel hdd_channels_5_GHZ[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700236{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700237 HDD5GHZCHAN(4920, 240, 0) ,
238 HDD5GHZCHAN(4940, 244, 0) ,
239 HDD5GHZCHAN(4960, 248, 0) ,
240 HDD5GHZCHAN(4980, 252, 0) ,
241 HDD5GHZCHAN(5040, 208, 0) ,
242 HDD5GHZCHAN(5060, 212, 0) ,
243 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700244 HDD5GHZCHAN(5180, 36, 0) ,
245 HDD5GHZCHAN(5200, 40, 0) ,
246 HDD5GHZCHAN(5220, 44, 0) ,
247 HDD5GHZCHAN(5240, 48, 0) ,
248 HDD5GHZCHAN(5260, 52, 0) ,
249 HDD5GHZCHAN(5280, 56, 0) ,
250 HDD5GHZCHAN(5300, 60, 0) ,
251 HDD5GHZCHAN(5320, 64, 0) ,
252 HDD5GHZCHAN(5500,100, 0) ,
253 HDD5GHZCHAN(5520,104, 0) ,
254 HDD5GHZCHAN(5540,108, 0) ,
255 HDD5GHZCHAN(5560,112, 0) ,
256 HDD5GHZCHAN(5580,116, 0) ,
257 HDD5GHZCHAN(5600,120, 0) ,
258 HDD5GHZCHAN(5620,124, 0) ,
259 HDD5GHZCHAN(5640,128, 0) ,
260 HDD5GHZCHAN(5660,132, 0) ,
261 HDD5GHZCHAN(5680,136, 0) ,
262 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800263#ifdef FEATURE_WLAN_CH144
264 HDD5GHZCHAN(5720,144, 0) ,
265#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700266 HDD5GHZCHAN(5745,149, 0) ,
267 HDD5GHZCHAN(5765,153, 0) ,
268 HDD5GHZCHAN(5785,157, 0) ,
269 HDD5GHZCHAN(5805,161, 0) ,
270 HDD5GHZCHAN(5825,165, 0) ,
271};
272
273static struct ieee80211_rate g_mode_rates[] =
274{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530275 HDD_G_MODE_RATETAB(10, 0x1, 0),
276 HDD_G_MODE_RATETAB(20, 0x2, 0),
277 HDD_G_MODE_RATETAB(55, 0x4, 0),
278 HDD_G_MODE_RATETAB(110, 0x8, 0),
279 HDD_G_MODE_RATETAB(60, 0x10, 0),
280 HDD_G_MODE_RATETAB(90, 0x20, 0),
281 HDD_G_MODE_RATETAB(120, 0x40, 0),
282 HDD_G_MODE_RATETAB(180, 0x80, 0),
283 HDD_G_MODE_RATETAB(240, 0x100, 0),
284 HDD_G_MODE_RATETAB(360, 0x200, 0),
285 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700286 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530287};
Jeff Johnson295189b2012-06-20 16:38:30 -0700288
289static struct ieee80211_rate a_mode_rates[] =
290{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530291 HDD_G_MODE_RATETAB(60, 0x10, 0),
292 HDD_G_MODE_RATETAB(90, 0x20, 0),
293 HDD_G_MODE_RATETAB(120, 0x40, 0),
294 HDD_G_MODE_RATETAB(180, 0x80, 0),
295 HDD_G_MODE_RATETAB(240, 0x100, 0),
296 HDD_G_MODE_RATETAB(360, 0x200, 0),
297 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700298 HDD_G_MODE_RATETAB(540, 0x800, 0),
299};
300
301static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
302{
Agrawal Ashish97dec502015-11-26 20:20:58 +0530303 .channels = NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700304 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
305 .band = IEEE80211_BAND_2GHZ,
306 .bitrates = g_mode_rates,
307 .n_bitrates = g_mode_rates_size,
308 .ht_cap.ht_supported = 1,
309 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
310 | IEEE80211_HT_CAP_GRN_FLD
311 | IEEE80211_HT_CAP_DSSSCCK40
312 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
313 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
314 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
315 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
316 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
317 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
318};
319
Jeff Johnson295189b2012-06-20 16:38:30 -0700320static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
321{
Agrawal Ashish97dec502015-11-26 20:20:58 +0530322 .channels = NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700323 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
324 .band = IEEE80211_BAND_5GHZ,
325 .bitrates = a_mode_rates,
326 .n_bitrates = a_mode_rates_size,
327 .ht_cap.ht_supported = 1,
328 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
329 | IEEE80211_HT_CAP_GRN_FLD
330 | IEEE80211_HT_CAP_DSSSCCK40
331 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
332 | IEEE80211_HT_CAP_SGI_40
333 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
334 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
335 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
336 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
337 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
338 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
339};
340
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530341/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700342 TX/RX direction for each kind of interface */
343static const struct ieee80211_txrx_stypes
344wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
345 [NL80211_IFTYPE_STATION] = {
346 .tx = 0xffff,
347 .rx = BIT(SIR_MAC_MGMT_ACTION) |
348 BIT(SIR_MAC_MGMT_PROBE_REQ),
349 },
350 [NL80211_IFTYPE_AP] = {
351 .tx = 0xffff,
352 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
353 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
354 BIT(SIR_MAC_MGMT_PROBE_REQ) |
355 BIT(SIR_MAC_MGMT_DISASSOC) |
356 BIT(SIR_MAC_MGMT_AUTH) |
357 BIT(SIR_MAC_MGMT_DEAUTH) |
358 BIT(SIR_MAC_MGMT_ACTION),
359 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700360 [NL80211_IFTYPE_ADHOC] = {
361 .tx = 0xffff,
362 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
363 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
364 BIT(SIR_MAC_MGMT_PROBE_REQ) |
365 BIT(SIR_MAC_MGMT_DISASSOC) |
366 BIT(SIR_MAC_MGMT_AUTH) |
367 BIT(SIR_MAC_MGMT_DEAUTH) |
368 BIT(SIR_MAC_MGMT_ACTION),
369 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700370 [NL80211_IFTYPE_P2P_CLIENT] = {
371 .tx = 0xffff,
372 .rx = BIT(SIR_MAC_MGMT_ACTION) |
373 BIT(SIR_MAC_MGMT_PROBE_REQ),
374 },
375 [NL80211_IFTYPE_P2P_GO] = {
376 /* This is also same as for SoftAP */
377 .tx = 0xffff,
378 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
379 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
380 BIT(SIR_MAC_MGMT_PROBE_REQ) |
381 BIT(SIR_MAC_MGMT_DISASSOC) |
382 BIT(SIR_MAC_MGMT_AUTH) |
383 BIT(SIR_MAC_MGMT_DEAUTH) |
384 BIT(SIR_MAC_MGMT_ACTION),
385 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700386};
387
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800388#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800389static const struct ieee80211_iface_limit
390wlan_hdd_iface_limit[] = {
391 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800392 /* max = 3 ; Our driver create two interfaces during driver init
393 * wlan0 and p2p0 interfaces. p2p0 is considered as station
394 * interface until a group is formed. In JB architecture, once the
395 * group is formed, interface type of p2p0 is changed to P2P GO or
396 * Client.
397 * When supplicant remove the group, it first issue a set interface
398 * cmd to change the mode back to Station. In JB this works fine as
399 * we advertize two station type interface during driver init.
400 * Some vendors create separate interface for P2P GO/Client,
401 * after group formation(Third one). But while group remove
402 * supplicant first tries to change the mode(3rd interface) to STATION
403 * But as we advertized only two sta type interfaces nl80211 was
404 * returning error for the third one which was leading to failure in
405 * delete interface. Ideally while removing the group, supplicant
406 * should not try to change the 3rd interface mode to Station type.
407 * Till we get a fix in wpa_supplicant, we advertize max STA
408 * interface type to 3
409 */
410 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800411 .types = BIT(NL80211_IFTYPE_STATION),
412 },
413 {
414 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700415 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800416 },
417 {
418 .max = 1,
419 .types = BIT(NL80211_IFTYPE_P2P_GO) |
420 BIT(NL80211_IFTYPE_P2P_CLIENT),
421 },
422};
423
424/* By default, only single channel concurrency is allowed */
425static struct ieee80211_iface_combination
426wlan_hdd_iface_combination = {
427 .limits = wlan_hdd_iface_limit,
428 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800429 /*
430 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
431 * and p2p0 interfaces during driver init
432 * Some vendors create separate interface for P2P operations.
433 * wlan0: STA interface
434 * p2p0: P2P Device interface, action frames goes
435 * through this interface.
436 * p2p-xx: P2P interface, After GO negotiation this interface is
437 * created for p2p operations(GO/CLIENT interface).
438 */
439 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800440 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
441 .beacon_int_infra_match = false,
442};
443#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800444
Jeff Johnson295189b2012-06-20 16:38:30 -0700445static struct cfg80211_ops wlan_hdd_cfg80211_ops;
446
447/* Data rate 100KBPS based on IE Index */
448struct index_data_rate_type
449{
450 v_U8_t beacon_rate_index;
451 v_U16_t supported_rate[4];
452};
453
454/* 11B, 11G Rate table include Basic rate and Extended rate
455 The IDX field is the rate index
456 The HI field is the rate when RSSI is strong or being ignored
457 (in this case we report actual rate)
458 The MID field is the rate when RSSI is moderate
459 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
460 The LO field is the rate when RSSI is low
461 (in this case we don't report rates, actual current rate used)
462 */
463static const struct
464{
465 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700466 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700467} supported_data_rate[] =
468{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700469/* IDX HI HM LM LO (RSSI-based index */
470 {2, { 10, 10, 10, 0}},
471 {4, { 20, 20, 10, 0}},
472 {11, { 55, 20, 10, 0}},
473 {12, { 60, 55, 20, 0}},
474 {18, { 90, 55, 20, 0}},
475 {22, {110, 55, 20, 0}},
476 {24, {120, 90, 60, 0}},
477 {36, {180, 120, 60, 0}},
478 {44, {220, 180, 60, 0}},
479 {48, {240, 180, 90, 0}},
480 {66, {330, 180, 90, 0}},
481 {72, {360, 240, 90, 0}},
482 {96, {480, 240, 120, 0}},
483 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700484};
485
486/* MCS Based rate table */
487static struct index_data_rate_type supported_mcs_rate[] =
488{
489/* MCS L20 L40 S20 S40 */
490 {0, {65, 135, 72, 150}},
491 {1, {130, 270, 144, 300}},
492 {2, {195, 405, 217, 450}},
493 {3, {260, 540, 289, 600}},
494 {4, {390, 810, 433, 900}},
495 {5, {520, 1080, 578, 1200}},
496 {6, {585, 1215, 650, 1350}},
497 {7, {650, 1350, 722, 1500}}
498};
499
Leo Chang6f8870f2013-03-26 18:11:36 -0700500#ifdef WLAN_FEATURE_11AC
501
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530502#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700503
504struct index_vht_data_rate_type
505{
506 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530507 v_U16_t supported_VHT80_rate[2];
508 v_U16_t supported_VHT40_rate[2];
509 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700510};
511
512typedef enum
513{
514 DATA_RATE_11AC_MAX_MCS_7,
515 DATA_RATE_11AC_MAX_MCS_8,
516 DATA_RATE_11AC_MAX_MCS_9,
517 DATA_RATE_11AC_MAX_MCS_NA
518} eDataRate11ACMaxMcs;
519
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530520/* SSID broadcast type */
521typedef enum eSSIDBcastType
522{
523 eBCAST_UNKNOWN = 0,
524 eBCAST_NORMAL = 1,
525 eBCAST_HIDDEN = 2,
526} tSSIDBcastType;
527
Leo Chang6f8870f2013-03-26 18:11:36 -0700528/* MCS Based VHT rate table */
529static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
530{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530531/* MCS L80 S80 L40 S40 L20 S40*/
532 {0, {293, 325}, {135, 150}, {65, 72}},
533 {1, {585, 650}, {270, 300}, {130, 144}},
534 {2, {878, 975}, {405, 450}, {195, 217}},
535 {3, {1170, 1300}, {540, 600}, {260, 289}},
536 {4, {1755, 1950}, {810, 900}, {390, 433}},
537 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
538 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
539 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
540 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
541 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700542};
543#endif /* WLAN_FEATURE_11AC */
544
c_hpothu79aab322014-07-14 21:11:01 +0530545/*array index points to MCS and array value points respective rssi*/
546static int rssiMcsTbl[][10] =
547{
548/*MCS 0 1 2 3 4 5 6 7 8 9*/
549 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
550 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
551 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
552};
553
Jeff Johnson295189b2012-06-20 16:38:30 -0700554extern struct net_device_ops net_ops_struct;
Dasari Srinivas7875a302014-09-26 17:50:57 +0530555#ifdef FEATURE_WLAN_SCAN_PNO
556static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
557#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700558
Leo Chang9056f462013-08-01 19:21:11 -0700559#ifdef WLAN_NL80211_TESTMODE
560enum wlan_hdd_tm_attr
561{
562 WLAN_HDD_TM_ATTR_INVALID = 0,
563 WLAN_HDD_TM_ATTR_CMD = 1,
564 WLAN_HDD_TM_ATTR_DATA = 2,
565 WLAN_HDD_TM_ATTR_TYPE = 3,
566 /* keep last */
567 WLAN_HDD_TM_ATTR_AFTER_LAST,
568 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
569};
570
571enum wlan_hdd_tm_cmd
572{
573 WLAN_HDD_TM_CMD_WLAN_HB = 1,
574};
575
576#define WLAN_HDD_TM_DATA_MAX_LEN 5000
577
578static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
579{
580 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
581 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
582 .len = WLAN_HDD_TM_DATA_MAX_LEN },
583};
584#endif /* WLAN_NL80211_TESTMODE */
585
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800586#ifdef FEATURE_WLAN_CH_AVOID
587/*
588 * FUNCTION: wlan_hdd_send_avoid_freq_event
589 * This is called when wlan driver needs to send vendor specific
590 * avoid frequency range event to userspace
591 */
592int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
593 tHddAvoidFreqList *pAvoidFreqList)
594{
595 struct sk_buff *vendor_event;
596
597 ENTER();
598
599 if (!pHddCtx)
600 {
601 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
602 "%s: HDD context is null", __func__);
603 return -1;
604 }
605
606 if (!pAvoidFreqList)
607 {
608 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
609 "%s: pAvoidFreqList is null", __func__);
610 return -1;
611 }
612
613 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530614#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
615 NULL,
616#endif
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800617 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530618 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800619 GFP_KERNEL);
620 if (!vendor_event)
621 {
622 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
623 "%s: cfg80211_vendor_event_alloc failed", __func__);
624 return -1;
625 }
626
627 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
628 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
629
630 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
631
632 EXIT();
633 return 0;
634}
635#endif /* FEATURE_WLAN_CH_AVOID */
636
Srinivas Dasari030bad32015-02-18 23:23:54 +0530637/*
638 * FUNCTION: __wlan_hdd_cfg80211_nan_request
639 * This is called when wlan driver needs to send vendor specific
640 * nan request event.
641 */
642static int __wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
643 struct wireless_dev *wdev,
644 const void *data, int data_len)
645{
646 tNanRequestReq nan_req;
647 VOS_STATUS status;
648 int ret_val = -1;
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530649 struct net_device *dev = wdev->netdev;
650 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
651 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530652 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
653
654 if (0 == data_len)
655 {
656 hddLog(VOS_TRACE_LEVEL_ERROR,
657 FL("NAN - Invalid Request, length = 0"));
658 return ret_val;
659 }
660
661 if (NULL == data)
662 {
663 hddLog(VOS_TRACE_LEVEL_ERROR,
664 FL("NAN - Invalid Request, data is NULL"));
665 return ret_val;
666 }
667
668 status = wlan_hdd_validate_context(pHddCtx);
669 if (0 != status)
670 {
671 hddLog(VOS_TRACE_LEVEL_ERROR,
672 FL("HDD context is not valid"));
673 return -EINVAL;
674 }
675
676 hddLog(LOG1, FL("Received NAN command"));
677 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
678 (tANI_U8 *)data, data_len);
679
680 /* check the NAN Capability */
681 if (TRUE != sme_IsFeatureSupportedByFW(NAN))
682 {
683 hddLog(VOS_TRACE_LEVEL_ERROR,
684 FL("NAN is not supported by Firmware"));
685 return -EINVAL;
686 }
687
688 nan_req.request_data_len = data_len;
689 nan_req.request_data = data;
690
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530691 status = sme_NanRequest(hHal, &nan_req, pAdapter->sessionId);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530692 if (VOS_STATUS_SUCCESS == status)
693 {
694 ret_val = 0;
695 }
696 return ret_val;
697}
698
699/*
700 * FUNCTION: wlan_hdd_cfg80211_nan_request
701 * Wrapper to protect the nan vendor command from ssr
702 */
703static int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
704 struct wireless_dev *wdev,
705 const void *data, int data_len)
706{
707 int ret;
708
709 vos_ssr_protect(__func__);
710 ret = __wlan_hdd_cfg80211_nan_request(wiphy, wdev, data, data_len);
711 vos_ssr_unprotect(__func__);
712
713 return ret;
714}
715
716/*
717 * FUNCTION: wlan_hdd_cfg80211_nan_callback
718 * This is a callback function and it gets called
719 * when we need to report nan response event to
720 * upper layers.
721 */
722static void wlan_hdd_cfg80211_nan_callback(void* ctx, tSirNanEvent* msg)
723{
724 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
725 struct sk_buff *vendor_event;
726 int status;
727 tSirNanEvent *data;
728
729 ENTER();
730 if (NULL == msg)
731 {
732 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
733 FL(" msg received here is null"));
734 return;
735 }
736 data = msg;
737
738 status = wlan_hdd_validate_context(pHddCtx);
739
740 if (0 != status)
741 {
742 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
743 FL("HDD context is not valid"));
744 return;
745 }
746
747 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530748#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
749 NULL,
750#endif
Srinivas Dasari030bad32015-02-18 23:23:54 +0530751 data->event_data_len +
752 NLMSG_HDRLEN,
753 QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX,
754 GFP_KERNEL);
755
756 if (!vendor_event)
757 {
758 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
759 FL("cfg80211_vendor_event_alloc failed"));
760 return;
761 }
762 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN,
763 data->event_data_len, data->event_data))
764 {
765 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
766 FL("QCA_WLAN_VENDOR_ATTR_NAN put fail"));
767 kfree_skb(vendor_event);
768 return;
769 }
770 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
771 EXIT();
772}
773
774/*
775 * FUNCTION: wlan_hdd_cfg80211_nan_init
776 * This function is called to register the callback to sme layer
777 */
778inline void wlan_hdd_cfg80211_nan_init(hdd_context_t *pHddCtx)
779{
780 sme_NanRegisterCallback(pHddCtx->hHal, wlan_hdd_cfg80211_nan_callback);
781}
782
Anurag Chouhanfcd20172017-07-19 17:25:19 +0530783/*
784 * define short names for the global vendor params
785 * used by __wlan_hdd_cfg80211_get_station_cmd()
786 */
787#define STATION_INVALID \
788 QCA_WLAN_VENDOR_ATTR_GET_STATION_INVALID
789#define STATION_INFO \
790 QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO
791#define STATION_ASSOC_FAIL_REASON \
792 QCA_WLAN_VENDOR_ATTR_GET_STATION_ASSOC_FAIL_REASON
793#define STATION_MAX \
794 QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX
795
796static const struct nla_policy
797hdd_get_station_policy[STATION_MAX + 1] = {
798 [STATION_INFO] = {.type = NLA_FLAG},
799 [STATION_ASSOC_FAIL_REASON] = {.type = NLA_FLAG},
800};
801
802/**
803 * hdd_get_station_assoc_fail() - Handle get station assoc fail
804 * @hdd_ctx: HDD context within host driver
805 * @wdev: wireless device
806 *
807 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION_ASSOC_FAIL.
808 * Validate cmd attributes and send the station info to upper layers.
809 *
810 * Return: Success(0) or reason code for failure
811 */
812static int hdd_get_station_assoc_fail(hdd_context_t *hdd_ctx,
813 hdd_adapter_t *adapter)
814{
815 struct sk_buff *skb = NULL;
816 uint32_t nl_buf_len;
817 hdd_station_ctx_t *hdd_sta_ctx;
818
819 nl_buf_len = NLMSG_HDRLEN;
820 nl_buf_len += sizeof(uint32_t);
821 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
822
823 if (!skb) {
824 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"cfg80211_vendor_cmd_alloc_reply_skb failed");
825 return -ENOMEM;
826 }
827
828 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
829
830 if (nla_put_u32(skb, INFO_ASSOC_FAIL_REASON,
831 hdd_sta_ctx->conn_info.assoc_status_code)) {
832 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
833 goto fail;
834 }
835 return cfg80211_vendor_cmd_reply(skb);
836fail:
837 if (skb)
838 kfree_skb(skb);
839 return -EINVAL;
840}
841
842/**
843 * hdd_map_auth_type() - transform auth type specific to
844 * vendor command
845 * @auth_type: csr auth type
846 *
847 * Return: Success(0) or reason code for failure
848 */
849static int hdd_convert_auth_type(uint32_t auth_type)
850{
851 uint32_t ret_val;
852
853 switch (auth_type) {
854 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
855 ret_val = QCA_WLAN_AUTH_TYPE_OPEN;
856 break;
857 case eCSR_AUTH_TYPE_SHARED_KEY:
858 ret_val = QCA_WLAN_AUTH_TYPE_SHARED;
859 break;
860 case eCSR_AUTH_TYPE_WPA:
861 ret_val = QCA_WLAN_AUTH_TYPE_WPA;
862 break;
863 case eCSR_AUTH_TYPE_WPA_PSK:
864 ret_val = QCA_WLAN_AUTH_TYPE_WPA_PSK;
865 break;
866 case eCSR_AUTH_TYPE_AUTOSWITCH:
867 ret_val = QCA_WLAN_AUTH_TYPE_AUTOSWITCH;
868 break;
869 case eCSR_AUTH_TYPE_WPA_NONE:
870 ret_val = QCA_WLAN_AUTH_TYPE_WPA_NONE;
871 break;
872 case eCSR_AUTH_TYPE_RSN:
873 ret_val = QCA_WLAN_AUTH_TYPE_RSN;
874 break;
875 case eCSR_AUTH_TYPE_RSN_PSK:
876 ret_val = QCA_WLAN_AUTH_TYPE_RSN_PSK;
877 break;
878 case eCSR_AUTH_TYPE_FT_RSN:
879 ret_val = QCA_WLAN_AUTH_TYPE_FT;
880 break;
881 case eCSR_AUTH_TYPE_FT_RSN_PSK:
882 ret_val = QCA_WLAN_AUTH_TYPE_FT_PSK;
883 break;
884 case eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE:
885 ret_val = QCA_WLAN_AUTH_TYPE_WAI;
886 break;
887 case eCSR_AUTH_TYPE_WAPI_WAI_PSK:
888 ret_val = QCA_WLAN_AUTH_TYPE_WAI_PSK;
889 break;
890#ifdef FEATURE_WLAN_ESE
891 case eCSR_AUTH_TYPE_CCKM_WPA:
892 ret_val = QCA_WLAN_AUTH_TYPE_CCKM_WPA;
893 break;
894 case eCSR_AUTH_TYPE_CCKM_RSN:
895 ret_val = QCA_WLAN_AUTH_TYPE_CCKM_RSN;
896 break;
897#endif
898 case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
899 ret_val = QCA_WLAN_AUTH_TYPE_SHA256_PSK;
900 break;
901 case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
902 ret_val = QCA_WLAN_AUTH_TYPE_SHA256;
903 break;
904 case eCSR_NUM_OF_SUPPORT_AUTH_TYPE:
905 case eCSR_AUTH_TYPE_FAILED:
906 case eCSR_AUTH_TYPE_NONE:
907 default:
908 ret_val = QCA_WLAN_AUTH_TYPE_INVALID;
909 break;
910 }
911 return ret_val;
912}
913
914/**
915 * hdd_map_dot_11_mode() - transform dot11mode type specific to
916 * vendor command
917 * @dot11mode: dot11mode
918 *
919 * Return: Success(0) or reason code for failure
920 */
921static int hdd_convert_dot11mode(uint32_t dot11mode)
922{
923 uint32_t ret_val;
924
925 switch (dot11mode) {
926 case eCSR_CFG_DOT11_MODE_11A:
927 ret_val = QCA_WLAN_802_11_MODE_11A;
928 break;
929 case eCSR_CFG_DOT11_MODE_11B:
930 ret_val = QCA_WLAN_802_11_MODE_11B;
931 break;
932 case eCSR_CFG_DOT11_MODE_11G:
933 ret_val = QCA_WLAN_802_11_MODE_11G;
934 break;
935 case eCSR_CFG_DOT11_MODE_11N:
936 ret_val = QCA_WLAN_802_11_MODE_11N;
937 break;
938 case eCSR_CFG_DOT11_MODE_11AC:
939 ret_val = QCA_WLAN_802_11_MODE_11AC;
940 break;
941 case eCSR_CFG_DOT11_MODE_AUTO:
942 case eCSR_CFG_DOT11_MODE_ABG:
943 default:
944 ret_val = QCA_WLAN_802_11_MODE_INVALID;
945 }
946 return ret_val;
947}
948
949/**
950 * hdd_add_tx_bitrate() - add tx bitrate attribute
951 * @skb: pointer to sk buff
952 * @hdd_sta_ctx: pointer to hdd station context
953 * @idx: attribute index
954 *
955 * Return: Success(0) or reason code for failure
956 */
957static int32_t hdd_add_tx_bitrate(struct sk_buff *skb,
958 hdd_station_ctx_t *hdd_sta_ctx,
959 int idx)
960{
961 struct nlattr *nla_attr;
962 uint32_t bitrate, bitrate_compat;
963
964 nla_attr = nla_nest_start(skb, idx);
965 if (!nla_attr)
966 goto fail;
967 /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
968 bitrate = cfg80211_calculate_bitrate(&hdd_sta_ctx->conn_info.txrate);
969
970 /* report 16-bit bitrate only if we can */
971 bitrate_compat = bitrate < (1UL << 16) ? bitrate : 0;
972 if (bitrate > 0 &&
973 nla_put_u32(skb, NL80211_RATE_INFO_BITRATE32, bitrate)) {
974 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
975 goto fail;
976 }
977 if (bitrate_compat > 0 &&
978 nla_put_u16(skb, NL80211_RATE_INFO_BITRATE, bitrate_compat)) {
979 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
980 goto fail;
981 }
982 if (nla_put_u8(skb, NL80211_RATE_INFO_VHT_NSS,
983 hdd_sta_ctx->conn_info.txrate.nss)) {
984 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
985 goto fail;
986 }
987 nla_nest_end(skb, nla_attr);
988 return 0;
989fail:
990 return -EINVAL;
991}
992
993/**
994 * hdd_add_sta_info() - add station info attribute
995 * @skb: pointer to sk buff
996 * @hdd_sta_ctx: pointer to hdd station context
997 * @idx: attribute index
998 *
999 * Return: Success(0) or reason code for failure
1000 */
1001static int32_t hdd_add_sta_info(struct sk_buff *skb,
1002 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1003{
1004 struct nlattr *nla_attr;
1005
1006 nla_attr = nla_nest_start(skb, idx);
1007 if (!nla_attr)
1008 goto fail;
1009 if (nla_put_u8(skb, NL80211_STA_INFO_SIGNAL,
1010 (hdd_sta_ctx->conn_info.signal + 100))) {
1011 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1012 goto fail;
1013 }
1014 if (hdd_add_tx_bitrate(skb, hdd_sta_ctx, NL80211_STA_INFO_TX_BITRATE))
1015 goto fail;
1016 nla_nest_end(skb, nla_attr);
1017 return 0;
1018fail:
1019 return -EINVAL;
1020}
1021
1022/**
1023 * hdd_add_survey_info() - add survey info attribute
1024 * @skb: pointer to sk buff
1025 * @hdd_sta_ctx: pointer to hdd station context
1026 * @idx: attribute index
1027 *
1028 * Return: Success(0) or reason code for failure
1029 */
1030static int32_t hdd_add_survey_info(struct sk_buff *skb,
1031 hdd_station_ctx_t *hdd_sta_ctx,
1032 int idx)
1033{
1034 struct nlattr *nla_attr;
1035
1036 nla_attr = nla_nest_start(skb, idx);
1037 if (!nla_attr)
1038 goto fail;
1039 if (nla_put_u32(skb, NL80211_SURVEY_INFO_FREQUENCY,
1040 hdd_sta_ctx->conn_info.freq) ||
1041 nla_put_u8(skb, NL80211_SURVEY_INFO_NOISE,
1042 (hdd_sta_ctx->conn_info.noise + 100))) {
1043 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1044 goto fail;
1045 }
1046 nla_nest_end(skb, nla_attr);
1047 return 0;
1048fail:
1049 return -EINVAL;
1050}
1051
1052/**
1053 * hdd_add_link_standard_info() - add link info attribute
1054 * @skb: pointer to sk buff
1055 * @hdd_sta_ctx: pointer to hdd station context
1056 * @idx: attribute index
1057 *
1058 * Return: Success(0) or reason code for failure
1059 */
1060static int32_t
1061hdd_add_link_standard_info(struct sk_buff *skb,
1062 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1063{
1064 struct nlattr *nla_attr;
1065
1066 nla_attr = nla_nest_start(skb, idx);
1067 if (!nla_attr)
1068 goto fail;
1069 if (nla_put(skb,
1070 NL80211_ATTR_SSID,
1071 hdd_sta_ctx->conn_info.SSID.SSID.length,
1072 hdd_sta_ctx->conn_info.SSID.SSID.ssId)) {
1073 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1074 goto fail;
1075 }
1076 if (hdd_add_survey_info(skb, hdd_sta_ctx, NL80211_ATTR_SURVEY_INFO))
1077 goto fail;
1078 if (hdd_add_sta_info(skb, hdd_sta_ctx, NL80211_ATTR_STA_INFO))
1079 goto fail;
1080 nla_nest_end(skb, nla_attr);
1081 return 0;
1082fail:
1083 return -EINVAL;
1084}
1085
1086/**
1087 * hdd_add_ap_standard_info() - add ap info attribute
1088 * @skb: pointer to sk buff
1089 * @hdd_sta_ctx: pointer to hdd station context
1090 * @idx: attribute index
1091 *
1092 * Return: Success(0) or reason code for failure
1093 */
1094static int32_t
1095hdd_add_ap_standard_info(struct sk_buff *skb,
1096 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1097{
1098 struct nlattr *nla_attr;
1099
1100 nla_attr = nla_nest_start(skb, idx);
1101 if (!nla_attr)
1102 goto fail;
1103 if (hdd_sta_ctx->conn_info.conn_flag.vht_present)
1104 if (nla_put(skb, NL80211_ATTR_VHT_CAPABILITY,
1105 sizeof(hdd_sta_ctx->conn_info.vht_caps),
1106 &hdd_sta_ctx->conn_info.vht_caps)) {
1107 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1108 goto fail;
1109 }
1110 if (hdd_sta_ctx->conn_info.conn_flag.ht_present)
1111 if (nla_put(skb, NL80211_ATTR_HT_CAPABILITY,
1112 sizeof(hdd_sta_ctx->conn_info.ht_caps),
1113 &hdd_sta_ctx->conn_info.ht_caps)) {
1114 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1115 goto fail;
1116 }
1117 nla_nest_end(skb, nla_attr);
1118 return 0;
1119fail:
1120 return -EINVAL;
1121}
1122
1123/**
1124 * hdd_get_station_info() - send BSS information to supplicant
1125 * @hdd_ctx: pointer to hdd context
1126 * @adapter: pointer to adapter
1127 *
1128 * Return: 0 if success else error status
1129 */
1130static int hdd_get_station_info(hdd_context_t *hdd_ctx,
1131 hdd_adapter_t *adapter)
1132{
1133 struct sk_buff *skb = NULL;
1134 uint8_t *tmp_hs20 = NULL;
1135 uint32_t nl_buf_len;
1136 hdd_station_ctx_t *hdd_sta_ctx;
1137
1138 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
1139
1140 nl_buf_len = NLMSG_HDRLEN;
1141 nl_buf_len += sizeof(hdd_sta_ctx->conn_info.SSID.SSID.length) +
1142 sizeof(hdd_sta_ctx->conn_info.freq) +
1143 sizeof(hdd_sta_ctx->conn_info.noise) +
1144 sizeof(hdd_sta_ctx->conn_info.signal) +
1145 (sizeof(uint32_t) * 2) +
1146 sizeof(hdd_sta_ctx->conn_info.txrate.nss) +
1147 sizeof(hdd_sta_ctx->conn_info.roam_count) +
1148 sizeof(hdd_sta_ctx->conn_info.authType) +
1149 sizeof(hdd_sta_ctx->conn_info.dot11Mode);
1150 if (hdd_sta_ctx->conn_info.conn_flag.vht_present)
1151 nl_buf_len += sizeof(hdd_sta_ctx->conn_info.vht_caps);
1152 if (hdd_sta_ctx->conn_info.conn_flag.ht_present)
1153 nl_buf_len += sizeof(hdd_sta_ctx->conn_info.ht_caps);
1154 if (hdd_sta_ctx->conn_info.conn_flag.hs20_present) {
1155 tmp_hs20 = (uint8_t *)&(hdd_sta_ctx->conn_info.hs20vendor_ie);
1156 nl_buf_len += (sizeof(hdd_sta_ctx->conn_info.hs20vendor_ie) -
1157 1);
1158 }
1159 if (hdd_sta_ctx->conn_info.conn_flag.ht_op_present)
1160 nl_buf_len += sizeof(hdd_sta_ctx->conn_info.ht_operation);
1161 if (hdd_sta_ctx->conn_info.conn_flag.vht_op_present)
1162 nl_buf_len += sizeof(hdd_sta_ctx->conn_info.vht_operation);
1163
1164
1165 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
1166 if (!skb) {
1167 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"%s: %d cfg80211_vendor_cmd_alloc_reply_skb failed",
1168 __func__, __LINE__);
1169 return -ENOMEM;
1170 }
1171
1172 if (hdd_add_link_standard_info(skb, hdd_sta_ctx,
1173 LINK_INFO_STANDARD_NL80211_ATTR)) {
1174 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1175 goto fail;
1176 }
1177 if (hdd_add_ap_standard_info(skb, hdd_sta_ctx,
1178 AP_INFO_STANDARD_NL80211_ATTR)) {
1179 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1180 goto fail;
1181 }
1182 if (nla_put_u32(skb, INFO_ROAM_COUNT,
1183 hdd_sta_ctx->conn_info.roam_count) ||
1184 nla_put_u32(skb, INFO_AKM,
1185 hdd_convert_auth_type(
1186 hdd_sta_ctx->conn_info.authType)) ||
1187 nla_put_u32(skb, WLAN802_11_MODE,
1188 hdd_convert_dot11mode(
1189 hdd_sta_ctx->conn_info.dot11Mode))) {
1190 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1191 goto fail;
1192 }
1193 if (hdd_sta_ctx->conn_info.conn_flag.ht_op_present)
1194 if (nla_put(skb, HT_OPERATION,
1195 (sizeof(hdd_sta_ctx->conn_info.ht_operation)),
1196 &hdd_sta_ctx->conn_info.ht_operation)) {
1197 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1198 goto fail;
1199 }
1200 if (hdd_sta_ctx->conn_info.conn_flag.vht_op_present)
1201 if (nla_put(skb, VHT_OPERATION,
1202 (sizeof(hdd_sta_ctx->conn_info.vht_operation)),
1203 &hdd_sta_ctx->conn_info.vht_operation)) {
1204 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1205 goto fail;
1206 }
1207 if (hdd_sta_ctx->conn_info.conn_flag.hs20_present)
1208 if (nla_put(skb, AP_INFO_HS20_INDICATION,
1209 (sizeof(hdd_sta_ctx->conn_info.hs20vendor_ie) - 1),
1210 tmp_hs20 + 1)) {
1211 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1212 goto fail;
1213 }
1214
1215 return cfg80211_vendor_cmd_reply(skb);
1216fail:
1217 if (skb)
1218 kfree_skb(skb);
1219 return -EINVAL;
1220}
1221
1222/**
1223 * __hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
1224 * @wiphy: corestack handler
1225 * @wdev: wireless device
1226 * @data: data
1227 * @data_len: data length
1228 *
1229 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
1230 * Validate cmd attributes and send the station info to upper layers.
1231 *
1232 * Return: Success(0) or reason code for failure
1233 */
1234static int32_t
1235__hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
1236 struct wireless_dev *wdev,
1237 const void *data,
1238 int data_len)
1239{
1240 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
1241 struct net_device *dev = wdev->netdev;
1242 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
1243 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX + 1];
1244 int32_t status;
1245
1246 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"Enter");
1247 if (VOS_FTM_MODE == hdd_get_conparam()) {
1248 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"Command not allowed in FTM mode");
1249 status = -EPERM;
1250 goto out;
1251 }
1252
1253 status = wlan_hdd_validate_context(hdd_ctx);
1254 if (0 != status)
1255 goto out;
1256
1257
1258 status = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX,
1259 data, data_len, NULL);
1260 if (status) {
1261 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"Invalid ATTR");
1262 goto out;
1263 }
1264
1265 /* Parse and fetch Command Type*/
1266 if (tb[STATION_INFO]) {
1267 status = hdd_get_station_info(hdd_ctx, adapter);
1268 } else if (tb[STATION_ASSOC_FAIL_REASON]) {
1269 status = hdd_get_station_assoc_fail(hdd_ctx, adapter);
1270 } else {
1271 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"get station info cmd type failed");
1272 status = -EINVAL;
1273 goto out;
1274 }
1275 EXIT();
1276out:
1277 return status;
1278}
1279
1280/**
1281 * wlan_hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
1282 * @wiphy: corestack handler
1283 * @wdev: wireless device
1284 * @data: data
1285 * @data_len: data length
1286 *
1287 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
1288 * Validate cmd attributes and send the station info to upper layers.
1289 *
1290 * Return: Success(0) or reason code for failure
1291 */
1292static int32_t
1293hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
1294 struct wireless_dev *wdev,
1295 const void *data,
1296 int data_len)
1297{
1298 int ret;
1299
1300 vos_ssr_protect(__func__);
1301 ret = __hdd_cfg80211_get_station_cmd(wiphy, wdev, data, data_len);
1302 vos_ssr_unprotect(__func__);
1303
1304 return ret;
1305}
1306
1307/*
1308 * undef short names defined for get station command
1309 * used by __wlan_hdd_cfg80211_get_station_cmd()
1310 */
1311#undef STATION_INVALID
1312#undef STATION_INFO
1313#undef STATION_ASSOC_FAIL_REASON
1314#undef STATION_MAX
Srinivas Dasari030bad32015-02-18 23:23:54 +05301315
Sunil Duttc69bccb2014-05-26 21:30:20 +05301316#ifdef WLAN_FEATURE_LINK_LAYER_STATS
1317
1318static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
1319 struct sk_buff *vendor_event)
1320{
1321 if (nla_put_u8(vendor_event,
1322 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
1323 stats->rate.preamble) ||
1324 nla_put_u8(vendor_event,
1325 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
1326 stats->rate.nss) ||
1327 nla_put_u8(vendor_event,
1328 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
1329 stats->rate.bw) ||
1330 nla_put_u8(vendor_event,
1331 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
1332 stats->rate.rateMcsIdx) ||
1333 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
1334 stats->rate.bitrate ) ||
1335 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
1336 stats->txMpdu ) ||
1337 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
1338 stats->rxMpdu ) ||
1339 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
1340 stats->mpduLost ) ||
1341 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
1342 stats->retries) ||
1343 nla_put_u32(vendor_event,
1344 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
1345 stats->retriesShort ) ||
1346 nla_put_u32(vendor_event,
1347 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
1348 stats->retriesLong))
1349 {
1350 hddLog(VOS_TRACE_LEVEL_ERROR,
1351 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1352 return FALSE;
1353 }
1354 return TRUE;
1355}
1356
1357static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
1358 struct sk_buff *vendor_event)
1359{
1360 u32 i = 0;
1361 struct nlattr *rateInfo;
1362 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
1363 stats->type) ||
1364 nla_put(vendor_event,
1365 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
1366 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
1367 nla_put_u32(vendor_event,
1368 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
1369 stats->capabilities) ||
1370 nla_put_u32(vendor_event,
1371 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
1372 stats->numRate))
1373 {
1374 hddLog(VOS_TRACE_LEVEL_ERROR,
1375 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1376 goto error;
1377 }
1378
1379 rateInfo = nla_nest_start(vendor_event,
1380 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301381 if(!rateInfo)
1382 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301383 for (i = 0; i < stats->numRate; i++)
1384 {
1385 struct nlattr *rates;
1386 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
1387 stats->rateStats +
1388 (i * sizeof(tSirWifiRateStat)));
1389 rates = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301390 if(!rates)
1391 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301392
1393 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
1394 {
1395 hddLog(VOS_TRACE_LEVEL_ERROR,
1396 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1397 return FALSE;
1398 }
1399 nla_nest_end(vendor_event, rates);
1400 }
1401 nla_nest_end(vendor_event, rateInfo);
1402
1403 return TRUE;
1404error:
1405 return FALSE;
1406}
1407
1408static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
1409 struct sk_buff *vendor_event)
1410{
1411 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
1412 stats->ac ) ||
1413 nla_put_u32(vendor_event,
1414 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
1415 stats->txMpdu ) ||
1416 nla_put_u32(vendor_event,
1417 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
1418 stats->rxMpdu ) ||
1419 nla_put_u32(vendor_event,
1420 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
1421 stats->txMcast ) ||
1422 nla_put_u32(vendor_event,
1423 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
1424 stats->rxMcast ) ||
1425 nla_put_u32(vendor_event,
1426 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
1427 stats->rxAmpdu ) ||
1428 nla_put_u32(vendor_event,
1429 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
1430 stats->txAmpdu ) ||
1431 nla_put_u32(vendor_event,
1432 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
1433 stats->mpduLost )||
1434 nla_put_u32(vendor_event,
1435 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
1436 stats->retries ) ||
1437 nla_put_u32(vendor_event,
1438 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
1439 stats->retriesShort ) ||
1440 nla_put_u32(vendor_event,
1441 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
1442 stats->retriesLong ) ||
1443 nla_put_u32(vendor_event,
1444 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
1445 stats->contentionTimeMin ) ||
1446 nla_put_u32(vendor_event,
1447 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
1448 stats->contentionTimeMax ) ||
1449 nla_put_u32(vendor_event,
1450 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
1451 stats->contentionTimeAvg ) ||
1452 nla_put_u32(vendor_event,
1453 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
1454 stats->contentionNumSamples ))
1455 {
1456 hddLog(VOS_TRACE_LEVEL_ERROR,
1457 FL("QCA_WLAN_VENDOR_ATTR put fail") );
1458 return FALSE;
1459 }
1460 return TRUE;
1461}
1462
1463static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
1464 struct sk_buff *vendor_event)
1465{
Dino Myclec8f3f332014-07-21 16:48:27 +05301466 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301467 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
1468 nla_put(vendor_event,
1469 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
1470 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
1471 nla_put_u32(vendor_event,
1472 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
1473 stats->state ) ||
1474 nla_put_u32(vendor_event,
1475 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
1476 stats->roaming ) ||
1477 nla_put_u32(vendor_event,
1478 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
1479 stats->capabilities ) ||
1480 nla_put(vendor_event,
1481 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
1482 strlen(stats->ssid), stats->ssid) ||
1483 nla_put(vendor_event,
1484 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
1485 WNI_CFG_BSSID_LEN, stats->bssid) ||
1486 nla_put(vendor_event,
1487 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
1488 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
1489 nla_put(vendor_event,
1490 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
1491 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
1492 )
1493 {
1494 hddLog(VOS_TRACE_LEVEL_ERROR,
1495 FL("QCA_WLAN_VENDOR_ATTR put fail") );
1496 return FALSE;
1497 }
1498 return TRUE;
1499}
1500
Dino Mycle3b9536d2014-07-09 22:05:24 +05301501static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
1502 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301503 struct sk_buff *vendor_event)
1504{
1505 int i = 0;
1506 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301507 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1508 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05301509 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301510
Sunil Duttc69bccb2014-05-26 21:30:20 +05301511 if (FALSE == put_wifi_interface_info(
1512 &pWifiIfaceStat->info,
1513 vendor_event))
1514 {
1515 hddLog(VOS_TRACE_LEVEL_ERROR,
1516 FL("QCA_WLAN_VENDOR_ATTR put fail") );
1517 return FALSE;
1518
1519 }
Dino Mycle3b9536d2014-07-09 22:05:24 +05301520 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
1521 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
1522 if (NULL == pWifiIfaceStatTL)
1523 {
1524 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
1525 return FALSE;
1526 }
1527
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05301528 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
1529 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
1530 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
1531 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
1532
1533 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
1534 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
1535 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
1536 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301537
1538 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
1539 {
1540 if (VOS_STATUS_SUCCESS ==
1541 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1542 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
1543 {
1544 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
1545 * obtained from TL structure
1546 */
1547
1548 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
1549 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301550 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
1551
Srinivas Dasari98947432014-11-07 19:41:24 +05301552 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
1553 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
1554 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
1555 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
1556 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
1557 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
1558 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
1559 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301560
Srinivas Dasari98947432014-11-07 19:41:24 +05301561 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
1562 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
1563 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
1564 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
1565 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
1566 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
1567 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
1568 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301569
Srinivas Dasari98947432014-11-07 19:41:24 +05301570 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
1571 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
1572 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
1573 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
1574 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
1575 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
1576 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
1577 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301578 }
1579 else
1580 {
1581 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
1582 }
1583
Dino Mycle3b9536d2014-07-09 22:05:24 +05301584 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
1585 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
1586 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
1587 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
1588 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
1589 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
1590 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
1591 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
1592 }
1593 else
1594 {
1595 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
1596 }
1597
1598
Sunil Duttc69bccb2014-05-26 21:30:20 +05301599
1600 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301601 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1602 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_IFACE) ||
1603 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301604 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
1605 pWifiIfaceStat->beaconRx) ||
1606 nla_put_u32(vendor_event,
1607 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
1608 pWifiIfaceStat->mgmtRx) ||
1609 nla_put_u32(vendor_event,
1610 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
1611 pWifiIfaceStat->mgmtActionRx) ||
1612 nla_put_u32(vendor_event,
1613 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
1614 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301615 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301616 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
1617 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301618 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301619 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
1620 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301621 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301622 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
1623 pWifiIfaceStat->rssiAck))
1624 {
1625 hddLog(VOS_TRACE_LEVEL_ERROR,
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05301626 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1627 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301628 return FALSE;
1629 }
1630
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05301631#ifdef FEATURE_EXT_LL_STAT
1632 /*
1633 * Ensure when EXT_LL_STAT is supported by both host and fwr,
1634 * then host should send Leaky AP stats to upper layer,
1635 * otherwise no need to send these stats.
1636 */
1637 if(sme_IsFeatureSupportedByFW(EXT_LL_STAT) &&
1638 sme_IsFeatureSupportedByDriver(EXT_LL_STAT)
1639 )
1640 {
1641 hddLog(VOS_TRACE_LEVEL_INFO,
1642 FL("EXT_LL_STAT is supported by fwr and host %u %u %u %llu"),
1643 pWifiIfaceStat->leakyApStat.is_leaky_ap,
1644 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked,
1645 pWifiIfaceStat->leakyApStat.rx_leak_window,
1646 pWifiIfaceStat->leakyApStat.avg_bcn_spread);
1647 if (nla_put_u32(vendor_event,
1648 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_DETECTED,
1649 pWifiIfaceStat->leakyApStat.is_leaky_ap) ||
1650 nla_put_u32(vendor_event,
1651 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_AVG_NUM_FRAMES_LEAKED,
1652 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked) ||
1653 nla_put_u32(vendor_event,
1654 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_GUARD_TIME,
1655 pWifiIfaceStat->leakyApStat.rx_leak_window) ||
1656 nla_put_u64(vendor_event,
1657 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_AVERAGE_TSF_OFFSET,
1658 pWifiIfaceStat->leakyApStat.avg_bcn_spread))
1659 {
1660 hddLog(VOS_TRACE_LEVEL_ERROR,
1661 FL("EXT_LL_STAT put fail"));
1662 vos_mem_free(pWifiIfaceStatTL);
1663 return FALSE;
1664 }
1665 }
1666#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +05301667 wmmInfo = nla_nest_start(vendor_event,
1668 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301669 if(!wmmInfo)
1670 {
1671 vos_mem_free(pWifiIfaceStatTL);
1672 return FALSE;
1673 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301674 for (i = 0; i < WIFI_AC_MAX; i++)
1675 {
1676 struct nlattr *wmmStats;
1677 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301678 if(!wmmStats)
1679 {
1680 vos_mem_free(pWifiIfaceStatTL);
1681 return FALSE;
1682 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301683 if (FALSE == put_wifi_wmm_ac_stat(
1684 &pWifiIfaceStat->AccessclassStats[i],
1685 vendor_event))
1686 {
1687 hddLog(VOS_TRACE_LEVEL_ERROR,
1688 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05301689 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301690 return FALSE;
1691 }
1692
1693 nla_nest_end(vendor_event, wmmStats);
1694 }
1695 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +05301696 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301697 return TRUE;
1698}
1699
1700static tSirWifiInterfaceMode
1701 hdd_map_device_to_ll_iface_mode ( int deviceMode )
1702{
1703 switch (deviceMode)
1704 {
1705 case WLAN_HDD_INFRA_STATION:
1706 return WIFI_INTERFACE_STA;
1707 case WLAN_HDD_SOFTAP:
1708 return WIFI_INTERFACE_SOFTAP;
1709 case WLAN_HDD_P2P_CLIENT:
1710 return WIFI_INTERFACE_P2P_CLIENT;
1711 case WLAN_HDD_P2P_GO:
1712 return WIFI_INTERFACE_P2P_GO;
1713 case WLAN_HDD_IBSS:
1714 return WIFI_INTERFACE_IBSS;
1715 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05301716 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301717 }
1718}
1719
1720static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
1721 tpSirWifiInterfaceInfo pInfo)
1722{
1723 v_U8_t *staMac = NULL;
1724 hdd_station_ctx_t *pHddStaCtx;
1725 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1726 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
1727
1728 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
1729
1730 vos_mem_copy(pInfo->macAddr,
1731 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1732
1733 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1734 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
1735 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
1736 {
1737 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1738 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
1739 {
1740 pInfo->state = WIFI_DISCONNECTED;
1741 }
1742 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
1743 {
1744 hddLog(VOS_TRACE_LEVEL_ERROR,
1745 "%s: Session ID %d, Connection is in progress", __func__,
1746 pAdapter->sessionId);
1747 pInfo->state = WIFI_ASSOCIATING;
1748 }
1749 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1750 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
1751 {
1752 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
1753 hddLog(VOS_TRACE_LEVEL_ERROR,
1754 "%s: client " MAC_ADDRESS_STR
1755 " is in the middle of WPS/EAPOL exchange.", __func__,
1756 MAC_ADDR_ARRAY(staMac));
1757 pInfo->state = WIFI_AUTHENTICATING;
1758 }
1759 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
1760 {
1761 pInfo->state = WIFI_ASSOCIATED;
1762 vos_mem_copy(pInfo->bssid,
1763 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
1764 vos_mem_copy(pInfo->ssid,
1765 pHddStaCtx->conn_info.SSID.SSID.ssId,
1766 pHddStaCtx->conn_info.SSID.SSID.length);
1767 //NULL Terminate the string.
1768 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
1769 }
1770 }
1771 vos_mem_copy(pInfo->countryStr,
1772 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1773
1774 vos_mem_copy(pInfo->apCountryStr,
1775 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1776
1777 return TRUE;
1778}
1779
1780/*
1781 * hdd_link_layer_process_peer_stats () - This function is called after
1782 * receiving Link Layer Peer statistics from FW.This function converts
1783 * the firmware data to the NL data and sends the same to the kernel/upper
1784 * layers.
1785 */
1786static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
1787 v_VOID_t *pData)
1788{
1789 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301790 tpSirWifiPeerStat pWifiPeerStat;
1791 tpSirWifiPeerInfo pWifiPeerInfo;
1792 struct nlattr *peerInfo;
1793 struct sk_buff *vendor_event;
1794 int status, i;
1795
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301796 ENTER();
1797
Sunil Duttc69bccb2014-05-26 21:30:20 +05301798 status = wlan_hdd_validate_context(pHddCtx);
1799 if (0 != status)
1800 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301801 return;
1802 }
1803
1804 pWifiPeerStat = (tpSirWifiPeerStat) pData;
1805
1806 hddLog(VOS_TRACE_LEVEL_INFO,
1807 "LL_STATS_PEER_ALL : numPeers %u",
1808 pWifiPeerStat->numPeers);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301809 /*
1810 * Allocate a size of 4096 for the peer stats comprising
1811 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1812 * sizeof (tSirWifiRateStat).Each field is put with an
1813 * NL attribute.The size of 4096 is considered assuming
1814 * that number of rates shall not exceed beyond 50 with
1815 * the sizeof (tSirWifiRateStat) being 32.
1816 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301817 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1818 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301819 if (!vendor_event)
1820 {
1821 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301822 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
Sunil Duttc69bccb2014-05-26 21:30:20 +05301823 __func__);
1824 return;
1825 }
1826 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301827 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1828 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_PEER) ||
1829 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301830 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1831 pWifiPeerStat->numPeers))
1832 {
1833 hddLog(VOS_TRACE_LEVEL_ERROR,
1834 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1835 kfree_skb(vendor_event);
1836 return;
1837 }
1838
1839 peerInfo = nla_nest_start(vendor_event,
1840 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301841 if(!peerInfo)
1842 {
1843 hddLog(VOS_TRACE_LEVEL_ERROR,
1844 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
1845 __func__);
1846 kfree_skb(vendor_event);
1847 return;
1848 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301849
1850 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1851 pWifiPeerStat->peerInfo);
1852
1853 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1854 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301855 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301856 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301857
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301858 if(!peers)
1859 {
1860 hddLog(VOS_TRACE_LEVEL_ERROR,
1861 "%s: peer stats put fail",
1862 __func__);
1863 kfree_skb(vendor_event);
1864 return;
1865 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301866 if (FALSE == put_wifi_peer_info(
1867 pWifiPeerInfo, vendor_event))
1868 {
1869 hddLog(VOS_TRACE_LEVEL_ERROR,
1870 "%s: put_wifi_peer_info put fail", __func__);
1871 kfree_skb(vendor_event);
1872 return;
1873 }
1874
1875 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1876 pWifiPeerStat->peerInfo +
1877 (i * sizeof(tSirWifiPeerInfo)) +
1878 (numRate * sizeof (tSirWifiRateStat)));
1879 nla_nest_end(vendor_event, peers);
1880 }
1881 nla_nest_end(vendor_event, peerInfo);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301882 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301883 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301884}
1885
1886/*
1887 * hdd_link_layer_process_iface_stats () - This function is called after
1888 * receiving Link Layer Interface statistics from FW.This function converts
1889 * the firmware data to the NL data and sends the same to the kernel/upper
1890 * layers.
1891 */
1892static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1893 v_VOID_t *pData)
1894{
1895 tpSirWifiIfaceStat pWifiIfaceStat;
1896 struct sk_buff *vendor_event;
1897 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1898 int status;
1899
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301900 ENTER();
1901
Sunil Duttc69bccb2014-05-26 21:30:20 +05301902 status = wlan_hdd_validate_context(pHddCtx);
1903 if (0 != status)
1904 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301905 return;
1906 }
1907 /*
1908 * Allocate a size of 4096 for the interface stats comprising
1909 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1910 * assuming that all these fit with in the limit.Please take
1911 * a call on the limit based on the data requirements on
1912 * interface statistics.
1913 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301914 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1915 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301916 if (!vendor_event)
1917 {
1918 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301919 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301920 return;
1921 }
1922
1923 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1924
Dino Mycle3b9536d2014-07-09 22:05:24 +05301925
1926 if (FALSE == hdd_get_interface_info( pAdapter,
1927 &pWifiIfaceStat->info))
1928 {
1929 hddLog(VOS_TRACE_LEVEL_ERROR,
1930 FL("hdd_get_interface_info get fail") );
1931 kfree_skb(vendor_event);
1932 return;
1933 }
1934
1935 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
1936 vendor_event))
1937 {
1938 hddLog(VOS_TRACE_LEVEL_ERROR,
1939 FL("put_wifi_iface_stats fail") );
1940 kfree_skb(vendor_event);
1941 return;
1942 }
1943
Sunil Duttc69bccb2014-05-26 21:30:20 +05301944 hddLog(VOS_TRACE_LEVEL_INFO,
1945 "WMI_LINK_STATS_IFACE Data");
1946
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301947 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301948
1949 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301950}
1951
1952/*
1953 * hdd_link_layer_process_radio_stats () - This function is called after
1954 * receiving Link Layer Radio statistics from FW.This function converts
1955 * the firmware data to the NL data and sends the same to the kernel/upper
1956 * layers.
1957 */
1958static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1959 v_VOID_t *pData)
1960{
1961 int status, i;
1962 tpSirWifiRadioStat pWifiRadioStat;
1963 tpSirWifiChannelStats pWifiChannelStats;
1964 struct sk_buff *vendor_event;
1965 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1966 struct nlattr *chList;
1967
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301968 ENTER();
1969
Sunil Duttc69bccb2014-05-26 21:30:20 +05301970 status = wlan_hdd_validate_context(pHddCtx);
1971 if (0 != status)
1972 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301973 return;
1974 }
1975 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1976
1977 hddLog(VOS_TRACE_LEVEL_INFO,
1978 "LL_STATS_RADIO"
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05301979 " number of radios = %u"
Sunil Duttc69bccb2014-05-26 21:30:20 +05301980 " radio is %d onTime is %u "
1981 " txTime is %u rxTime is %u "
1982 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301983 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301984 " onTimePnoScan is %u onTimeHs20 is %u "
1985 " numChannels is %u",
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05301986 NUM_RADIOS,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301987 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1988 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1989 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301990 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301991 pWifiRadioStat->onTimeRoamScan,
1992 pWifiRadioStat->onTimePnoScan,
1993 pWifiRadioStat->onTimeHs20,
1994 pWifiRadioStat->numChannels);
1995 /*
1996 * Allocate a size of 4096 for the Radio stats comprising
1997 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1998 * (tSirWifiChannelStats).Each channel data is put with an
1999 * NL attribute.The size of 4096 is considered assuming that
2000 * number of channels shall not exceed beyond 60 with the
2001 * sizeof (tSirWifiChannelStats) being 24 bytes.
2002 */
2003
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302004 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2005 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302006 if (!vendor_event)
2007 {
2008 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302009 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05302010 return;
2011 }
2012
2013 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302014 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2015 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO) ||
2016 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302017 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
2018 pWifiRadioStat->radio) ||
2019 nla_put_u32(vendor_event,
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302020 QCA_WLAN_VENDOR_ATTR_LL_STATS_NUM_RADIOS,
2021 NUM_RADIOS) ||
2022 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302023 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
2024 pWifiRadioStat->onTime) ||
2025 nla_put_u32(vendor_event,
2026 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
2027 pWifiRadioStat->txTime) ||
2028 nla_put_u32(vendor_event,
2029 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
2030 pWifiRadioStat->rxTime) ||
2031 nla_put_u32(vendor_event,
2032 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
2033 pWifiRadioStat->onTimeScan) ||
2034 nla_put_u32(vendor_event,
2035 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
2036 pWifiRadioStat->onTimeNbd) ||
2037 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302038 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
2039 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05302040 nla_put_u32(vendor_event,
2041 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
2042 pWifiRadioStat->onTimeRoamScan) ||
2043 nla_put_u32(vendor_event,
2044 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
2045 pWifiRadioStat->onTimePnoScan) ||
2046 nla_put_u32(vendor_event,
2047 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
2048 pWifiRadioStat->onTimeHs20) ||
2049 nla_put_u32(vendor_event,
2050 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
2051 pWifiRadioStat->numChannels))
2052 {
2053 hddLog(VOS_TRACE_LEVEL_ERROR,
2054 FL("QCA_WLAN_VENDOR_ATTR put fail"));
2055 kfree_skb(vendor_event);
2056 return ;
2057 }
2058
2059 chList = nla_nest_start(vendor_event,
2060 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302061 if(!chList)
2062 {
2063 hddLog(VOS_TRACE_LEVEL_ERROR,
2064 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
2065 __func__);
2066 kfree_skb(vendor_event);
2067 return;
2068 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302069 for (i = 0; i < pWifiRadioStat->numChannels; i++)
2070 {
2071 struct nlattr *chInfo;
2072
2073 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
2074 pWifiRadioStat->channels +
2075 (i * sizeof(tSirWifiChannelStats)));
2076
Sunil Duttc69bccb2014-05-26 21:30:20 +05302077 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302078 if(!chInfo)
2079 {
2080 hddLog(VOS_TRACE_LEVEL_ERROR,
2081 "%s: failed to put chInfo",
2082 __func__);
2083 kfree_skb(vendor_event);
2084 return;
2085 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302086
2087 if (nla_put_u32(vendor_event,
2088 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
2089 pWifiChannelStats->channel.width) ||
2090 nla_put_u32(vendor_event,
2091 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
2092 pWifiChannelStats->channel.centerFreq) ||
2093 nla_put_u32(vendor_event,
2094 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
2095 pWifiChannelStats->channel.centerFreq0) ||
2096 nla_put_u32(vendor_event,
2097 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
2098 pWifiChannelStats->channel.centerFreq1) ||
2099 nla_put_u32(vendor_event,
2100 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
2101 pWifiChannelStats->onTime) ||
2102 nla_put_u32(vendor_event,
2103 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
2104 pWifiChannelStats->ccaBusyTime))
2105 {
2106 hddLog(VOS_TRACE_LEVEL_ERROR,
2107 FL("cfg80211_vendor_event_alloc failed") );
2108 kfree_skb(vendor_event);
2109 return ;
2110 }
2111 nla_nest_end(vendor_event, chInfo);
2112 }
2113 nla_nest_end(vendor_event, chList);
2114
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302115 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302116
2117 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302118 return;
2119}
2120
2121/*
2122 * hdd_link_layer_stats_ind_callback () - This function is called after
2123 * receiving Link Layer indications from FW.This callback converts the firmware
2124 * data to the NL data and send the same to the kernel/upper layers.
2125 */
2126static void hdd_link_layer_stats_ind_callback ( void *pCtx,
2127 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05302128 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302129{
Dino Mycled3d50022014-07-07 12:58:25 +05302130 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
2131 hdd_adapter_t *pAdapter = NULL;
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302132 struct hdd_ll_stats_context *context;
Dino Mycled3d50022014-07-07 12:58:25 +05302133 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302134 int status;
2135
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302136 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302137
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302138 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302139 if (0 != status)
2140 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302141 return;
2142 }
2143
Dino Mycled3d50022014-07-07 12:58:25 +05302144 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
2145 if (NULL == pAdapter)
2146 {
2147 hddLog(VOS_TRACE_LEVEL_ERROR,
2148 FL(" MAC address %pM does not exist with host"),
2149 macAddr);
2150 return;
2151 }
2152
Sunil Duttc69bccb2014-05-26 21:30:20 +05302153 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05302154 "%s: Interface: %s LLStats indType: %d", __func__,
2155 pAdapter->dev->name, indType);
2156
Sunil Duttc69bccb2014-05-26 21:30:20 +05302157 switch (indType)
2158 {
2159 case SIR_HAL_LL_STATS_RESULTS_RSP:
2160 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302161 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302162 "LL_STATS RESP paramID = 0x%x, ifaceId = %u MAC: %pM "
2163 "respId = %u, moreResultToFollow = %u",
2164 linkLayerStatsResults->paramId, linkLayerStatsResults->ifaceId,
2165 macAddr, linkLayerStatsResults->respId,
2166 linkLayerStatsResults->moreResultToFollow);
2167
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302168 spin_lock(&hdd_context_lock);
2169 context = &pHddCtx->ll_stats_context;
2170 /* validate response received from target */
2171 if ((context->request_id != linkLayerStatsResults->respId) ||
2172 !(context->request_bitmap & linkLayerStatsResults->paramId))
2173 {
2174 spin_unlock(&hdd_context_lock);
2175 hddLog(LOGE,
2176 FL("Error : Request id %d response id %d request bitmap 0x%x"
2177 "response bitmap 0x%x"),
2178 context->request_id, linkLayerStatsResults->respId,
2179 context->request_bitmap, linkLayerStatsResults->paramId);
2180 return;
2181 }
2182 spin_unlock(&hdd_context_lock);
2183
Sunil Duttc69bccb2014-05-26 21:30:20 +05302184 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
2185 {
2186 hdd_link_layer_process_radio_stats(pAdapter,
2187 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302188 spin_lock(&hdd_context_lock);
2189 context->request_bitmap &= ~(WMI_LINK_STATS_RADIO);
2190 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302191 }
2192 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
2193 {
2194 hdd_link_layer_process_iface_stats(pAdapter,
2195 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302196 spin_lock(&hdd_context_lock);
2197 context->request_bitmap &= ~(WMI_LINK_STATS_IFACE);
2198 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302199 }
2200 else if ( linkLayerStatsResults->paramId &
2201 WMI_LINK_STATS_ALL_PEER )
2202 {
2203 hdd_link_layer_process_peer_stats(pAdapter,
2204 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302205 spin_lock(&hdd_context_lock);
2206 context->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER);
2207 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302208 } /* WMI_LINK_STATS_ALL_PEER */
2209 else
2210 {
2211 hddLog(VOS_TRACE_LEVEL_ERROR,
2212 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
2213 }
2214
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302215 spin_lock(&hdd_context_lock);
2216 /* complete response event if all requests are completed */
2217 if (0 == context->request_bitmap)
2218 complete(&context->response_event);
2219 spin_unlock(&hdd_context_lock);
2220
Sunil Duttc69bccb2014-05-26 21:30:20 +05302221 break;
2222 }
2223 default:
2224 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
2225 break;
2226 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302227
2228 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302229 return;
2230}
2231
2232const struct
2233nla_policy
2234qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
2235{
2236 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
2237 { .type = NLA_U32 },
2238 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
2239 { .type = NLA_U32 },
2240};
2241
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302242static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
2243 struct wireless_dev *wdev,
2244 const void *data,
2245 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302246{
2247 int status;
2248 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302249 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302250 struct net_device *dev = wdev->netdev;
2251 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2252 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2253
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302254 ENTER();
2255
Sunil Duttc69bccb2014-05-26 21:30:20 +05302256 status = wlan_hdd_validate_context(pHddCtx);
2257 if (0 != status)
2258 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302259 return -EINVAL;
2260 }
2261
2262 if (NULL == pAdapter)
2263 {
2264 hddLog(VOS_TRACE_LEVEL_ERROR,
2265 FL("HDD adapter is Null"));
2266 return -ENODEV;
2267 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302268 /* check the LLStats Capability */
2269 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2270 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2271 {
Anurag Chouhan65ea6dc2016-10-25 19:59:14 +05302272 hddLog(VOS_TRACE_LEVEL_WARN,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302273 FL("Link Layer Statistics not supported by Firmware"));
2274 return -EINVAL;
2275 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302276
2277 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
2278 (struct nlattr *)data,
2279 data_len, qca_wlan_vendor_ll_set_policy))
2280 {
2281 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2282 return -EINVAL;
2283 }
2284 if (!tb_vendor
2285 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
2286 {
2287 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
2288 return -EINVAL;
2289 }
2290 if (!tb_vendor[
2291 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
2292 {
2293 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
2294 return -EINVAL;
2295 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302296 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302297 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302298
Dino Mycledf0a5d92014-07-04 09:41:55 +05302299 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302300 nla_get_u32(
2301 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
2302
Dino Mycledf0a5d92014-07-04 09:41:55 +05302303 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302304 nla_get_u32(
2305 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
2306
Dino Mycled3d50022014-07-07 12:58:25 +05302307 vos_mem_copy(linkLayerStatsSetReq.macAddr,
2308 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302309
2310
2311 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302312 "LL_STATS_SET reqId = %d, MAC = %pM, mpduSizeThreshold = %d "
2313 "Statistics Gathering = %d ",
2314 linkLayerStatsSetReq.reqId, linkLayerStatsSetReq.macAddr,
2315 linkLayerStatsSetReq.mpduSizeThreshold,
2316 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302317
2318 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
2319 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05302320 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302321 {
2322 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2323 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302324 return -EINVAL;
2325
2326 }
Srinivas Dasari98947432014-11-07 19:41:24 +05302327
Sunil Duttc69bccb2014-05-26 21:30:20 +05302328 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302329 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302330 {
2331 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2332 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302333 return -EINVAL;
2334 }
2335
2336 pAdapter->isLinkLayerStatsSet = 1;
2337
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302338 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302339 return 0;
2340}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302341static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
2342 struct wireless_dev *wdev,
2343 const void *data,
2344 int data_len)
2345{
2346 int ret = 0;
2347
2348 vos_ssr_protect(__func__);
2349 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
2350 vos_ssr_unprotect(__func__);
2351
2352 return ret;
2353}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302354
2355const struct
2356nla_policy
2357qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
2358{
2359 /* Unsigned 32bit value provided by the caller issuing the GET stats
2360 * command. When reporting
2361 * the stats results, the driver uses the same value to indicate
2362 * which GET request the results
2363 * correspond to.
2364 */
2365 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
2366
2367 /* Unsigned 32bit value . bit mask to identify what statistics are
2368 requested for retrieval */
2369 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
2370};
2371
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302372static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
2373 struct wireless_dev *wdev,
2374 const void *data,
2375 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302376{
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302377 unsigned long rc;
2378 struct hdd_ll_stats_context *context;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302379 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2380 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302381 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302382 struct net_device *dev = wdev->netdev;
2383 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma10313ba2015-07-29 19:14:39 +05302384 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302385 int status;
2386
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302387 ENTER();
2388
Sunil Duttc69bccb2014-05-26 21:30:20 +05302389 status = wlan_hdd_validate_context(pHddCtx);
2390 if (0 != status)
2391 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302392 return -EINVAL ;
2393 }
2394
2395 if (NULL == pAdapter)
2396 {
2397 hddLog(VOS_TRACE_LEVEL_FATAL,
2398 "%s: HDD adapter is Null", __func__);
2399 return -ENODEV;
2400 }
Mukul Sharma10313ba2015-07-29 19:14:39 +05302401
2402 if (pHddStaCtx == NULL)
2403 {
2404 hddLog(VOS_TRACE_LEVEL_FATAL,
2405 "%s: HddStaCtx is Null", __func__);
2406 return -ENODEV;
2407 }
2408
Dino Mycledf0a5d92014-07-04 09:41:55 +05302409 /* check the LLStats Capability */
2410 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2411 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2412 {
2413 hddLog(VOS_TRACE_LEVEL_ERROR,
2414 FL("Link Layer Statistics not supported by Firmware"));
2415 return -EINVAL;
2416 }
2417
Sunil Duttc69bccb2014-05-26 21:30:20 +05302418
2419 if (!pAdapter->isLinkLayerStatsSet)
2420 {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05302421 hddLog(VOS_TRACE_LEVEL_ERROR,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302422 "%s: isLinkLayerStatsSet : %d",
2423 __func__, pAdapter->isLinkLayerStatsSet);
2424 return -EINVAL;
2425 }
2426
Mukul Sharma10313ba2015-07-29 19:14:39 +05302427 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
2428 {
2429 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2430 "%s: Roaming in progress, so unable to proceed this request", __func__);
2431 return -EBUSY;
2432 }
2433
Sunil Duttc69bccb2014-05-26 21:30:20 +05302434 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
2435 (struct nlattr *)data,
2436 data_len, qca_wlan_vendor_ll_get_policy))
2437 {
2438 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2439 return -EINVAL;
2440 }
2441
2442 if (!tb_vendor
2443 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
2444 {
2445 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
2446 return -EINVAL;
2447 }
2448
2449 if (!tb_vendor
2450 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
2451 {
2452 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
2453 return -EINVAL;
2454 }
2455
Sunil Duttc69bccb2014-05-26 21:30:20 +05302456
Dino Mycledf0a5d92014-07-04 09:41:55 +05302457 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302458 nla_get_u32( tb_vendor[
2459 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05302460 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302461 nla_get_u32( tb_vendor[
2462 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
2463
Dino Mycled3d50022014-07-07 12:58:25 +05302464 vos_mem_copy(linkLayerStatsGetReq.macAddr,
2465 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302466
2467 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302468 "LL_STATS_GET reqId = %d, MAC = %pM, paramIdMask = %d",
2469 linkLayerStatsGetReq.reqId, linkLayerStatsGetReq.macAddr,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302470 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302471
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302472 spin_lock(&hdd_context_lock);
2473 context = &pHddCtx->ll_stats_context;
2474 context->request_id = linkLayerStatsGetReq.reqId;
2475 context->request_bitmap = linkLayerStatsGetReq.paramIdMask;
2476 INIT_COMPLETION(context->response_event);
2477 spin_unlock(&hdd_context_lock);
2478
Sunil Duttc69bccb2014-05-26 21:30:20 +05302479 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302480 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302481 {
2482 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2483 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302484 return -EINVAL;
2485 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302486
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302487 rc = wait_for_completion_timeout(&context->response_event,
2488 msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS));
2489 if (!rc)
2490 {
2491 hddLog(LOGE,
2492 FL("Target response timed out request id %d request bitmap 0x%x"),
2493 context->request_id, context->request_bitmap);
2494 return -ETIMEDOUT;
2495 }
2496
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302497 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302498 return 0;
2499}
2500
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302501static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
2502 struct wireless_dev *wdev,
2503 const void *data,
2504 int data_len)
2505{
2506 int ret = 0;
2507
2508 vos_ssr_protect(__func__);
2509 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
2510 vos_ssr_unprotect(__func__);
2511
2512 return ret;
2513}
2514
Sunil Duttc69bccb2014-05-26 21:30:20 +05302515const struct
2516nla_policy
2517qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
2518{
2519 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
2520 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
2521 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
2522 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
2523};
2524
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302525static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2526 struct wireless_dev *wdev,
2527 const void *data,
2528 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302529{
2530 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2531 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302532 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302533 struct net_device *dev = wdev->netdev;
2534 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2535 u32 statsClearReqMask;
2536 u8 stopReq;
2537 int status;
2538
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302539 ENTER();
2540
Sunil Duttc69bccb2014-05-26 21:30:20 +05302541 status = wlan_hdd_validate_context(pHddCtx);
2542 if (0 != status)
2543 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302544 return -EINVAL;
2545 }
2546
2547 if (NULL == pAdapter)
2548 {
2549 hddLog(VOS_TRACE_LEVEL_FATAL,
2550 "%s: HDD adapter is Null", __func__);
2551 return -ENODEV;
2552 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302553 /* check the LLStats Capability */
2554 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2555 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2556 {
2557 hddLog(VOS_TRACE_LEVEL_ERROR,
2558 FL("Enable LLStats Capability"));
2559 return -EINVAL;
2560 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302561
2562 if (!pAdapter->isLinkLayerStatsSet)
2563 {
2564 hddLog(VOS_TRACE_LEVEL_FATAL,
2565 "%s: isLinkLayerStatsSet : %d",
2566 __func__, pAdapter->isLinkLayerStatsSet);
2567 return -EINVAL;
2568 }
2569
2570 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
2571 (struct nlattr *)data,
2572 data_len, qca_wlan_vendor_ll_clr_policy))
2573 {
2574 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2575 return -EINVAL;
2576 }
2577
2578 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
2579
2580 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
2581 {
2582 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
2583 return -EINVAL;
2584
2585 }
2586
Sunil Duttc69bccb2014-05-26 21:30:20 +05302587
Dino Mycledf0a5d92014-07-04 09:41:55 +05302588 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302589 nla_get_u32(
2590 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
2591
Dino Mycledf0a5d92014-07-04 09:41:55 +05302592 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302593 nla_get_u8(
2594 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
2595
2596 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302597 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302598
Dino Mycled3d50022014-07-07 12:58:25 +05302599 vos_mem_copy(linkLayerStatsClearReq.macAddr,
2600 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302601
2602 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302603 "LL_STATS_CLEAR reqId = %d, MAC = %pM,"
2604 "statsClearReqMask = 0x%X, stopReq = %d",
2605 linkLayerStatsClearReq.reqId,
2606 linkLayerStatsClearReq.macAddr,
2607 linkLayerStatsClearReq.statsClearReqMask,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302608 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302609
2610 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302611 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302612 {
2613 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05302614 hdd_station_ctx_t *pHddStaCtx;
2615
2616 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2617 if (VOS_STATUS_SUCCESS !=
2618 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2619 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
2620 {
2621 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2622 "WLANTL_ClearInterfaceStats Failed", __func__);
2623 return -EINVAL;
2624 }
2625 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
2626 (statsClearReqMask & WIFI_STATS_IFACE)) {
2627 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
2628 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
2629 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
2630 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
2631 }
2632
Sunil Duttc69bccb2014-05-26 21:30:20 +05302633 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
2634 2 * sizeof(u32) +
2635 NLMSG_HDRLEN);
2636
2637 if (temp_skbuff != NULL)
2638 {
2639
2640 if (nla_put_u32(temp_skbuff,
2641 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
2642 statsClearReqMask) ||
2643 nla_put_u32(temp_skbuff,
2644 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
2645 stopReq))
2646 {
2647 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
2648 kfree_skb(temp_skbuff);
2649 return -EINVAL;
2650 }
2651 /* If the ask is to stop the stats collection as part of clear
2652 * (stopReq = 1) , ensure that no further requests of get
2653 * go to the firmware by having isLinkLayerStatsSet set to 0.
2654 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302655 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05302656 * case the firmware is just asked to clear the statistics.
2657 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05302658 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302659 pAdapter->isLinkLayerStatsSet = 0;
2660 return cfg80211_vendor_cmd_reply(temp_skbuff);
2661 }
2662 return -ENOMEM;
2663 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302664
2665 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302666 return -EINVAL;
2667}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302668static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2669 struct wireless_dev *wdev,
2670 const void *data,
2671 int data_len)
2672{
2673 int ret = 0;
2674
2675 vos_ssr_protect(__func__);
2676 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
2677 vos_ssr_unprotect(__func__);
2678
2679 return ret;
2680
2681
2682}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302683#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
2684
Dino Mycle6fb96c12014-06-10 11:52:40 +05302685#ifdef WLAN_FEATURE_EXTSCAN
2686static const struct nla_policy
2687wlan_hdd_extscan_config_policy
2688 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
2689{
2690 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
2691 { .type = NLA_U32 },
2692 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
2693 { .type = NLA_U32 },
SaidiReddy Yenugaf2145922017-05-26 18:19:31 +05302694 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS] =
2695 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302696 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
2697 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
2698 { .type = NLA_U32 },
2699 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
2700 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
2701
2702 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
2703 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
2704 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
2705 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
2706 { .type = NLA_U8 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302707 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] =
2708 { .type = NLA_U32 },
2709 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT] =
2710 { .type = NLA_U32 },
2711 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] =
2712 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302713 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
2714 { .type = NLA_U32 },
2715 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
2716 { .type = NLA_U32 },
2717 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
2718 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302719 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] =
2720 { .type = NLA_U8 },
2721 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302722 { .type = NLA_U8 },
2723 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
2724 { .type = NLA_U8 },
2725 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
2726 { .type = NLA_U8 },
2727
2728 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
2729 { .type = NLA_U32 },
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05302730 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] = {
2731 .type = NLA_UNSPEC,
2732 .len = HDD_MAC_ADDR_LEN},
Dino Mycle6fb96c12014-06-10 11:52:40 +05302733 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
2734 { .type = NLA_S32 },
2735 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
2736 { .type = NLA_S32 },
2737 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
2738 { .type = NLA_U32 },
2739 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
2740 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302741 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] =
2742 { .type = NLA_U32 },
2743 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] =
2744 { .type = NLA_BINARY,
2745 .len = IEEE80211_MAX_SSID_LEN + 1 },
2746 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302747 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302748 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] =
2749 { .type = NLA_U32 },
2750 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] =
2751 { .type = NLA_U8 },
2752 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] =
2753 { .type = NLA_S32 },
2754 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] =
2755 { .type = NLA_S32 },
2756 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] =
2757 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302758};
2759
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302760/**
2761 * wlan_hdd_cfg80211_extscan_get_capabilities_rsp() - response from target
2762 * @ctx: hdd global context
2763 * @data: capabilities data
2764 *
2765 * Return: none
2766 */
2767static void
2768wlan_hdd_cfg80211_extscan_get_capabilities_rsp(void *ctx, void *pMsg)
Dino Mycle6fb96c12014-06-10 11:52:40 +05302769{
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302770 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302771 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302772 tSirEXTScanCapabilitiesEvent *data =
2773 (tSirEXTScanCapabilitiesEvent *) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302774
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302775 ENTER();
2776
2777 if (wlan_hdd_validate_context(pHddCtx))
2778 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302779 return;
2780 }
2781
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302782 if (!pMsg)
2783 {
2784 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2785 return;
2786 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302787
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302788 vos_spin_lock_acquire(&hdd_context_lock);
2789
2790 context = &pHddCtx->ext_scan_context;
2791 /* validate response received from target*/
2792 if (context->request_id != data->requestId)
2793 {
2794 vos_spin_lock_release(&hdd_context_lock);
2795 hddLog(LOGE,
2796 FL("Target response id did not match: request_id %d resposne_id %d"),
2797 context->request_id, data->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302798 return;
2799 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302800 else
2801 {
2802 context->capability_response = *data;
2803 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302804 }
2805
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302806 vos_spin_lock_release(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302807
Dino Mycle6fb96c12014-06-10 11:52:40 +05302808 return;
2809}
2810
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302811/*
2812 * define short names for the global vendor params
2813 * used by wlan_hdd_send_ext_scan_capability()
2814 */
2815#define PARAM_REQUEST_ID \
2816 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
2817#define PARAM_STATUS \
2818 QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS
2819#define MAX_SCAN_CACHE_SIZE \
2820 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE
2821#define MAX_SCAN_BUCKETS \
2822 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS
2823#define MAX_AP_CACHE_PER_SCAN \
2824 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN
2825#define MAX_RSSI_SAMPLE_SIZE \
2826 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE
2827#define MAX_SCAN_RPT_THRHOLD \
2828 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
2829#define MAX_HOTLIST_BSSIDS \
2830 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS
2831#define MAX_BSSID_HISTORY_ENTRIES \
2832 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
2833#define MAX_HOTLIST_SSIDS \
2834 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302835#define MAX_SIGNIFICANT_WIFI_CHANGE_APS \
2836 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302837
2838static int wlan_hdd_send_ext_scan_capability(void *ctx)
2839{
2840 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2841 struct sk_buff *skb = NULL;
2842 int ret;
2843 tSirEXTScanCapabilitiesEvent *data;
2844 tANI_U32 nl_buf_len;
2845
2846 ret = wlan_hdd_validate_context(pHddCtx);
2847 if (0 != ret)
2848 {
2849 return ret;
2850 }
2851
2852 data = &(pHddCtx->ext_scan_context.capability_response);
2853
2854 nl_buf_len = NLMSG_HDRLEN;
2855 nl_buf_len += (sizeof(data->requestId) + NLA_HDRLEN) +
2856 (sizeof(data->status) + NLA_HDRLEN) +
2857 (sizeof(data->scanCacheSize) + NLA_HDRLEN) +
2858 (sizeof(data->scanBuckets) + NLA_HDRLEN) +
2859 (sizeof(data->maxApPerScan) + NLA_HDRLEN) +
2860 (sizeof(data->maxRssiSampleSize) + NLA_HDRLEN) +
2861 (sizeof(data->maxScanReportingThreshold) + NLA_HDRLEN) +
2862 (sizeof(data->maxHotlistAPs) + NLA_HDRLEN) +
2863 (sizeof(data->maxBsidHistoryEntries) + NLA_HDRLEN) +
2864 (sizeof(data->maxHotlistSSIDs) + NLA_HDRLEN);
2865
2866 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, nl_buf_len);
2867
2868 if (!skb)
2869 {
2870 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
2871 return -ENOMEM;
2872 }
2873
2874 hddLog(LOG1, "Req Id (%u) Status (%u)", data->requestId, data->status);
2875 hddLog(LOG1, "Scan cache size (%u) Scan buckets (%u) Max AP per scan (%u)",
2876 data->scanCacheSize, data->scanBuckets, data->maxApPerScan);
2877 hddLog(LOG1, "max_rssi_sample_size (%u) max_scan_reporting_threshold (%u)",
2878 data->maxRssiSampleSize, data->maxScanReportingThreshold);
2879 hddLog(LOG1, "max_hotlist_bssids (%u) max_bssid_history_entries (%u)"
2880 "max_hotlist_ssids (%u)", data->maxHotlistAPs,
2881 data->maxBsidHistoryEntries, data->maxHotlistSSIDs);
2882
2883 if (nla_put_u32(skb, PARAM_REQUEST_ID, data->requestId) ||
2884 nla_put_u32(skb, PARAM_STATUS, data->status) ||
2885 nla_put_u32(skb, MAX_SCAN_CACHE_SIZE, data->scanCacheSize) ||
2886 nla_put_u32(skb, MAX_SCAN_BUCKETS, data->scanBuckets) ||
2887 nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN,
2888 data->maxApPerScan) ||
2889 nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE,
2890 data->maxRssiSampleSize) ||
2891 nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD,
2892 data->maxScanReportingThreshold) ||
2893 nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->maxHotlistAPs) ||
2894 nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES,
2895 data->maxBsidHistoryEntries) ||
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302896 nla_put_u32(skb, MAX_HOTLIST_SSIDS, data->maxHotlistSSIDs) ||
2897 nla_put_u32(skb, MAX_SIGNIFICANT_WIFI_CHANGE_APS, 0))
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302898 {
2899 hddLog(LOGE, FL("nla put fail"));
2900 goto nla_put_failure;
2901 }
2902
2903 cfg80211_vendor_cmd_reply(skb);
2904 return 0;
2905
2906nla_put_failure:
2907 kfree_skb(skb);
2908 return -EINVAL;;
2909}
2910
2911/*
2912 * done with short names for the global vendor params
2913 * used by wlan_hdd_send_ext_scan_capability()
2914 */
2915#undef PARAM_REQUEST_ID
2916#undef PARAM_STATUS
2917#undef MAX_SCAN_CACHE_SIZE
2918#undef MAX_SCAN_BUCKETS
2919#undef MAX_AP_CACHE_PER_SCAN
2920#undef MAX_RSSI_SAMPLE_SIZE
2921#undef MAX_SCAN_RPT_THRHOLD
2922#undef MAX_HOTLIST_BSSIDS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302923#undef MAX_BSSID_HISTORY_ENTRIES
2924#undef MAX_HOTLIST_SSIDS
Dino Mycle6fb96c12014-06-10 11:52:40 +05302925
2926static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
2927{
2928 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
2929 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302930 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302931 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302932
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302933 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302934
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302935 if (wlan_hdd_validate_context(pHddCtx))
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302936 return;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302937
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302938 if (!pMsg)
2939 {
2940 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302941 return;
2942 }
2943
Dino Mycle6fb96c12014-06-10 11:52:40 +05302944 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2945 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2946
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302947 context = &pHddCtx->ext_scan_context;
2948 spin_lock(&hdd_context_lock);
2949 if (context->request_id == pData->requestId) {
2950 context->response_status = pData->status ? -EINVAL : 0;
2951 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302952 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302953 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302954
2955 /*
2956 * Store the Request ID for comparing with the requestID obtained
2957 * in other requests.HDD shall return a failure is the extscan_stop
2958 * request is issued with a different requestId as that of the
2959 * extscan_start request. Also, This requestId shall be used while
2960 * indicating the full scan results to the upper layers.
2961 * The requestId is stored with the assumption that the firmware
2962 * shall return the ext scan start request's requestId in ext scan
2963 * start response.
2964 */
2965 if (pData->status == 0)
2966 pMac->sme.extScanStartReqId = pData->requestId;
2967
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302968 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302969 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302970}
2971
2972
2973static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2974{
2975 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2976 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302977 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302978
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302979 ENTER();
2980
2981 if (wlan_hdd_validate_context(pHddCtx)){
2982 return;
2983 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302984
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302985 if (!pMsg)
2986 {
2987 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302988 return;
2989 }
2990
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302991 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2992 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302993
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302994 context = &pHddCtx->ext_scan_context;
2995 spin_lock(&hdd_context_lock);
2996 if (context->request_id == pData->requestId) {
2997 context->response_status = pData->status ? -EINVAL : 0;
2998 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302999 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303000 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303001
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303002 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303003 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303004}
3005
Dino Mycle6fb96c12014-06-10 11:52:40 +05303006static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
3007 void *pMsg)
3008{
3009 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303010 tpSirEXTScanSetBssidHotListRspParams pData =
3011 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303012 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303013
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303014 ENTER();
3015
3016 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05303017 return;
3018 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303019
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303020 if (!pMsg)
3021 {
3022 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3023 return;
3024 }
3025
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303026 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3027 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303028
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303029 context = &pHddCtx->ext_scan_context;
3030 spin_lock(&hdd_context_lock);
3031 if (context->request_id == pData->requestId) {
3032 context->response_status = pData->status ? -EINVAL : 0;
3033 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303034 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303035 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303036
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303037 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303038 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303039}
3040
3041static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
3042 void *pMsg)
3043{
3044 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303045 tpSirEXTScanResetBssidHotlistRspParams pData =
3046 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303047 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303048
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303049 ENTER();
3050
3051 if (wlan_hdd_validate_context(pHddCtx)) {
3052 return;
3053 }
3054 if (!pMsg)
3055 {
3056 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303057 return;
3058 }
3059
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303060 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3061 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303062
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303063 context = &pHddCtx->ext_scan_context;
3064 spin_lock(&hdd_context_lock);
3065 if (context->request_id == pData->requestId) {
3066 context->response_status = pData->status ? -EINVAL : 0;
3067 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303068 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303069 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303070
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303071 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303072 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303073}
3074
Dino Mycle6fb96c12014-06-10 11:52:40 +05303075static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
3076 void *pMsg)
3077{
3078 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3079 struct sk_buff *skb = NULL;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303080 tANI_U32 i = 0, j, resultsPerEvent, scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303081 tANI_S32 totalResults;
3082 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303083 tpSirWifiScanResult pSirWifiScanResult, head_ptr;
3084 struct hdd_ext_scan_context *context;
3085 bool ignore_cached_results = false;
3086 tExtscanCachedScanResult *result;
3087 struct nlattr *nla_results;
3088 tANI_U16 ieLength= 0;
3089 tANI_U8 *ie = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303090
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303091 ENTER();
3092
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303093 if (wlan_hdd_validate_context(pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303094 return;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303095
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303096 if (!pMsg)
3097 {
3098 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3099 return;
3100 }
3101
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303102 spin_lock(&hdd_context_lock);
3103 context = &pHddCtx->ext_scan_context;
3104 ignore_cached_results = context->ignore_cached_results;
3105 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303106
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303107 if (ignore_cached_results) {
3108 hddLog(LOGE,
3109 FL("Ignore the cached results received after timeout"));
3110 return;
3111 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303112
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303113 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u More Data %u No of scan ids %u",
3114 pData->requestId, pData->moreData, pData->scanResultSize);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303115
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303116 result = (tExtscanCachedScanResult *)&(pData->result);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303117
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303118 for (scan_id_index = 0; scan_id_index < pData->scanResultSize;
3119 scan_id_index++) {
3120 result+= scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303121
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303122 totalResults = result->num_results;
3123 hddLog(VOS_TRACE_LEVEL_INFO, "scan_id %u flags %u Num results %u",
3124 result->scan_id, result->flags, totalResults);
3125 i = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303126
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303127 do{
3128 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
3129 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
3130 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303131
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303132 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
3133 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN);
3134
3135 if (!skb) {
3136 hddLog(VOS_TRACE_LEVEL_ERROR,
3137 FL("cfg80211_vendor_event_alloc failed"));
3138 return;
3139 }
3140
3141 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
3142
3143 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3144 pData->requestId) ||
3145 nla_put_u32(skb,
3146 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3147 resultsPerEvent)) {
3148 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3149 goto fail;
3150 }
3151 if (nla_put_u8(skb,
3152 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3153 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303154 {
3155 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3156 goto fail;
3157 }
3158
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303159 if (nla_put_u32(skb,
3160 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
3161 result->scan_id)) {
3162 hddLog(LOGE, FL("put fail"));
3163 goto fail;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303164 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303165
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303166 nla_results = nla_nest_start(skb,
3167 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_LIST);
3168 if (!nla_results)
3169 goto fail;
3170
3171 if (resultsPerEvent) {
3172 struct nlattr *aps;
3173 struct nlattr *nla_result;
3174
3175 nla_result = nla_nest_start(skb, scan_id_index);
3176 if(!nla_result)
3177 goto fail;
3178
3179 if (nla_put_u32(skb,
3180 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
3181 result->scan_id) ||
3182 nla_put_u32(skb,
3183 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_FLAGS,
3184 result->flags) ||
3185 nla_put_u32(skb,
3186 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3187 totalResults)) {
3188 hddLog(LOGE, FL("put fail"));
3189 goto fail;
3190 }
3191
3192 aps = nla_nest_start(skb,
3193 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3194 if (!aps)
3195 {
3196 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3197 goto fail;
3198 }
3199
3200 head_ptr = (tpSirWifiScanResult) &(result->ap);
3201
3202 for (j = 0; j < resultsPerEvent; j++, i++) {
3203 struct nlattr *ap;
3204 pSirWifiScanResult = head_ptr + i;
3205
3206 /*
Srinivas Dasari91727c12016-03-23 17:59:06 +05303207 * Firmware returns timestamp from extscan_start till
3208 * BSSID was cached (in micro seconds). Add this with
3209 * time gap between system boot up to extscan_start
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303210 * to derive the time since boot when the
3211 * BSSID was cached.
3212 */
Srinivas Dasari91727c12016-03-23 17:59:06 +05303213 pSirWifiScanResult->ts +=
3214 pHddCtx->extscan_start_time_since_boot;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303215 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
3216 "Ssid (%s)"
3217 "Bssid: %pM "
3218 "Channel (%u)"
3219 "Rssi (%d)"
3220 "RTT (%u)"
3221 "RTT_SD (%u)"
3222 "Beacon Period %u"
3223 "Capability 0x%x "
3224 "Ie length %d",
3225 i,
3226 pSirWifiScanResult->ts,
3227 pSirWifiScanResult->ssid,
3228 pSirWifiScanResult->bssid,
3229 pSirWifiScanResult->channel,
3230 pSirWifiScanResult->rssi,
3231 pSirWifiScanResult->rtt,
3232 pSirWifiScanResult->rtt_sd,
3233 pSirWifiScanResult->beaconPeriod,
3234 pSirWifiScanResult->capability,
3235 ieLength);
3236
3237 ap = nla_nest_start(skb, j + 1);
3238 if (!ap)
3239 {
3240 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3241 goto fail;
3242 }
3243
3244 if (nla_put_u64(skb,
3245 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3246 pSirWifiScanResult->ts) )
3247 {
3248 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3249 goto fail;
3250 }
3251 if (nla_put(skb,
3252 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3253 sizeof(pSirWifiScanResult->ssid),
3254 pSirWifiScanResult->ssid) )
3255 {
3256 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3257 goto fail;
3258 }
3259 if (nla_put(skb,
3260 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3261 sizeof(pSirWifiScanResult->bssid),
3262 pSirWifiScanResult->bssid) )
3263 {
3264 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3265 goto fail;
3266 }
3267 if (nla_put_u32(skb,
3268 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3269 pSirWifiScanResult->channel) )
3270 {
3271 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3272 goto fail;
3273 }
3274 if (nla_put_s32(skb,
3275 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
3276 pSirWifiScanResult->rssi) )
3277 {
3278 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3279 goto fail;
3280 }
3281 if (nla_put_u32(skb,
3282 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3283 pSirWifiScanResult->rtt) )
3284 {
3285 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3286 goto fail;
3287 }
3288 if (nla_put_u32(skb,
3289 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3290 pSirWifiScanResult->rtt_sd))
3291 {
3292 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3293 goto fail;
3294 }
3295 if (nla_put_u32(skb,
3296 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3297 pSirWifiScanResult->beaconPeriod))
3298 {
3299 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3300 goto fail;
3301 }
3302 if (nla_put_u32(skb,
3303 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3304 pSirWifiScanResult->capability))
3305 {
3306 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3307 goto fail;
3308 }
3309 if (nla_put_u32(skb,
3310 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
3311 ieLength))
3312 {
3313 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3314 goto fail;
3315 }
3316
3317 if (ieLength)
3318 if (nla_put(skb,
3319 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3320 ieLength, ie)) {
3321 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3322 goto fail;
3323 }
3324
3325 nla_nest_end(skb, ap);
3326 }
3327 nla_nest_end(skb, aps);
3328 nla_nest_end(skb, nla_result);
3329 }
3330
3331 nla_nest_end(skb, nla_results);
3332
3333 cfg80211_vendor_cmd_reply(skb);
3334
3335 } while (totalResults > 0);
3336 }
3337
3338 if (!pData->moreData) {
3339 spin_lock(&hdd_context_lock);
3340 context->response_status = 0;
3341 complete(&context->response_event);
3342 spin_unlock(&hdd_context_lock);
3343 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303344
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303345 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303346 return;
3347fail:
3348 kfree_skb(skb);
3349 return;
3350}
3351
3352static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
3353 void *pMsg)
3354{
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303355 tpSirEXTScanHotlistMatch pData = (tpSirEXTScanHotlistMatch) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303356 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3357 struct sk_buff *skb = NULL;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303358 tANI_U32 i, index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303359
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303360 ENTER();
3361
3362 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303363 hddLog(LOGE,
3364 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303365 return;
3366 }
3367 if (!pMsg)
3368 {
3369 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303370 return;
3371 }
3372
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303373 if (pData->bss_found)
3374 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX;
3375 else
3376 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX;
3377
Dino Mycle6fb96c12014-06-10 11:52:40 +05303378 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303379#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3380 NULL,
3381#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303382 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303383 index, GFP_KERNEL);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303384
3385 if (!skb) {
3386 hddLog(VOS_TRACE_LEVEL_ERROR,
3387 FL("cfg80211_vendor_event_alloc failed"));
3388 return;
3389 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303390
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303391 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3392 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numHotlistBss);
3393 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
3394 hddLog(VOS_TRACE_LEVEL_INFO, "ap_found %u", pData->bss_found);
3395
3396 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303397 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
3398 "Ssid (%s) "
3399 "Bssid (" MAC_ADDRESS_STR ") "
3400 "Channel (%u) "
3401 "Rssi (%d) "
3402 "RTT (%u) "
3403 "RTT_SD (%u) ",
3404 i,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303405 pData->bssHotlist[i].ts,
3406 pData->bssHotlist[i].ssid,
3407 MAC_ADDR_ARRAY(pData->bssHotlist[i].bssid),
3408 pData->bssHotlist[i].channel,
3409 pData->bssHotlist[i].rssi,
3410 pData->bssHotlist[i].rtt,
3411 pData->bssHotlist[i].rtt_sd);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303412 }
3413
3414 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3415 pData->requestId) ||
3416 nla_put_u32(skb,
3417 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303418 pData->numHotlistBss)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303419 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3420 goto fail;
3421 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303422 if (pData->numHotlistBss) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303423 struct nlattr *aps;
3424
3425 aps = nla_nest_start(skb,
3426 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3427 if (!aps)
3428 goto fail;
3429
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303430 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303431 struct nlattr *ap;
3432
3433 ap = nla_nest_start(skb, i + 1);
3434 if (!ap)
3435 goto fail;
3436
3437 if (nla_put_u64(skb,
3438 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303439 pData->bssHotlist[i].ts) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303440 nla_put(skb,
3441 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303442 sizeof(pData->bssHotlist[i].ssid),
3443 pData->bssHotlist[i].ssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303444 nla_put(skb,
3445 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303446 sizeof(pData->bssHotlist[i].bssid),
3447 pData->bssHotlist[i].bssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303448 nla_put_u32(skb,
3449 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303450 pData->bssHotlist[i].channel) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303451 nla_put_s32(skb,
3452 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303453 pData->bssHotlist[i].rssi) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303454 nla_put_u32(skb,
3455 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303456 pData->bssHotlist[i].rtt) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303457 nla_put_u32(skb,
3458 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303459 pData->bssHotlist[i].rtt_sd))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303460 goto fail;
3461
3462 nla_nest_end(skb, ap);
3463 }
3464 nla_nest_end(skb, aps);
3465
3466 if (nla_put_u8(skb,
3467 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3468 pData->moreData))
3469 goto fail;
3470 }
3471
3472 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303473 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303474 return;
3475
3476fail:
3477 kfree_skb(skb);
3478 return;
3479
3480}
Dino Mycle6fb96c12014-06-10 11:52:40 +05303481
3482static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
3483 void *pMsg)
3484{
3485 struct sk_buff *skb;
3486 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3487 tpSirWifiFullScanResultEvent pData =
3488 (tpSirWifiFullScanResultEvent) (pMsg);
3489
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303490 ENTER();
3491
3492 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303493 hddLog(LOGE,
3494 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303495 return;
3496 }
3497 if (!pMsg)
3498 {
3499 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303500 return;
3501 }
3502
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303503 /*
3504 * If the full scan result including IE data exceeds NL 4K size
3505 * limitation, drop that beacon/probe rsp frame.
3506 */
3507 if ((sizeof(*pData) + pData->ieLength) >= EXTSCAN_EVENT_BUF_SIZE) {
3508 hddLog(LOGE, FL("Frame exceeded NL size limilation, drop it!"));
3509 return;
3510 }
3511
Dino Mycle6fb96c12014-06-10 11:52:40 +05303512 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303513#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3514 NULL,
3515#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303516 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3517 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
3518 GFP_KERNEL);
3519
3520 if (!skb) {
3521 hddLog(VOS_TRACE_LEVEL_ERROR,
3522 FL("cfg80211_vendor_event_alloc failed"));
3523 return;
3524 }
3525
Dino Mycle6fb96c12014-06-10 11:52:40 +05303526 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
3527 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
3528 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
3529 "Ssid (%s)"
3530 "Bssid (" MAC_ADDRESS_STR ")"
3531 "Channel (%u)"
3532 "Rssi (%d)"
3533 "RTT (%u)"
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303534 "RTT_SD (%u)"
3535 "Bcn Period %d"
3536 "Capability 0x%X "),
Dino Mycle6fb96c12014-06-10 11:52:40 +05303537 pData->ap.ts,
3538 pData->ap.ssid,
3539 MAC_ADDR_ARRAY(pData->ap.bssid),
3540 pData->ap.channel,
3541 pData->ap.rssi,
3542 pData->ap.rtt,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303543 pData->ap.rtt_sd,
3544 pData->ap.beaconPeriod,
3545 pData->ap.capability);
3546
Dino Mycle6fb96c12014-06-10 11:52:40 +05303547 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
3548 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3549 pData->requestId) ||
3550 nla_put_u64(skb,
3551 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3552 pData->ap.ts) ||
3553 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3554 sizeof(pData->ap.ssid),
3555 pData->ap.ssid) ||
3556 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3557 WNI_CFG_BSSID_LEN,
3558 pData->ap.bssid) ||
3559 nla_put_u32(skb,
3560 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3561 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05303562 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303563 pData->ap.rssi) ||
3564 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3565 pData->ap.rtt) ||
3566 nla_put_u32(skb,
3567 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3568 pData->ap.rtt_sd) ||
3569 nla_put_u16(skb,
3570 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3571 pData->ap.beaconPeriod) ||
3572 nla_put_u16(skb,
3573 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3574 pData->ap.capability) ||
3575 nla_put_u32(skb,
3576 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303577 pData->ieLength) ||
3578 nla_put_u8(skb,
3579 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3580 pData->moreData))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303581 {
3582 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3583 goto nla_put_failure;
3584 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303585
3586 if (pData->ieLength) {
3587 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3588 pData->ieLength,
3589 pData->ie))
3590 {
3591 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3592 goto nla_put_failure;
3593 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303594 }
3595
3596 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303597 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303598 return;
3599
3600nla_put_failure:
3601 kfree_skb(skb);
3602 return;
3603}
3604
3605static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
3606 void *pMsg)
3607{
3608 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3609 struct sk_buff *skb = NULL;
3610 tpSirEXTScanResultsAvailableIndParams pData =
3611 (tpSirEXTScanResultsAvailableIndParams) pMsg;
3612
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303613 ENTER();
3614
3615 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303616 hddLog(LOGE,
3617 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303618 return;
3619 }
3620 if (!pMsg)
3621 {
3622 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303623 return;
3624 }
3625
3626 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303627#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3628 NULL,
3629#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303630 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3631 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
3632 GFP_KERNEL);
3633
3634 if (!skb) {
3635 hddLog(VOS_TRACE_LEVEL_ERROR,
3636 FL("cfg80211_vendor_event_alloc failed"));
3637 return;
3638 }
3639
Dino Mycle6fb96c12014-06-10 11:52:40 +05303640 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3641 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
3642 pData->numResultsAvailable);
3643 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3644 pData->requestId) ||
3645 nla_put_u32(skb,
3646 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3647 pData->numResultsAvailable)) {
3648 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3649 goto nla_put_failure;
3650 }
3651
3652 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303653 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303654 return;
3655
3656nla_put_failure:
3657 kfree_skb(skb);
3658 return;
3659}
3660
3661static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
3662{
3663 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3664 struct sk_buff *skb = NULL;
3665 tpSirEXTScanProgressIndParams pData =
3666 (tpSirEXTScanProgressIndParams) pMsg;
3667
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303668 ENTER();
3669
3670 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303671 hddLog(LOGE,
3672 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303673 return;
3674 }
3675 if (!pMsg)
3676 {
3677 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303678 return;
3679 }
3680
3681 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303682#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3683 NULL,
3684#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303685 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3686 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
3687 GFP_KERNEL);
3688
3689 if (!skb) {
3690 hddLog(VOS_TRACE_LEVEL_ERROR,
3691 FL("cfg80211_vendor_event_alloc failed"));
3692 return;
3693 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303694 hddLog(VOS_TRACE_LEVEL_INFO, FL("Request Id (%u) "), pData->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303695 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
3696 pData->extScanEventType);
3697 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
3698 pData->status);
3699
3700 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
3701 pData->extScanEventType) ||
3702 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05303703 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3704 pData->requestId) ||
3705 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303706 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
3707 pData->status)) {
3708 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3709 goto nla_put_failure;
3710 }
3711
3712 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303713 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303714 return;
3715
3716nla_put_failure:
3717 kfree_skb(skb);
3718 return;
3719}
3720
3721void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
3722 void *pMsg)
3723{
3724 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3725
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303726 ENTER();
3727
Dino Mycle6fb96c12014-06-10 11:52:40 +05303728 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303729 return;
3730 }
3731
3732 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
3733
3734
3735 switch(evType) {
3736 case SIR_HAL_EXTSCAN_START_RSP:
3737 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
3738 break;
3739
3740 case SIR_HAL_EXTSCAN_STOP_RSP:
3741 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
3742 break;
3743 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
3744 /* There is no need to send this response to upper layer
3745 Just log the message */
3746 hddLog(VOS_TRACE_LEVEL_INFO,
3747 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
3748 break;
3749 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
3750 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
3751 break;
3752
3753 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
3754 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
3755 break;
3756
Dino Mycle6fb96c12014-06-10 11:52:40 +05303757 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303758 wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx, pMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303759 break;
3760 case SIR_HAL_EXTSCAN_PROGRESS_IND:
3761 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
3762 break;
3763 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
3764 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
3765 break;
3766 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
3767 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
3768 break;
3769 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
3770 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
3771 break;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303772 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
3773 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
3774 break;
3775 default:
3776 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
3777 break;
3778 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303779 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303780}
3781
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303782static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3783 struct wireless_dev *wdev,
3784 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303785{
Dino Myclee8843b32014-07-04 14:21:45 +05303786 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303787 struct net_device *dev = wdev->netdev;
3788 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3789 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3790 struct nlattr
3791 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3792 eHalStatus status;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303793 struct hdd_ext_scan_context *context;
3794 unsigned long rc;
3795 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303796
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303797 ENTER();
3798
Dino Mycle6fb96c12014-06-10 11:52:40 +05303799 status = wlan_hdd_validate_context(pHddCtx);
3800 if (0 != status)
3801 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303802 return -EINVAL;
3803 }
Dino Myclee8843b32014-07-04 14:21:45 +05303804 /* check the EXTScan Capability */
3805 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303806 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3807 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303808 {
3809 hddLog(VOS_TRACE_LEVEL_ERROR,
3810 FL("EXTScan not enabled/supported by Firmware"));
3811 return -EINVAL;
3812 }
3813
Dino Mycle6fb96c12014-06-10 11:52:40 +05303814 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3815 data, dataLen,
3816 wlan_hdd_extscan_config_policy)) {
3817 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3818 return -EINVAL;
3819 }
3820
3821 /* Parse and fetch request Id */
3822 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3823 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3824 return -EINVAL;
3825 }
3826
Dino Myclee8843b32014-07-04 14:21:45 +05303827 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303828 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303829 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303830
Dino Myclee8843b32014-07-04 14:21:45 +05303831 reqMsg.sessionId = pAdapter->sessionId;
3832 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303833
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303834 vos_spin_lock_acquire(&hdd_context_lock);
3835 context = &pHddCtx->ext_scan_context;
3836 context->request_id = reqMsg.requestId;
3837 INIT_COMPLETION(context->response_event);
3838 vos_spin_lock_release(&hdd_context_lock);
3839
Dino Myclee8843b32014-07-04 14:21:45 +05303840 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303841 if (!HAL_STATUS_SUCCESS(status)) {
3842 hddLog(VOS_TRACE_LEVEL_ERROR,
3843 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303844 return -EINVAL;
3845 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303846
3847 rc = wait_for_completion_timeout(&context->response_event,
3848 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3849 if (!rc) {
3850 hddLog(LOGE, FL("Target response timed out"));
3851 return -ETIMEDOUT;
3852 }
3853
3854 ret = wlan_hdd_send_ext_scan_capability(pHddCtx);
3855 if (ret)
3856 hddLog(LOGE, FL("Failed to send ext scan capability to user space"));
3857
3858 return ret;
3859
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303860 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303861 return 0;
3862}
3863
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303864static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3865 struct wireless_dev *wdev,
3866 const void *data, int dataLen)
3867{
3868 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303869
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303870 vos_ssr_protect(__func__);
3871 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
3872 vos_ssr_unprotect(__func__);
3873
3874 return ret;
3875}
3876
3877static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3878 struct wireless_dev *wdev,
3879 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303880{
Dino Myclee8843b32014-07-04 14:21:45 +05303881 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303882 struct net_device *dev = wdev->netdev;
3883 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3884 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3885 struct nlattr
3886 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3887 eHalStatus status;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303888 struct hdd_ext_scan_context *context;
3889 unsigned long rc;
3890 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303891
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303892 ENTER();
3893
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303894 if (VOS_FTM_MODE == hdd_get_conparam()) {
3895 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3896 return -EINVAL;
3897 }
3898
Dino Mycle6fb96c12014-06-10 11:52:40 +05303899 status = wlan_hdd_validate_context(pHddCtx);
3900 if (0 != status)
3901 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303902 return -EINVAL;
3903 }
Dino Myclee8843b32014-07-04 14:21:45 +05303904 /* check the EXTScan Capability */
3905 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303906 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3907 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303908 {
3909 hddLog(VOS_TRACE_LEVEL_ERROR,
3910 FL("EXTScan not enabled/supported by Firmware"));
3911 return -EINVAL;
3912 }
3913
Dino Mycle6fb96c12014-06-10 11:52:40 +05303914 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3915 data, dataLen,
3916 wlan_hdd_extscan_config_policy)) {
3917 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3918 return -EINVAL;
3919 }
3920 /* Parse and fetch request Id */
3921 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3922 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3923 return -EINVAL;
3924 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303925
Dino Myclee8843b32014-07-04 14:21:45 +05303926 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303927 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3928
Dino Myclee8843b32014-07-04 14:21:45 +05303929 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303930
Dino Myclee8843b32014-07-04 14:21:45 +05303931 reqMsg.sessionId = pAdapter->sessionId;
3932 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303933
3934 /* Parse and fetch flush parameter */
3935 if (!tb
3936 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3937 {
3938 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3939 goto failed;
3940 }
Dino Myclee8843b32014-07-04 14:21:45 +05303941 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303942 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3943
Dino Myclee8843b32014-07-04 14:21:45 +05303944 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303945
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303946 spin_lock(&hdd_context_lock);
3947 context = &pHddCtx->ext_scan_context;
3948 context->request_id = reqMsg.requestId;
3949 context->ignore_cached_results = false;
3950 INIT_COMPLETION(context->response_event);
3951 spin_unlock(&hdd_context_lock);
3952
Dino Myclee8843b32014-07-04 14:21:45 +05303953 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303954 if (!HAL_STATUS_SUCCESS(status)) {
3955 hddLog(VOS_TRACE_LEVEL_ERROR,
3956 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303957 return -EINVAL;
3958 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303959
3960 rc = wait_for_completion_timeout(&context->response_event,
3961 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3962 if (!rc) {
3963 hddLog(LOGE, FL("Target response timed out"));
3964 retval = -ETIMEDOUT;
3965 spin_lock(&hdd_context_lock);
3966 context->ignore_cached_results = true;
3967 spin_unlock(&hdd_context_lock);
3968 } else {
3969 spin_lock(&hdd_context_lock);
3970 retval = context->response_status;
3971 spin_unlock(&hdd_context_lock);
3972 }
3973
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303974 EXIT();
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303975 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303976
3977failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303978 return -EINVAL;
3979}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303980static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3981 struct wireless_dev *wdev,
3982 const void *data, int dataLen)
3983{
3984 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303985
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303986 vos_ssr_protect(__func__);
3987 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
3988 vos_ssr_unprotect(__func__);
3989
3990 return ret;
3991}
3992
3993static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303994 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05303995 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303996{
3997 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3998 struct net_device *dev = wdev->netdev;
3999 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4000 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4001 struct nlattr
4002 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4003 struct nlattr
4004 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4005 struct nlattr *apTh;
4006 eHalStatus status;
4007 tANI_U8 i = 0;
4008 int rem;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304009 struct hdd_ext_scan_context *context;
4010 tANI_U32 request_id;
4011 unsigned long rc;
4012 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304013
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304014 ENTER();
4015
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304016 if (VOS_FTM_MODE == hdd_get_conparam()) {
4017 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4018 return -EINVAL;
4019 }
4020
Dino Mycle6fb96c12014-06-10 11:52:40 +05304021 status = wlan_hdd_validate_context(pHddCtx);
4022 if (0 != status)
4023 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304024 return -EINVAL;
4025 }
Dino Myclee8843b32014-07-04 14:21:45 +05304026 /* check the EXTScan Capability */
4027 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304028 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4029 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304030 {
4031 hddLog(VOS_TRACE_LEVEL_ERROR,
4032 FL("EXTScan not enabled/supported by Firmware"));
4033 return -EINVAL;
4034 }
4035
Dino Mycle6fb96c12014-06-10 11:52:40 +05304036 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4037 data, dataLen,
4038 wlan_hdd_extscan_config_policy)) {
4039 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4040 return -EINVAL;
4041 }
4042
4043 /* Parse and fetch request Id */
4044 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4045 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4046 return -EINVAL;
4047 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304048 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
4049 vos_mem_malloc(sizeof(*pReqMsg));
4050 if (!pReqMsg) {
4051 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4052 return -ENOMEM;
4053 }
4054
Dino Myclee8843b32014-07-04 14:21:45 +05304055
Dino Mycle6fb96c12014-06-10 11:52:40 +05304056 pReqMsg->requestId = nla_get_u32(
4057 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4058 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4059
4060 /* Parse and fetch number of APs */
4061 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
4062 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
4063 goto fail;
4064 }
4065
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304066 /* Parse and fetch lost ap sample size */
4067 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]) {
4068 hddLog(LOGE, FL("attr lost ap sample size failed"));
4069 goto fail;
4070 }
4071
4072 pReqMsg->lostBssidSampleSize = nla_get_u32(
4073 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]);
4074 hddLog(LOG1, FL("Lost ap sample size %d"), pReqMsg->lostBssidSampleSize);
4075
Dino Mycle6fb96c12014-06-10 11:52:40 +05304076 pReqMsg->sessionId = pAdapter->sessionId;
4077 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4078
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304079 pReqMsg->numBssid = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304080 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304081 if (pReqMsg->numBssid > WLAN_EXTSCAN_MAX_HOTLIST_APS) {
4082 hddLog(LOGE, FL("Number of AP: %u exceeds max: %u"),
4083 pReqMsg->numBssid, WLAN_EXTSCAN_MAX_HOTLIST_APS);
4084 goto fail;
4085 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304086 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numBssid);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304087
4088 nla_for_each_nested(apTh,
4089 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304090 if (i == pReqMsg->numBssid) {
4091 hddLog(LOGW, FL("Ignoring excess AP"));
4092 break;
4093 }
4094
Dino Mycle6fb96c12014-06-10 11:52:40 +05304095 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4096 nla_data(apTh), nla_len(apTh),
4097 NULL)) {
4098 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
4099 goto fail;
4100 }
4101
4102 /* Parse and fetch MAC address */
4103 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
4104 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
4105 goto fail;
4106 }
4107 memcpy(pReqMsg->ap[i].bssid, nla_data(
4108 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
4109 sizeof(tSirMacAddr));
4110 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
4111
4112 /* Parse and fetch low RSSI */
4113 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
4114 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
4115 goto fail;
4116 }
4117 pReqMsg->ap[i].low = nla_get_s32(
4118 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
4119 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
4120
4121 /* Parse and fetch high RSSI */
4122 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
4123 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
4124 goto fail;
4125 }
4126 pReqMsg->ap[i].high = nla_get_s32(
4127 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
4128 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
4129 pReqMsg->ap[i].high);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304130 i++;
4131 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304132
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304133 if (i < pReqMsg->numBssid) {
4134 hddLog(LOGW, FL("Number of AP %u less than expected %u"),
4135 i, pReqMsg->numBssid);
4136 pReqMsg->numBssid = i;
4137 }
4138
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304139 context = &pHddCtx->ext_scan_context;
4140 spin_lock(&hdd_context_lock);
4141 INIT_COMPLETION(context->response_event);
4142 context->request_id = request_id = pReqMsg->requestId;
4143 spin_unlock(&hdd_context_lock);
4144
Dino Mycle6fb96c12014-06-10 11:52:40 +05304145 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
4146 if (!HAL_STATUS_SUCCESS(status)) {
4147 hddLog(VOS_TRACE_LEVEL_ERROR,
4148 FL("sme_SetBssHotlist failed(err=%d)"), status);
4149 vos_mem_free(pReqMsg);
4150 return -EINVAL;
4151 }
4152
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304153 /* request was sent -- wait for the response */
4154 rc = wait_for_completion_timeout(&context->response_event,
4155 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4156
4157 if (!rc) {
4158 hddLog(LOGE, FL("sme_SetBssHotlist timed out"));
4159 retval = -ETIMEDOUT;
4160 } else {
4161 spin_lock(&hdd_context_lock);
4162 if (context->request_id == request_id)
4163 retval = context->response_status;
4164 else
4165 retval = -EINVAL;
4166 spin_unlock(&hdd_context_lock);
4167 }
4168
Dino Myclee8843b32014-07-04 14:21:45 +05304169 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304170 EXIT();
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304171 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304172
4173fail:
4174 vos_mem_free(pReqMsg);
4175 return -EINVAL;
4176}
4177
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304178static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
4179 struct wireless_dev *wdev,
4180 const void *data, int dataLen)
4181{
4182 int ret = 0;
4183
4184 vos_ssr_protect(__func__);
4185 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
4186 dataLen);
4187 vos_ssr_unprotect(__func__);
4188
4189 return ret;
4190}
4191
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304192static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304193 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304194 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304195{
Agrawal Ashish16abf782016-08-18 22:42:59 +05304196 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4197 struct net_device *dev = wdev->netdev;
4198 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4199 uint32_t chan_list[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4200 uint8_t num_channels = 0;
4201 uint8_t num_chan_new = 0;
4202 uint8_t buf[256] = {0};
Dino Mycle6fb96c12014-06-10 11:52:40 +05304203 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304204 tANI_U32 requestId, maxChannels;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304205 tWifiBand wifiBand;
4206 eHalStatus status;
4207 struct sk_buff *replySkb;
Agrawal Ashish16abf782016-08-18 22:42:59 +05304208 tANI_U8 i,j,k;
4209 int ret,len = 0;;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304210
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304211 ENTER();
4212
Dino Mycle6fb96c12014-06-10 11:52:40 +05304213 status = wlan_hdd_validate_context(pHddCtx);
4214 if (0 != status)
4215 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304216 return -EINVAL;
4217 }
Dino Myclee8843b32014-07-04 14:21:45 +05304218
Dino Mycle6fb96c12014-06-10 11:52:40 +05304219 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4220 data, dataLen,
4221 wlan_hdd_extscan_config_policy)) {
4222 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4223 return -EINVAL;
4224 }
4225
4226 /* Parse and fetch request Id */
4227 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4228 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4229 return -EINVAL;
4230 }
4231 requestId = nla_get_u32(
4232 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4233 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
4234
4235 /* Parse and fetch wifi band */
4236 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
4237 {
4238 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4239 return -EINVAL;
4240 }
4241 wifiBand = nla_get_u32(
4242 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
4243 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
4244
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304245 /* Parse and fetch max channels */
4246 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
4247 {
4248 hddLog(LOGE, FL("attr max channels failed"));
4249 return -EINVAL;
4250 }
4251 maxChannels = nla_get_u32(
4252 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
4253 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);
4254
Dino Mycle6fb96c12014-06-10 11:52:40 +05304255 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
Agrawal Ashish16abf782016-08-18 22:42:59 +05304256 wifiBand, chan_list,
4257 &num_channels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304258 if (eHAL_STATUS_SUCCESS != status) {
4259 hddLog(VOS_TRACE_LEVEL_ERROR,
4260 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
4261 return -EINVAL;
4262 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304263
Agrawal Ashish16abf782016-08-18 22:42:59 +05304264 num_channels = VOS_MIN(num_channels, maxChannels);
4265 num_chan_new = num_channels;
4266 /* remove the indoor only channels if iface is SAP */
4267 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
4268 {
4269 num_chan_new = 0;
4270 for (i = 0; i < num_channels; i++)
4271 for (j = 0; j < IEEE80211_NUM_BANDS; j++) {
4272 if (wiphy->bands[j] == NULL)
4273 continue;
4274 for (k = 0; k < wiphy->bands[j]->n_channels; k++) {
4275 if ((chan_list[i] ==
4276 wiphy->bands[j]->channels[k].center_freq) &&
4277 (!(wiphy->bands[j]->channels[k].flags &
4278 IEEE80211_CHAN_INDOOR_ONLY))) {
4279 chan_list[num_chan_new] = chan_list[i];
4280 num_chan_new++;
4281 }
4282 }
4283 }
4284 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304285
Agrawal Ashish16abf782016-08-18 22:42:59 +05304286 hddLog(LOG1, FL("Number of channels: %d"), num_chan_new);
4287 for (i = 0; i < num_chan_new; i++)
4288 len += scnprintf(buf + len, sizeof(buf) - len, "%u ", chan_list[i]);
4289 hddLog(LOG1, "Channels: %s", buf);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304290
4291 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
Agrawal Ashish16abf782016-08-18 22:42:59 +05304292 sizeof(u32) * num_chan_new +
Dino Mycle6fb96c12014-06-10 11:52:40 +05304293 NLMSG_HDRLEN);
4294
4295 if (!replySkb) {
4296 hddLog(VOS_TRACE_LEVEL_ERROR,
4297 FL("valid channels: buffer alloc fail"));
4298 return -EINVAL;
4299 }
4300 if (nla_put_u32(replySkb,
4301 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304302 num_chan_new) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05304303 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304304 sizeof(u32) * num_chan_new, chan_list)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304305
4306 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4307 kfree_skb(replySkb);
4308 return -EINVAL;
4309 }
4310
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304311 ret = cfg80211_vendor_cmd_reply(replySkb);
4312
4313 EXIT();
4314 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304315}
4316
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304317static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
4318 struct wireless_dev *wdev,
4319 const void *data, int dataLen)
4320{
4321 int ret = 0;
4322
4323 vos_ssr_protect(__func__);
4324 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
4325 dataLen);
4326 vos_ssr_unprotect(__func__);
4327
4328 return ret;
4329}
4330
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304331static int hdd_extscan_start_fill_bucket_channel_spec(
4332 hdd_context_t *pHddCtx,
4333 tpSirEXTScanStartReqParams pReqMsg,
4334 struct nlattr **tb)
4335{
4336 struct nlattr *bucket[
4337 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4338 struct nlattr *channel[
4339 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4340 struct nlattr *buckets;
4341 struct nlattr *channels;
4342 int rem1, rem2;
4343 eHalStatus status;
4344 tANI_U8 bktIndex, j, numChannels;
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304345 uint32_t expected_buckets;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304346 tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4347 tANI_U32 passive_max_chn_time, active_max_chn_time;
4348
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304349 expected_buckets = pReqMsg->numBuckets;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304350 bktIndex = 0;
4351
4352 nla_for_each_nested(buckets,
4353 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304354 if (bktIndex >= expected_buckets) {
4355 hddLog(LOGW, FL("ignoring excess buckets"));
4356 break;
4357 }
4358
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304359 if (nla_parse(bucket,
Ashish Kumar Dhanotiya9c93f562017-06-20 12:13:33 +05304360 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4361 nla_data(buckets), nla_len(buckets),
4362 wlan_hdd_extscan_config_policy)) {
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304363 hddLog(LOGE, FL("nla_parse failed"));
4364 return -EINVAL;
4365 }
4366
4367 /* Parse and fetch bucket spec */
4368 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4369 hddLog(LOGE, FL("attr bucket index failed"));
4370 return -EINVAL;
4371 }
4372 pReqMsg->buckets[bktIndex].bucket = nla_get_u8(
4373 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4374 hddLog(LOG1, FL("Bucket spec Index %d"),
4375 pReqMsg->buckets[bktIndex].bucket);
4376
4377 /* Parse and fetch wifi band */
4378 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4379 hddLog(LOGE, FL("attr wifi band failed"));
4380 return -EINVAL;
4381 }
4382 pReqMsg->buckets[bktIndex].band = nla_get_u8(
4383 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4384 hddLog(LOG1, FL("Wifi band %d"),
4385 pReqMsg->buckets[bktIndex].band);
4386
4387 /* Parse and fetch period */
4388 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4389 hddLog(LOGE, FL("attr period failed"));
4390 return -EINVAL;
4391 }
4392 pReqMsg->buckets[bktIndex].period = nla_get_u32(
4393 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4394 hddLog(LOG1, FL("period %d"),
4395 pReqMsg->buckets[bktIndex].period);
4396
4397 /* Parse and fetch report events */
4398 if (!bucket[
4399 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4400 hddLog(LOGE, FL("attr report events failed"));
4401 return -EINVAL;
4402 }
4403 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
4404 bucket[
4405 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4406 hddLog(LOG1, FL("report events %d"),
4407 pReqMsg->buckets[bktIndex].reportEvents);
4408
4409 /* Parse and fetch max period */
4410 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
4411 hddLog(LOGE, FL("attr max period failed"));
4412 return -EINVAL;
4413 }
4414 pReqMsg->buckets[bktIndex].max_period = nla_get_u32(
4415 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);
4416 hddLog(LOG1, FL("max period %u"),
4417 pReqMsg->buckets[bktIndex].max_period);
4418
4419 /* Parse and fetch exponent */
4420 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
4421 hddLog(LOGE, FL("attr exponent failed"));
4422 return -EINVAL;
4423 }
4424 pReqMsg->buckets[bktIndex].exponent = nla_get_u32(
4425 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
4426 hddLog(LOG1, FL("exponent %u"),
4427 pReqMsg->buckets[bktIndex].exponent);
4428
4429 /* Parse and fetch step count */
4430 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
4431 hddLog(LOGE, FL("attr step count failed"));
4432 return -EINVAL;
4433 }
4434 pReqMsg->buckets[bktIndex].step_count = nla_get_u32(
4435 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
4436 hddLog(LOG1, FL("Step count %u"),
4437 pReqMsg->buckets[bktIndex].step_count);
4438
4439 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time);
4440 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time);
4441
4442 /* Framework shall pass the channel list if the input WiFi band is
4443 * WIFI_BAND_UNSPECIFIED.
4444 * If the input WiFi band is specified (any value other than
4445 * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
4446 */
4447 if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) {
4448 numChannels = 0;
4449 hddLog(LOG1, "WiFi band is specified, driver to fill channel list");
4450 status = sme_GetValidChannelsByBand(pHddCtx->hHal,
4451 pReqMsg->buckets[bktIndex].band,
4452 chanList, &numChannels);
4453 if (!HAL_STATUS_SUCCESS(status)) {
4454 hddLog(LOGE,
4455 FL("sme_GetValidChannelsByBand failed (err=%d)"),
4456 status);
4457 return -EINVAL;
4458 }
4459
4460 pReqMsg->buckets[bktIndex].numChannels =
4461 VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS);
4462 hddLog(LOG1, FL("Num channels %d"),
4463 pReqMsg->buckets[bktIndex].numChannels);
4464
4465 for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels;
4466 j++) {
4467 pReqMsg->buckets[bktIndex].channels[j].channel =
4468 chanList[j];
4469 pReqMsg->buckets[bktIndex].channels[j].
4470 chnlClass = 0;
4471 if (CSR_IS_CHANNEL_DFS(
4472 vos_freq_to_chan(chanList[j]))) {
4473 pReqMsg->buckets[bktIndex].channels[j].
4474 passive = 1;
4475 pReqMsg->buckets[bktIndex].channels[j].
4476 dwellTimeMs = passive_max_chn_time;
4477 } else {
4478 pReqMsg->buckets[bktIndex].channels[j].
4479 passive = 0;
4480 pReqMsg->buckets[bktIndex].channels[j].
4481 dwellTimeMs = active_max_chn_time;
4482 }
4483
4484 hddLog(LOG1,
4485 "Channel %u Passive %u Dwell time %u ms",
4486 pReqMsg->buckets[bktIndex].channels[j].channel,
4487 pReqMsg->buckets[bktIndex].channels[j].passive,
4488 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4489 }
4490
4491 bktIndex++;
4492 continue;
4493 }
4494
4495 /* Parse and fetch number of channels */
4496 if (!bucket[
4497 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
4498 hddLog(LOGE, FL("attr num channels failed"));
4499 return -EINVAL;
4500 }
4501
4502 pReqMsg->buckets[bktIndex].numChannels =
4503 nla_get_u32(bucket[
4504 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
4505 hddLog(LOG1, FL("num channels %d"),
4506 pReqMsg->buckets[bktIndex].numChannels);
4507
4508 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
4509 hddLog(LOGE, FL("attr channel spec failed"));
4510 return -EINVAL;
4511 }
4512
4513 j = 0;
4514 nla_for_each_nested(channels,
4515 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
4516 if (nla_parse(channel,
4517 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4518 nla_data(channels), nla_len(channels),
4519 wlan_hdd_extscan_config_policy)) {
4520 hddLog(LOGE, FL("nla_parse failed"));
4521 return -EINVAL;
4522 }
4523
4524 /* Parse and fetch channel */
4525 if (!channel[
4526 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
4527 hddLog(LOGE, FL("attr channel failed"));
4528 return -EINVAL;
4529 }
4530 pReqMsg->buckets[bktIndex].channels[j].channel =
4531 nla_get_u32(channel[
4532 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
4533 hddLog(LOG1, FL("channel %u"),
4534 pReqMsg->buckets[bktIndex].channels[j].channel);
4535
4536 /* Parse and fetch dwell time */
4537 if (!channel[
4538 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
4539 hddLog(LOGE, FL("attr dwelltime failed"));
4540 return -EINVAL;
4541 }
4542 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
4543 nla_get_u32(channel[
4544 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
4545
4546 hddLog(LOG1, FL("Dwell time (%u ms)"),
4547 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4548
4549
4550 /* Parse and fetch channel spec passive */
4551 if (!channel[
4552 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
4553 hddLog(LOGE,
4554 FL("attr channel spec passive failed"));
4555 return -EINVAL;
4556 }
4557 pReqMsg->buckets[bktIndex].channels[j].passive =
4558 nla_get_u8(channel[
4559 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
4560 hddLog(LOG1, FL("Chnl spec passive %u"),
4561 pReqMsg->buckets[bktIndex].channels[j].passive);
4562
4563 j++;
4564 }
4565
4566 bktIndex++;
4567 }
4568
4569 return 0;
4570}
4571
4572
4573/*
4574 * define short names for the global vendor params
4575 * used by wlan_hdd_cfg80211_extscan_start()
4576 */
4577#define PARAM_MAX \
4578QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
4579#define PARAM_REQUEST_ID \
4580QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
4581#define PARAM_BASE_PERIOD \
4582QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
4583#define PARAM_MAX_AP_PER_SCAN \
4584QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
4585#define PARAM_RPT_THRHLD_PERCENT \
4586QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
4587#define PARAM_RPT_THRHLD_NUM_SCANS \
4588QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
4589#define PARAM_NUM_BUCKETS \
4590QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
4591
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304592static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304593 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304594 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304595{
Dino Myclee8843b32014-07-04 14:21:45 +05304596 tpSirEXTScanStartReqParams pReqMsg = NULL;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304597 struct net_device *dev = wdev->netdev;
4598 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4599 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4600 struct nlattr *tb[PARAM_MAX + 1];
4601 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304602 eHalStatus status;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304603 tANI_U32 request_id;
4604 struct hdd_ext_scan_context *context;
4605 unsigned long rc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304606
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304607 ENTER();
4608
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304609 if (VOS_FTM_MODE == hdd_get_conparam()) {
4610 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4611 return -EINVAL;
4612 }
4613
Dino Mycle6fb96c12014-06-10 11:52:40 +05304614 status = wlan_hdd_validate_context(pHddCtx);
4615 if (0 != status)
4616 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304617 return -EINVAL;
4618 }
Dino Myclee8843b32014-07-04 14:21:45 +05304619 /* check the EXTScan Capability */
4620 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304621 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4622 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304623 {
4624 hddLog(VOS_TRACE_LEVEL_ERROR,
4625 FL("EXTScan not enabled/supported by Firmware"));
4626 return -EINVAL;
4627 }
4628
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304629 if (nla_parse(tb, PARAM_MAX,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304630 data, dataLen,
4631 wlan_hdd_extscan_config_policy)) {
4632 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4633 return -EINVAL;
4634 }
4635
4636 /* Parse and fetch request Id */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304637 if (!tb[PARAM_REQUEST_ID]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304638 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4639 return -EINVAL;
4640 }
4641
Dino Myclee8843b32014-07-04 14:21:45 +05304642 pReqMsg = (tpSirEXTScanStartReqParams)
4643 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304644 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05304645 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4646 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304647 }
4648
4649 pReqMsg->requestId = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304650 tb[PARAM_REQUEST_ID]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304651 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4652
4653 pReqMsg->sessionId = pAdapter->sessionId;
4654 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4655
4656 /* Parse and fetch base period */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304657 if (!tb[PARAM_BASE_PERIOD]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304658 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
4659 goto fail;
4660 }
4661 pReqMsg->basePeriod = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304662 tb[PARAM_BASE_PERIOD]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304663 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
4664 pReqMsg->basePeriod);
4665
4666 /* Parse and fetch max AP per scan */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304667 if (!tb[PARAM_MAX_AP_PER_SCAN]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304668 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
4669 goto fail;
4670 }
4671 pReqMsg->maxAPperScan = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304672 tb[PARAM_MAX_AP_PER_SCAN]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304673 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
4674 pReqMsg->maxAPperScan);
4675
4676 /* Parse and fetch report threshold */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304677 if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304678 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
4679 goto fail;
4680 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304681 pReqMsg->reportThresholdPercent = nla_get_u8(
4682 tb[PARAM_RPT_THRHLD_PERCENT]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304683 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304684 pReqMsg->reportThresholdPercent);
4685
4686 /* Parse and fetch report threshold num scans */
4687 if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
4688 hddLog(LOGE, FL("attr report_threshold num scans failed"));
4689 goto fail;
4690 }
4691 pReqMsg->reportThresholdNumScans = nla_get_u8(
4692 tb[PARAM_RPT_THRHLD_NUM_SCANS]);
4693 hddLog(LOG1, FL("Report Threshold num scans %d"),
4694 pReqMsg->reportThresholdNumScans);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304695
4696 /* Parse and fetch number of buckets */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304697 if (!tb[PARAM_NUM_BUCKETS]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304698 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
4699 goto fail;
4700 }
4701 pReqMsg->numBuckets = nla_get_u8(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304702 tb[PARAM_NUM_BUCKETS]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304703 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
4704 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
4705 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
4706 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
4707 }
4708 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
4709 pReqMsg->numBuckets);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304710
Dino Mycle6fb96c12014-06-10 11:52:40 +05304711 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
4712 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
4713 goto fail;
4714 }
4715
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304716 pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304717
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304718 if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
4719 goto fail;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304720
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304721 context = &pHddCtx->ext_scan_context;
4722 spin_lock(&hdd_context_lock);
4723 INIT_COMPLETION(context->response_event);
4724 context->request_id = request_id = pReqMsg->requestId;
4725 spin_unlock(&hdd_context_lock);
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304726
Dino Mycle6fb96c12014-06-10 11:52:40 +05304727 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
4728 if (!HAL_STATUS_SUCCESS(status)) {
4729 hddLog(VOS_TRACE_LEVEL_ERROR,
4730 FL("sme_EXTScanStart failed(err=%d)"), status);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304731 goto fail;
4732 }
4733
Srinivas Dasari91727c12016-03-23 17:59:06 +05304734 pHddCtx->extscan_start_time_since_boot = vos_get_monotonic_boottime();
4735
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304736 /* request was sent -- wait for the response */
4737 rc = wait_for_completion_timeout(&context->response_event,
4738 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4739
4740 if (!rc) {
4741 hddLog(LOGE, FL("sme_ExtScanStart timed out"));
4742 retval = -ETIMEDOUT;
4743 } else {
4744 spin_lock(&hdd_context_lock);
4745 if (context->request_id == request_id)
4746 retval = context->response_status;
4747 else
4748 retval = -EINVAL;
4749 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304750 }
4751
Dino Myclee8843b32014-07-04 14:21:45 +05304752 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304753 EXIT();
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304754 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304755
4756fail:
4757 vos_mem_free(pReqMsg);
4758 return -EINVAL;
4759}
4760
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304761/*
4762 * done with short names for the global vendor params
4763 * used by wlan_hdd_cfg80211_extscan_start()
4764 */
4765#undef PARAM_MAX
4766#undef PARAM_REQUEST_ID
4767#undef PARAM_BASE_PERIOD
4768#undef PARAMS_MAX_AP_PER_SCAN
4769#undef PARAMS_RPT_THRHLD_PERCENT
4770#undef PARAMS_RPT_THRHLD_NUM_SCANS
4771#undef PARAMS_NUM_BUCKETS
4772
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304773static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
4774 struct wireless_dev *wdev,
4775 const void *data, int dataLen)
4776{
4777 int ret = 0;
4778
4779 vos_ssr_protect(__func__);
4780 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
4781 vos_ssr_unprotect(__func__);
4782
4783 return ret;
4784}
4785
4786static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304787 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304788 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304789{
Dino Myclee8843b32014-07-04 14:21:45 +05304790 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304791 struct net_device *dev = wdev->netdev;
4792 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4793 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4794 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4795 eHalStatus status;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304796 int retval;
4797 unsigned long rc;
4798 struct hdd_ext_scan_context *context;
4799 tANI_U32 request_id;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304800
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304801 ENTER();
4802
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304803 if (VOS_FTM_MODE == hdd_get_conparam()) {
4804 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4805 return -EINVAL;
4806 }
4807
Dino Mycle6fb96c12014-06-10 11:52:40 +05304808 status = wlan_hdd_validate_context(pHddCtx);
4809 if (0 != status)
4810 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304811 return -EINVAL;
4812 }
Dino Myclee8843b32014-07-04 14:21:45 +05304813 /* check the EXTScan Capability */
4814 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304815 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4816 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304817 {
4818 hddLog(VOS_TRACE_LEVEL_ERROR,
4819 FL("EXTScan not enabled/supported by Firmware"));
4820 return -EINVAL;
4821 }
4822
Dino Mycle6fb96c12014-06-10 11:52:40 +05304823 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4824 data, dataLen,
4825 wlan_hdd_extscan_config_policy)) {
4826 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4827 return -EINVAL;
4828 }
4829
4830 /* Parse and fetch request Id */
4831 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4832 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4833 return -EINVAL;
4834 }
4835
Dino Myclee8843b32014-07-04 14:21:45 +05304836 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304837 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304838 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304839
Dino Myclee8843b32014-07-04 14:21:45 +05304840 reqMsg.sessionId = pAdapter->sessionId;
4841 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304842
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304843 context = &pHddCtx->ext_scan_context;
4844 spin_lock(&hdd_context_lock);
4845 INIT_COMPLETION(context->response_event);
Sravanti Palakonda7539fb92016-02-26 17:49:21 +05304846 context->request_id = request_id = reqMsg.requestId;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304847 spin_unlock(&hdd_context_lock);
4848
Dino Myclee8843b32014-07-04 14:21:45 +05304849 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304850 if (!HAL_STATUS_SUCCESS(status)) {
4851 hddLog(VOS_TRACE_LEVEL_ERROR,
4852 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304853 return -EINVAL;
4854 }
4855
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304856 /* request was sent -- wait for the response */
4857 rc = wait_for_completion_timeout(&context->response_event,
4858 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4859
4860 if (!rc) {
4861 hddLog(LOGE, FL("sme_ExtScanStop timed out"));
4862 retval = -ETIMEDOUT;
4863 } else {
4864 spin_lock(&hdd_context_lock);
4865 if (context->request_id == request_id)
4866 retval = context->response_status;
4867 else
4868 retval = -EINVAL;
4869 spin_unlock(&hdd_context_lock);
4870 }
4871
4872 return retval;
4873
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304874 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304875 return 0;
4876}
4877
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304878static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
4879 struct wireless_dev *wdev,
4880 const void *data, int dataLen)
4881{
4882 int ret = 0;
4883
4884 vos_ssr_protect(__func__);
4885 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
4886 vos_ssr_unprotect(__func__);
4887
4888 return ret;
4889}
4890
4891static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304892 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304893 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304894{
Dino Myclee8843b32014-07-04 14:21:45 +05304895 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304896 struct net_device *dev = wdev->netdev;
4897 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4898 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4899 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4900 eHalStatus status;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304901 struct hdd_ext_scan_context *context;
4902 tANI_U32 request_id;
4903 unsigned long rc;
4904 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304905
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304906 ENTER();
4907
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304908 if (VOS_FTM_MODE == hdd_get_conparam()) {
4909 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4910 return -EINVAL;
4911 }
4912
Dino Mycle6fb96c12014-06-10 11:52:40 +05304913 status = wlan_hdd_validate_context(pHddCtx);
4914 if (0 != status)
4915 {
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304916 hddLog(LOGE, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304917 return -EINVAL;
4918 }
Dino Myclee8843b32014-07-04 14:21:45 +05304919 /* check the EXTScan Capability */
4920 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304921 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4922 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304923 {
4924 hddLog(VOS_TRACE_LEVEL_ERROR,
4925 FL("EXTScan not enabled/supported by Firmware"));
4926 return -EINVAL;
4927 }
4928
Dino Mycle6fb96c12014-06-10 11:52:40 +05304929 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4930 data, dataLen,
4931 wlan_hdd_extscan_config_policy)) {
4932 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4933 return -EINVAL;
4934 }
4935
4936 /* Parse and fetch request Id */
4937 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4938 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4939 return -EINVAL;
4940 }
4941
Dino Myclee8843b32014-07-04 14:21:45 +05304942 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304943 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304944 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304945
Dino Myclee8843b32014-07-04 14:21:45 +05304946 reqMsg.sessionId = pAdapter->sessionId;
4947 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304948
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304949 context = &pHddCtx->ext_scan_context;
4950 spin_lock(&hdd_context_lock);
4951 INIT_COMPLETION(context->response_event);
4952 context->request_id = request_id = reqMsg.requestId;
4953 spin_unlock(&hdd_context_lock);
4954
Dino Myclee8843b32014-07-04 14:21:45 +05304955 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304956 if (!HAL_STATUS_SUCCESS(status)) {
4957 hddLog(VOS_TRACE_LEVEL_ERROR,
4958 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304959 return -EINVAL;
4960 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304961
4962 /* request was sent -- wait for the response */
4963 rc = wait_for_completion_timeout(&context->response_event,
4964 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4965 if (!rc) {
4966 hddLog(LOGE, FL("sme_ResetBssHotlist timed out"));
4967 retval = -ETIMEDOUT;
4968 } else {
4969 spin_lock(&hdd_context_lock);
4970 if (context->request_id == request_id)
4971 retval = context->response_status;
4972 else
4973 retval = -EINVAL;
4974 spin_unlock(&hdd_context_lock);
4975 }
4976
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304977 EXIT();
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304978 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304979}
4980
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304981static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
4982 struct wireless_dev *wdev,
4983 const void *data, int dataLen)
4984{
4985 int ret = 0;
4986
4987 vos_ssr_protect(__func__);
4988 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
4989 vos_ssr_unprotect(__func__);
4990
4991 return ret;
4992}
Dino Mycle6fb96c12014-06-10 11:52:40 +05304993#endif /* WLAN_FEATURE_EXTSCAN */
4994
Atul Mittal115287b2014-07-08 13:26:33 +05304995/*EXT TDLS*/
4996static const struct nla_policy
4997wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
4998{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05304999 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {
5000 .type = NLA_UNSPEC,
5001 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305002 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
5003 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
5004 {.type = NLA_S32 },
5005 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
5006 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
5007
5008};
5009
5010static const struct nla_policy
5011wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
5012{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305013 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {
5014 .type = NLA_UNSPEC,
5015 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305016
5017};
5018
5019static const struct nla_policy
5020wlan_hdd_tdls_config_state_change_policy[
5021 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
5022{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305023 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {
5024 .type = NLA_UNSPEC,
5025 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305026 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
5027 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305028 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
5029 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
5030 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305031
5032};
5033
5034static const struct nla_policy
5035wlan_hdd_tdls_config_get_status_policy[
5036 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
5037{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305038 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {
5039 .type = NLA_UNSPEC,
5040 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305041 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
5042 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305043 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
5044 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
5045 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305046
5047};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305048
5049static const struct nla_policy
5050wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
5051{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305052 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {
5053 .type = NLA_UNSPEC,
5054 .len = VOS_MAC_ADDR_FIRST_3_BYTES},
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305055};
5056
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305057static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305058 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305059 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305060 int data_len)
5061{
5062
5063 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5064 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
5065
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305066 ENTER();
5067
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305068 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305069 return -EINVAL;
5070 }
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +05305071 if (0 == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05305072 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305073 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05305074 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305075 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05305076 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305077 return -ENOTSUPP;
5078 }
5079
5080 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
5081 data, data_len, wlan_hdd_mac_config)) {
5082 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5083 return -EINVAL;
5084 }
5085
5086 /* Parse and fetch mac address */
5087 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
5088 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5089 return -EINVAL;
5090 }
5091
5092 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
5093 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5094 VOS_MAC_ADDR_LAST_3_BYTES);
5095
Siddharth Bhal76972212014-10-15 16:22:51 +05305096 pHddCtx->spoofMacAddr.isEnabled = TRUE;
5097
5098 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305099 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5100 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05305101 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
5102 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
5103 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
5104 {
5105 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
5106 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
5107 VOS_MAC_ADDRESS_LEN);
5108 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305109 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305110
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +05305111 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
5112 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305113
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305114 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305115 return 0;
5116}
5117
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305118static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
5119 struct wireless_dev *wdev,
5120 const void *data,
5121 int data_len)
5122{
5123 int ret = 0;
5124
5125 vos_ssr_protect(__func__);
5126 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
5127 vos_ssr_unprotect(__func__);
5128
5129 return ret;
5130}
5131
5132static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305133 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305134 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305135 int data_len)
5136{
5137 u8 peer[6] = {0};
5138 struct net_device *dev = wdev->netdev;
5139 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5140 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5141 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
5142 eHalStatus ret;
5143 tANI_S32 state;
5144 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305145 tANI_S32 global_operating_class = 0;
5146 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05305147 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305148 int retVal;
5149
5150 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305151
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305152 if (!pAdapter) {
5153 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5154 return -EINVAL;
5155 }
5156
Atul Mittal115287b2014-07-08 13:26:33 +05305157 ret = wlan_hdd_validate_context(pHddCtx);
5158 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305159 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305160 return -EINVAL;
5161 }
5162 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305163 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305164 return -ENOTSUPP;
5165 }
5166 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
5167 data, data_len,
5168 wlan_hdd_tdls_config_get_status_policy)) {
5169 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5170 return -EINVAL;
5171 }
5172
5173 /* Parse and fetch mac address */
5174 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
5175 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5176 return -EINVAL;
5177 }
5178
5179 memcpy(peer, nla_data(
5180 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
5181 sizeof(peer));
5182 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5183
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05305184 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05305185
Atul Mittal115287b2014-07-08 13:26:33 +05305186 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305187 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05305188 NLMSG_HDRLEN);
5189
5190 if (!skb) {
5191 hddLog(VOS_TRACE_LEVEL_ERROR,
5192 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5193 return -EINVAL;
5194 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305195 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reason (%d) Status (%d) class (%d) channel (%d) peer" MAC_ADDRESS_STR),
Atul Mittal115287b2014-07-08 13:26:33 +05305196 reason,
5197 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305198 global_operating_class,
5199 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05305200 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305201 if (nla_put_s32(skb,
5202 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
5203 state) ||
5204 nla_put_s32(skb,
5205 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
5206 reason) ||
5207 nla_put_s32(skb,
5208 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
5209 global_operating_class) ||
5210 nla_put_s32(skb,
5211 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
5212 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05305213
5214 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5215 goto nla_put_failure;
5216 }
5217
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305218 retVal = cfg80211_vendor_cmd_reply(skb);
5219 EXIT();
5220 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05305221
5222nla_put_failure:
5223 kfree_skb(skb);
5224 return -EINVAL;
5225}
5226
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305227static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
5228 struct wireless_dev *wdev,
5229 const void *data,
5230 int data_len)
5231{
5232 int ret = 0;
5233
5234 vos_ssr_protect(__func__);
5235 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
5236 vos_ssr_unprotect(__func__);
5237
5238 return ret;
5239}
5240
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05305241static int wlan_hdd_cfg80211_exttdls_callback(
5242#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
5243 const tANI_U8* mac,
5244#else
5245 tANI_U8* mac,
5246#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305247 tANI_S32 state,
5248 tANI_S32 reason,
5249 void *ctx)
5250{
5251 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05305252 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305253 tANI_S32 global_operating_class = 0;
5254 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305255 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05305256
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305257 ENTER();
5258
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305259 if (!pAdapter) {
5260 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5261 return -EINVAL;
5262 }
5263
5264 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05305265 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305266 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305267 return -EINVAL;
5268 }
5269
5270 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305271 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305272 return -ENOTSUPP;
5273 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05305274 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
5275#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
5276 NULL,
5277#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305278 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
5279 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
5280 GFP_KERNEL);
5281
5282 if (!skb) {
5283 hddLog(VOS_TRACE_LEVEL_ERROR,
5284 FL("cfg80211_vendor_event_alloc failed"));
5285 return -EINVAL;
5286 }
5287 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305288 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
5289 reason,
5290 state,
5291 global_operating_class,
5292 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05305293 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
5294 MAC_ADDR_ARRAY(mac));
5295
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305296 if (nla_put(skb,
5297 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
5298 VOS_MAC_ADDR_SIZE, mac) ||
5299 nla_put_s32(skb,
5300 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
5301 state) ||
5302 nla_put_s32(skb,
5303 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
5304 reason) ||
5305 nla_put_s32(skb,
5306 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
5307 channel) ||
5308 nla_put_s32(skb,
5309 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
5310 global_operating_class)
5311 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05305312 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5313 goto nla_put_failure;
5314 }
5315
5316 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305317 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05305318 return (0);
5319
5320nla_put_failure:
5321 kfree_skb(skb);
5322 return -EINVAL;
5323}
5324
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305325static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305326 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305327 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305328 int data_len)
5329{
5330 u8 peer[6] = {0};
5331 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305332 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5333 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
5334 eHalStatus status;
5335 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305336 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305337 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305338
5339 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305340
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305341 if (!dev) {
5342 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5343 return -EINVAL;
5344 }
5345
5346 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5347 if (!pAdapter) {
5348 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5349 return -EINVAL;
5350 }
5351
Atul Mittal115287b2014-07-08 13:26:33 +05305352 status = wlan_hdd_validate_context(pHddCtx);
5353 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305354 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305355 return -EINVAL;
5356 }
5357 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305358 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305359 return -ENOTSUPP;
5360 }
5361 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
5362 data, data_len,
5363 wlan_hdd_tdls_config_enable_policy)) {
5364 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5365 return -EINVAL;
5366 }
5367
5368 /* Parse and fetch mac address */
5369 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
5370 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5371 return -EINVAL;
5372 }
5373
5374 memcpy(peer, nla_data(
5375 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
5376 sizeof(peer));
5377 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5378
5379 /* Parse and fetch channel */
5380 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
5381 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
5382 return -EINVAL;
5383 }
5384 pReqMsg.channel = nla_get_s32(
5385 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
5386 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
5387
5388 /* Parse and fetch global operating class */
5389 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
5390 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
5391 return -EINVAL;
5392 }
5393 pReqMsg.global_operating_class = nla_get_s32(
5394 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
5395 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
5396 pReqMsg.global_operating_class);
5397
5398 /* Parse and fetch latency ms */
5399 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
5400 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
5401 return -EINVAL;
5402 }
5403 pReqMsg.max_latency_ms = nla_get_s32(
5404 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
5405 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
5406 pReqMsg.max_latency_ms);
5407
5408 /* Parse and fetch required bandwidth kbps */
5409 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
5410 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
5411 return -EINVAL;
5412 }
5413
5414 pReqMsg.min_bandwidth_kbps = nla_get_s32(
5415 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
5416 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
5417 pReqMsg.min_bandwidth_kbps);
5418
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305419 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05305420 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05305421 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305422 wlan_hdd_cfg80211_exttdls_callback);
5423
5424 EXIT();
5425 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305426}
5427
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305428static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
5429 struct wireless_dev *wdev,
5430 const void *data,
5431 int data_len)
5432{
5433 int ret = 0;
5434
5435 vos_ssr_protect(__func__);
5436 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
5437 vos_ssr_unprotect(__func__);
5438
5439 return ret;
5440}
5441
5442static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305443 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305444 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305445 int data_len)
5446{
5447 u8 peer[6] = {0};
5448 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305449 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5450 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
5451 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305452 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305453 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305454
5455 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305456
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305457 if (!dev) {
5458 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5459 return -EINVAL;
5460 }
5461
5462 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5463 if (!pAdapter) {
5464 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
5465 return -EINVAL;
5466 }
5467
Atul Mittal115287b2014-07-08 13:26:33 +05305468 status = wlan_hdd_validate_context(pHddCtx);
5469 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305470 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305471 return -EINVAL;
5472 }
5473 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305474 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305475 return -ENOTSUPP;
5476 }
5477 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
5478 data, data_len,
5479 wlan_hdd_tdls_config_disable_policy)) {
5480 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5481 return -EINVAL;
5482 }
5483 /* Parse and fetch mac address */
5484 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
5485 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5486 return -EINVAL;
5487 }
5488
5489 memcpy(peer, nla_data(
5490 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
5491 sizeof(peer));
5492 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5493
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305494 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
5495
5496 EXIT();
5497 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305498}
5499
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305500static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
5501 struct wireless_dev *wdev,
5502 const void *data,
5503 int data_len)
5504{
5505 int ret = 0;
5506
5507 vos_ssr_protect(__func__);
5508 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
5509 vos_ssr_unprotect(__func__);
5510
5511 return ret;
5512}
5513
Dasari Srinivas7875a302014-09-26 17:50:57 +05305514static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305515__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05305516 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305517 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05305518{
5519 struct net_device *dev = wdev->netdev;
5520 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5521 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5522 struct sk_buff *skb = NULL;
5523 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305524 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305525
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305526 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305527
5528 ret = wlan_hdd_validate_context(pHddCtx);
5529 if (0 != ret)
5530 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305531 return ret;
5532 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305533 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
5534 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
5535 fset |= WIFI_FEATURE_INFRA;
5536 }
5537
5538 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
5539 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
5540 fset |= WIFI_FEATURE_INFRA_5G;
5541 }
5542
5543#ifdef WLAN_FEATURE_P2P
5544 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
5545 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
5546 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
5547 fset |= WIFI_FEATURE_P2P;
5548 }
5549#endif
5550
5551 /* Soft-AP is supported currently by default */
5552 fset |= WIFI_FEATURE_SOFT_AP;
5553
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05305554 /* HOTSPOT is a supplicant feature, enable it by default */
5555 fset |= WIFI_FEATURE_HOTSPOT;
5556
Dasari Srinivas7875a302014-09-26 17:50:57 +05305557#ifdef WLAN_FEATURE_EXTSCAN
5558 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305559 sme_IsFeatureSupportedByFW(EXTENDED_SCAN) &&
5560 sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)) {
5561 hddLog(LOG1, FL("Enhanced EXTScan is supported by firmware"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05305562 fset |= WIFI_FEATURE_EXTSCAN;
5563 }
5564#endif
5565
Dasari Srinivas7875a302014-09-26 17:50:57 +05305566 if (sme_IsFeatureSupportedByFW(NAN)) {
5567 hddLog(LOG1, FL("NAN is supported by firmware"));
5568 fset |= WIFI_FEATURE_NAN;
5569 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305570
5571 /* D2D RTT is not supported currently by default */
5572 if (sme_IsFeatureSupportedByFW(RTT)) {
5573 hddLog(LOG1, FL("RTT is supported by firmware"));
5574 fset |= WIFI_FEATURE_D2AP_RTT;
5575 }
5576
Padma, Santhosh Kumaraac4c4d2015-12-08 16:07:47 +05305577 if (sme_IsFeatureSupportedByFW(RTT3)) {
5578 hddLog(LOG1, FL("RTT3 is supported by firmware"));
5579 fset |= WIFI_FEATURE_RTT3;
5580 }
5581
Dasari Srinivas7875a302014-09-26 17:50:57 +05305582#ifdef FEATURE_WLAN_BATCH_SCAN
5583 if (fset & WIFI_FEATURE_EXTSCAN) {
5584 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
5585 fset &= ~WIFI_FEATURE_BATCH_SCAN;
5586 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
5587 hddLog(LOG1, FL("Batch scan is supported by firmware"));
5588 fset |= WIFI_FEATURE_BATCH_SCAN;
5589 }
5590#endif
5591
5592#ifdef FEATURE_WLAN_SCAN_PNO
5593 if (pHddCtx->cfg_ini->configPNOScanSupport &&
5594 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
5595 hddLog(LOG1, FL("PNO is supported by firmware"));
5596 fset |= WIFI_FEATURE_PNO;
5597 }
5598#endif
5599
5600 /* STA+STA is supported currently by default */
5601 fset |= WIFI_FEATURE_ADDITIONAL_STA;
5602
5603#ifdef FEATURE_WLAN_TDLS
5604 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
5605 sme_IsFeatureSupportedByFW(TDLS)) {
5606 hddLog(LOG1, FL("TDLS is supported by firmware"));
5607 fset |= WIFI_FEATURE_TDLS;
5608 }
5609
5610 /* TDLS_OFFCHANNEL is not supported currently by default */
5611#endif
5612
5613#ifdef WLAN_AP_STA_CONCURRENCY
5614 /* AP+STA concurrency is supported currently by default */
5615 fset |= WIFI_FEATURE_AP_STA;
5616#endif
5617
Mukul Sharma5add0532015-08-17 15:57:47 +05305618#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5619 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
5620 hddLog(LOG1, FL("Link layer stats is supported by driver"));
5621#endif
5622
Dasari Srinivas7875a302014-09-26 17:50:57 +05305623 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
5624 NLMSG_HDRLEN);
5625
5626 if (!skb) {
5627 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5628 return -EINVAL;
5629 }
5630 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
5631
5632 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
5633 hddLog(LOGE, FL("nla put fail"));
5634 goto nla_put_failure;
5635 }
5636
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305637 ret = cfg80211_vendor_cmd_reply(skb);
5638 EXIT();
5639 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305640
5641nla_put_failure:
5642 kfree_skb(skb);
5643 return -EINVAL;
5644}
5645
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305646static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305647wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
5648 struct wireless_dev *wdev,
5649 const void *data, int data_len)
5650{
5651 int ret = 0;
5652
5653 vos_ssr_protect(__func__);
5654 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
5655 vos_ssr_unprotect(__func__);
5656
5657 return ret;
5658}
5659
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305660
5661static const struct
5662nla_policy
5663qca_wlan_vendor_wifi_logger_get_ring_data_policy
5664[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1] = {
5665 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]
5666 = {.type = NLA_U32 },
5667};
5668
5669static int
5670 __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
5671 struct wireless_dev *wdev,
5672 const void *data,
5673 int data_len)
5674{
5675 int ret;
5676 VOS_STATUS status;
5677 uint32_t ring_id;
5678 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5679 struct nlattr *tb
5680 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1];
5681
5682 ENTER();
5683
5684 ret = wlan_hdd_validate_context(hdd_ctx);
5685 if (0 != ret) {
5686 return ret;
5687 }
5688
5689 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX,
5690 data, data_len,
5691 qca_wlan_vendor_wifi_logger_get_ring_data_policy)) {
5692 hddLog(LOGE, FL("Invalid attribute"));
5693 return -EINVAL;
5694 }
5695
5696 /* Parse and fetch ring id */
5697 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]) {
5698 hddLog(LOGE, FL("attr ATTR failed"));
5699 return -EINVAL;
5700 }
5701
5702 ring_id = nla_get_u32(
5703 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]);
5704
5705 hddLog(LOG1, FL("Bug report triggered by framework"));
5706
5707 status = vos_fatal_event_logs_req(WLAN_LOG_TYPE_NON_FATAL,
5708 WLAN_LOG_INDICATOR_FRAMEWORK,
5709 WLAN_LOG_REASON_CODE_FRAMEWORK,
Abhishek Singh837adf22015-10-01 17:37:37 +05305710 TRUE, TRUE
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305711 );
5712 if (VOS_STATUS_SUCCESS != status) {
5713 hddLog(LOGE, FL("Failed to trigger bug report"));
5714
5715 return -EINVAL;
5716 }
5717
5718 return 0;
5719
5720
5721}
5722
5723
5724static int
5725 wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
5726 struct wireless_dev *wdev,
5727 const void *data,
5728 int data_len)
5729{
5730 int ret = 0;
5731
5732 vos_ssr_protect(__func__);
5733 ret = __wlan_hdd_cfg80211_wifi_logger_get_ring_data(wiphy,
5734 wdev, data, data_len);
5735 vos_ssr_unprotect(__func__);
5736
5737 return ret;
5738
5739}
5740
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05305741#define MAX_CONCURRENT_MATRIX \
5742 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX
5743#define MATRIX_CONFIG_PARAM_SET_SIZE_MAX \
5744 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX
5745static const struct nla_policy
5746wlan_hdd_get_concurrency_matrix_policy[MAX_CONCURRENT_MATRIX + 1] = {
5747 [MATRIX_CONFIG_PARAM_SET_SIZE_MAX] = {.type = NLA_U32},
5748};
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305749
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305750static int
5751__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305752 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305753 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305754{
5755 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
5756 uint8_t i, feature_sets, max_feature_sets;
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05305757 struct nlattr *tb[MAX_CONCURRENT_MATRIX + 1];
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305758 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305759 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5760 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305761
5762 ENTER();
5763
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305764 ret = wlan_hdd_validate_context(pHddCtx);
5765 if (0 != ret)
5766 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305767 return ret;
5768 }
5769
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05305770 if (nla_parse(tb, MAX_CONCURRENT_MATRIX, data, data_len,
5771 wlan_hdd_get_concurrency_matrix_policy)) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305772 hddLog(LOGE, FL("Invalid ATTR"));
5773 return -EINVAL;
5774 }
5775
5776 /* Parse and fetch max feature set */
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05305777 if (!tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305778 hddLog(LOGE, FL("Attr max feature set size failed"));
5779 return -EINVAL;
5780 }
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05305781 max_feature_sets = nla_get_u32(tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305782 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
5783
5784 /* Fill feature combination matrix */
5785 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305786 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5787 WIFI_FEATURE_P2P;
5788
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305789 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5790 WIFI_FEATURE_SOFT_AP;
5791
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305792 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
5793 WIFI_FEATURE_SOFT_AP;
5794
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305795 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5796 WIFI_FEATURE_SOFT_AP |
5797 WIFI_FEATURE_P2P;
5798
5799 /* Add more feature combinations here */
5800
5801 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
5802 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
5803 hddLog(LOG1, "Feature set matrix");
5804 for (i = 0; i < feature_sets; i++)
5805 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
5806
5807 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
5808 sizeof(u32) * feature_sets +
5809 NLMSG_HDRLEN);
5810
5811 if (reply_skb) {
5812 if (nla_put_u32(reply_skb,
5813 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
5814 feature_sets) ||
5815 nla_put(reply_skb,
5816 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
5817 sizeof(u32) * feature_sets, feature_set_matrix)) {
5818 hddLog(LOGE, FL("nla put fail"));
5819 kfree_skb(reply_skb);
5820 return -EINVAL;
5821 }
5822
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305823 ret = cfg80211_vendor_cmd_reply(reply_skb);
5824 EXIT();
5825 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305826 }
5827 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
5828 return -ENOMEM;
5829
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305830}
5831
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05305832#undef MAX_CONCURRENT_MATRIX
5833#undef MATRIX_CONFIG_PARAM_SET_SIZE_MAX
5834
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305835static int
5836wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
5837 struct wireless_dev *wdev,
5838 const void *data, int data_len)
5839{
5840 int ret = 0;
5841
5842 vos_ssr_protect(__func__);
5843 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
5844 data_len);
5845 vos_ssr_unprotect(__func__);
5846
5847 return ret;
5848}
5849
c_manjeecfd1efb2015-09-25 19:32:34 +05305850
5851static int
5852__wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5853 struct wireless_dev *wdev,
5854 const void *data, int data_len)
5855{
5856 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5857 int ret;
5858 ENTER();
5859
5860 ret = wlan_hdd_validate_context(pHddCtx);
5861 if (0 != ret)
5862 {
5863 return ret;
5864 }
5865
5866 if( !pHddCtx->cfg_ini->enableFwrMemDump ||
5867 (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
5868 {
5869 hddLog(VOS_TRACE_LEVEL_INFO, FL("FW dump Logging not supported"));
5870 return -EINVAL;
5871 }
5872 /*call common API for FW mem dump req*/
5873 ret = wlan_hdd_fw_mem_dump_req(pHddCtx);
5874
Abhishek Singhc783fa72015-12-09 18:07:34 +05305875 if (!ret)
c_manjee04b4c5c2015-10-13 18:35:01 +05305876 {
5877 /*indicate to userspace the status of fw mem dump */
5878 wlan_indicate_mem_dump_complete(true);
5879 }
5880 else
5881 {
5882 /*else send failure to userspace */
5883 wlan_indicate_mem_dump_complete(false);
5884 }
c_manjeecfd1efb2015-09-25 19:32:34 +05305885 EXIT();
5886 return ret;
5887}
5888
5889/**
5890 * wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump
5891 * @wiphy: pointer to wireless wiphy structure.
5892 * @wdev: pointer to wireless_dev structure.
5893 * @data: Pointer to the NL data.
5894 * @data_len:Length of @data
5895 *
5896 * This is called when wlan driver needs to get the firmware memory dump
5897 * via vendor specific command.
5898 *
5899 * Return: 0 on success, error number otherwise.
5900 */
5901
5902static int
5903wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5904 struct wireless_dev *wdev,
5905 const void *data, int data_len)
Sushant Kaushik8e644982015-09-23 12:18:54 +05305906{
5907 int ret = 0;
5908 vos_ssr_protect(__func__);
5909 ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data,
5910 data_len);
5911 vos_ssr_unprotect(__func__);
5912 return ret;
5913}
c_manjeecfd1efb2015-09-25 19:32:34 +05305914
Sushant Kaushik8e644982015-09-23 12:18:54 +05305915static const struct
5916nla_policy
5917qca_wlan_vendor_wifi_logger_start_policy
5918[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
5919 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
5920 = {.type = NLA_U32 },
5921 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
5922 = {.type = NLA_U32 },
5923 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
5924 = {.type = NLA_U32 },
5925};
5926
5927/**
5928 * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
5929 * or disable the collection of packet statistics from the firmware
5930 * @wiphy: WIPHY structure pointer
5931 * @wdev: Wireless device structure pointer
5932 * @data: Pointer to the data received
5933 * @data_len: Length of the data received
5934 *
5935 * This function is used to enable or disable the collection of packet
5936 * statistics from the firmware
5937 *
5938 * Return: 0 on success and errno on failure
5939 */
5940static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
5941 struct wireless_dev *wdev,
5942 const void *data,
5943 int data_len)
5944{
5945 eHalStatus status;
5946 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5947 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
5948 tAniWifiStartLog start_log;
5949
5950 status = wlan_hdd_validate_context(hdd_ctx);
5951 if (0 != status) {
5952 return -EINVAL;
5953 }
5954
5955 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
5956 data, data_len,
5957 qca_wlan_vendor_wifi_logger_start_policy)) {
5958 hddLog(LOGE, FL("Invalid attribute"));
5959 return -EINVAL;
5960 }
5961
5962 /* Parse and fetch ring id */
5963 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
5964 hddLog(LOGE, FL("attr ATTR failed"));
5965 return -EINVAL;
5966 }
5967 start_log.ringId = nla_get_u32(
5968 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
5969 hddLog(LOG1, FL("Ring ID=%d"), start_log.ringId);
5970
5971 /* Parse and fetch verbose level */
5972 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
5973 hddLog(LOGE, FL("attr verbose_level failed"));
5974 return -EINVAL;
5975 }
5976 start_log.verboseLevel = nla_get_u32(
5977 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
5978 hddLog(LOG1, FL("verbose_level=%d"), start_log.verboseLevel);
5979
5980 /* Parse and fetch flag */
5981 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
5982 hddLog(LOGE, FL("attr flag failed"));
5983 return -EINVAL;
5984 }
5985 start_log.flag = nla_get_u32(
5986 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
5987 hddLog(LOG1, FL("flag=%d"), start_log.flag);
5988
5989 if ((RING_ID_PER_PACKET_STATS == start_log.ringId) &&
Sushant Kaushik33200572015-08-05 16:46:20 +05305990 (!hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable ||
5991 !vos_isPktStatsEnabled()))
5992
Sushant Kaushik8e644982015-09-23 12:18:54 +05305993 {
5994 hddLog(LOGE, FL("per pkt stats not enabled"));
5995 return -EINVAL;
5996 }
Sushant Kaushik8e644982015-09-23 12:18:54 +05305997
Sushant Kaushik33200572015-08-05 16:46:20 +05305998 vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel);
Sushant Kaushik8e644982015-09-23 12:18:54 +05305999 return 0;
6000}
6001
6002/**
6003 * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
6004 * or disable the collection of packet statistics from the firmware
6005 * @wiphy: WIPHY structure pointer
6006 * @wdev: Wireless device structure pointer
6007 * @data: Pointer to the data received
6008 * @data_len: Length of the data received
6009 *
6010 * This function is used to enable or disable the collection of packet
6011 * statistics from the firmware
6012 *
6013 * Return: 0 on success and errno on failure
6014 */
6015static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6016 struct wireless_dev *wdev,
6017 const void *data,
6018 int data_len)
c_manjeecfd1efb2015-09-25 19:32:34 +05306019{
6020 int ret = 0;
6021
6022 vos_ssr_protect(__func__);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306023
6024 ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
6025 wdev, data, data_len);
c_manjeecfd1efb2015-09-25 19:32:34 +05306026 vos_ssr_unprotect(__func__);
6027
6028 return ret;
c_manjeecfd1efb2015-09-25 19:32:34 +05306029}
6030
6031
Agarwal Ashish738843c2014-09-25 12:27:56 +05306032static const struct nla_policy
6033wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
6034 +1] =
6035{
6036 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
6037};
6038
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306039static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306040 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306041 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306042 int data_len)
6043{
6044 struct net_device *dev = wdev->netdev;
6045 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6046 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6047 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6048 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
6049 eHalStatus status;
6050 u32 dfsFlag = 0;
6051
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306052 ENTER();
6053
Agarwal Ashish738843c2014-09-25 12:27:56 +05306054 status = wlan_hdd_validate_context(pHddCtx);
6055 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05306056 return -EINVAL;
6057 }
6058 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
6059 data, data_len,
6060 wlan_hdd_set_no_dfs_flag_config_policy)) {
6061 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6062 return -EINVAL;
6063 }
6064
6065 /* Parse and fetch required bandwidth kbps */
6066 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
6067 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
6068 return -EINVAL;
6069 }
6070
6071 dfsFlag = nla_get_u32(
6072 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
6073 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
6074 dfsFlag);
6075
6076 pHddCtx->disable_dfs_flag = dfsFlag;
6077
6078 sme_disable_dfs_channel(hHal, dfsFlag);
6079 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306080
6081 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05306082 return 0;
6083}
Atul Mittal115287b2014-07-08 13:26:33 +05306084
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306085static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
6086 struct wireless_dev *wdev,
6087 const void *data,
6088 int data_len)
6089{
6090 int ret = 0;
6091
6092 vos_ssr_protect(__func__);
6093 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
6094 vos_ssr_unprotect(__func__);
6095
6096 return ret;
6097
6098}
6099
Mukul Sharma2a271632014-10-13 14:59:01 +05306100const struct
6101nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
6102{
6103 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05306104 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
6105 .type = NLA_UNSPEC,
6106 .len = HDD_MAC_ADDR_LEN},
Mukul Sharma2a271632014-10-13 14:59:01 +05306107};
6108
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306109static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05306110 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05306111{
6112
6113 u8 bssid[6] = {0};
6114 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6115 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6116 eHalStatus status = eHAL_STATUS_SUCCESS;
6117 v_U32_t isFwrRoamEnabled = FALSE;
6118 int ret;
6119
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306120 ENTER();
6121
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306122 ret = wlan_hdd_validate_context(pHddCtx);
6123 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306124 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05306125 }
6126
6127 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
6128 data, data_len,
6129 qca_wlan_vendor_attr);
6130 if (ret){
6131 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6132 return -EINVAL;
6133 }
6134
6135 /* Parse and fetch Enable flag */
6136 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
6137 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
6138 return -EINVAL;
6139 }
6140
6141 isFwrRoamEnabled = nla_get_u32(
6142 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
6143
6144 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
6145
6146 /* Parse and fetch bssid */
6147 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
6148 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
6149 return -EINVAL;
6150 }
6151
6152 memcpy(bssid, nla_data(
6153 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
6154 sizeof(bssid));
6155 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
6156
6157 //Update roaming
6158 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306159 if (!HAL_STATUS_SUCCESS(status)) {
6160 hddLog(LOGE,
6161 FL("sme_ConfigFwrRoaming failed (err=%d)"), status);
6162 return -EINVAL;
6163 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306164 EXIT();
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306165 return 0;
Mukul Sharma2a271632014-10-13 14:59:01 +05306166}
6167
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306168static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
6169 struct wireless_dev *wdev, const void *data, int data_len)
6170{
6171 int ret = 0;
6172
6173 vos_ssr_protect(__func__);
6174 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
6175 vos_ssr_unprotect(__func__);
6176
6177 return ret;
6178}
6179
Sushant Kaushik847890c2015-09-28 16:05:17 +05306180static const struct
6181nla_policy
6182qca_wlan_vendor_get_wifi_info_policy[
6183 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
6184 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
6185 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
6186};
6187
6188
6189/**
6190 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6191 * @wiphy: pointer to wireless wiphy structure.
6192 * @wdev: pointer to wireless_dev structure.
6193 * @data: Pointer to the data to be passed via vendor interface
6194 * @data_len:Length of the data to be passed
6195 *
6196 * This is called when wlan driver needs to send wifi driver related info
6197 * (driver/fw version) to the user space application upon request.
6198 *
6199 * Return: Return the Success or Failure code.
6200 */
6201static int __wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6202 struct wireless_dev *wdev,
6203 const void *data, int data_len)
6204{
6205 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6206 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
6207 tSirVersionString version;
6208 uint32 version_len;
6209 uint8 attr;
6210 int status;
6211 struct sk_buff *reply_skb = NULL;
6212
6213 if (VOS_FTM_MODE == hdd_get_conparam()) {
6214 hddLog(LOGE, FL("Command not allowed in FTM mode"));
6215 return -EINVAL;
6216 }
6217
6218 status = wlan_hdd_validate_context(hdd_ctx);
6219 if (0 != status) {
6220 hddLog(LOGE, FL("HDD context is not valid"));
6221 return -EINVAL;
6222 }
6223
6224 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
6225 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
6226 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
6227 return -EINVAL;
6228 }
6229
6230 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
6231 hddLog(LOG1, FL("Rcvd req for Driver version Driver version is %s"),
6232 QWLAN_VERSIONSTR);
6233 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
6234 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
6235 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
6236 hddLog(LOG1, FL("Rcvd req for FW version FW version is %s"),
6237 hdd_ctx->fw_Version);
6238 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
6239 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
6240 } else {
6241 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
6242 return -EINVAL;
6243 }
6244
6245 version_len = strlen(version);
6246 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
6247 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
6248 if (!reply_skb) {
6249 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6250 return -ENOMEM;
6251 }
6252
6253 if (nla_put(reply_skb, attr, version_len, version)) {
6254 hddLog(LOGE, FL("nla put fail"));
6255 kfree_skb(reply_skb);
6256 return -EINVAL;
6257 }
6258
6259 return cfg80211_vendor_cmd_reply(reply_skb);
6260}
6261
6262/**
6263 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6264 * @wiphy: pointer to wireless wiphy structure.
6265 * @wdev: pointer to wireless_dev structure.
6266 * @data: Pointer to the data to be passed via vendor interface
6267 * @data_len:Length of the data to be passed
6268 * @data_len: Length of the data received
6269 *
6270 * This function is used to enable or disable the collection of packet
6271 * statistics from the firmware
6272 *
6273 * Return: 0 on success and errno on failure
6274 */
6275
6276static int
6277wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6278 struct wireless_dev *wdev,
6279 const void *data, int data_len)
6280
6281
6282{
6283 int ret = 0;
6284
6285 vos_ssr_protect(__func__);
6286 ret = __wlan_hdd_cfg80211_get_wifi_info(wiphy,
6287 wdev, data, data_len);
6288 vos_ssr_unprotect(__func__);
6289
6290 return ret;
6291}
6292
6293
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306294/*
6295 * define short names for the global vendor params
6296 * used by __wlan_hdd_cfg80211_monitor_rssi()
6297 */
6298#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX
6299#define PARAM_REQUEST_ID QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID
6300#define PARAM_CONTROL QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL
6301#define PARAM_MIN_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI
6302#define PARAM_MAX_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI
6303
6304/**---------------------------------------------------------------------------
6305
6306 \brief hdd_rssi_monitor_start_done - callback to be executed when rssi
6307 monitor start is completed successfully.
6308
6309 \return - None
6310
6311 --------------------------------------------------------------------------*/
6312void hdd_rssi_monitor_start_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6313{
6314 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6315
6316 if (NULL == pHddCtx)
6317 {
6318 hddLog(VOS_TRACE_LEVEL_ERROR,
6319 "%s: HDD context is NULL",__func__);
6320 return;
6321 }
6322
6323 if (VOS_STATUS_SUCCESS == status)
6324 {
6325 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor start successful"));
6326 }
6327 else
6328 {
6329 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor start not successful"));
6330 }
6331
6332 return;
6333}
6334
6335/**---------------------------------------------------------------------------
6336
6337 \brief hdd_rssi_monitor_stop_done - callback to be executed when rssi monitor
6338 stop is completed successfully.
6339
6340 \return - None
6341
6342 --------------------------------------------------------------------------*/
6343void hdd_rssi_monitor_stop_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6344{
6345 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6346
6347 if (NULL == pHddCtx)
6348 {
6349 hddLog(VOS_TRACE_LEVEL_ERROR,
6350 "%s: HDD context is NULL",__func__);
6351 return;
6352 }
6353
6354 if (VOS_STATUS_SUCCESS == status)
6355 {
6356 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor stop successful"));
6357 }
6358 else
6359 {
6360 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor stop not successful"));
6361 }
6362
6363 return;
6364}
6365
6366/**
6367 * __wlan_hdd_cfg80211_monitor_rssi() - monitor rssi
6368 * @wiphy: Pointer to wireless phy
6369 * @wdev: Pointer to wireless device
6370 * @data: Pointer to data
6371 * @data_len: Data length
6372 *
6373 * Return: 0 on success, negative errno on failure
6374 */
6375
6376static int
6377__wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy,
6378 struct wireless_dev *wdev,
6379 const void *data,
6380 int data_len)
6381{
6382 struct net_device *dev = wdev->netdev;
6383 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6384 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6385 hdd_station_ctx_t *pHddStaCtx;
6386 struct nlattr *tb[PARAM_MAX + 1];
6387 tpSirRssiMonitorReq pReq;
6388 eHalStatus status;
6389 int ret;
6390 uint32_t control;
6391 static const struct nla_policy policy[PARAM_MAX + 1] = {
6392 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6393 [PARAM_CONTROL] = { .type = NLA_U32 },
6394 [PARAM_MIN_RSSI] = { .type = NLA_S8 },
6395 [PARAM_MAX_RSSI] = { .type = NLA_S8 },
6396 };
6397
6398 ENTER();
6399
6400 ret = wlan_hdd_validate_context(hdd_ctx);
6401 if (0 != ret) {
6402 return -EINVAL;
6403 }
6404
6405 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6406 hddLog(LOGE, FL("Not in Connected state!"));
6407 return -ENOTSUPP;
6408 }
6409
6410 if (nla_parse(tb, PARAM_MAX, data, data_len, policy)) {
6411 hddLog(LOGE, FL("Invalid ATTR"));
6412 return -EINVAL;
6413 }
6414
6415 if (!tb[PARAM_REQUEST_ID]) {
6416 hddLog(LOGE, FL("attr request id failed"));
6417 return -EINVAL;
6418 }
6419
6420 if (!tb[PARAM_CONTROL]) {
6421 hddLog(LOGE, FL("attr control failed"));
6422 return -EINVAL;
6423 }
6424
6425 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6426
6427 pReq = vos_mem_malloc(sizeof(tSirRssiMonitorReq));
6428 if(NULL == pReq)
6429 {
6430 hddLog(LOGE,
6431 FL("vos_mem_alloc failed "));
6432 return eHAL_STATUS_FAILED_ALLOC;
6433 }
6434 vos_mem_set(pReq, sizeof(tSirRssiMonitorReq), 0);
6435
6436 pReq->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]);
6437 pReq->sessionId = pAdapter->sessionId;
6438 pReq->rssiMonitorCbContext = hdd_ctx;
6439 control = nla_get_u32(tb[PARAM_CONTROL]);
6440 vos_mem_copy( &pReq->currentBssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
6441
6442 hddLog(LOG1, FL("Request Id: %u Session_id: %d Control: %d"),
6443 pReq->requestId, pReq->sessionId, control);
6444
6445 if (control == QCA_WLAN_RSSI_MONITORING_START) {
6446 if (!tb[PARAM_MIN_RSSI]) {
6447 hddLog(LOGE, FL("attr min rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306448 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306449 }
6450
6451 if (!tb[PARAM_MAX_RSSI]) {
6452 hddLog(LOGE, FL("attr max rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306453 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306454 }
6455
6456 pReq->minRssi = nla_get_s8(tb[PARAM_MIN_RSSI]);
6457 pReq->maxRssi = nla_get_s8(tb[PARAM_MAX_RSSI]);
6458 pReq->rssiMonitorCallback = hdd_rssi_monitor_start_done;
6459
6460 if (!(pReq->minRssi < pReq->maxRssi)) {
6461 hddLog(LOGW, FL("min_rssi: %d must be less than max_rssi: %d"),
6462 pReq->minRssi, pReq->maxRssi);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306463 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306464 }
6465 hddLog(LOG1, FL("Min_rssi: %d Max_rssi: %d"),
6466 pReq->minRssi, pReq->maxRssi);
6467 status = sme_StartRssiMonitoring(hdd_ctx->hHal, pReq);
6468
6469 }
6470 else if (control == QCA_WLAN_RSSI_MONITORING_STOP) {
6471 pReq->rssiMonitorCallback = hdd_rssi_monitor_stop_done;
6472 status = sme_StopRssiMonitoring(hdd_ctx->hHal, pReq);
6473 }
6474 else {
6475 hddLog(LOGE, FL("Invalid control cmd: %d"), control);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306476 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306477 }
6478
6479 if (!HAL_STATUS_SUCCESS(status)) {
6480 hddLog(LOGE,
6481 FL("sme_set_rssi_monitoring failed(err=%d)"), status);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306482 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306483 }
6484
6485 return 0;
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306486fail:
6487 vos_mem_free(pReq);
6488 return -EINVAL;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306489}
6490
6491/*
6492 * done with short names for the global vendor params
6493 * used by __wlan_hdd_cfg80211_monitor_rssi()
6494 */
6495#undef PARAM_MAX
6496#undef PARAM_CONTROL
6497#undef PARAM_REQUEST_ID
6498#undef PARAM_MAX_RSSI
6499#undef PARAM_MIN_RSSI
6500
6501/**
6502 * wlan_hdd_cfg80211_monitor_rssi() - SSR wrapper to rssi monitoring
6503 * @wiphy: wiphy structure pointer
6504 * @wdev: Wireless device structure pointer
6505 * @data: Pointer to the data received
6506 * @data_len: Length of @data
6507 *
6508 * Return: 0 on success; errno on failure
6509 */
6510static int
6511wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, struct wireless_dev *wdev,
6512 const void *data, int data_len)
6513{
6514 int ret;
6515
6516 vos_ssr_protect(__func__);
6517 ret = __wlan_hdd_cfg80211_monitor_rssi(wiphy, wdev, data, data_len);
6518 vos_ssr_unprotect(__func__);
6519
6520 return ret;
6521}
6522
6523/**
6524 * hdd_rssi_threshold_breached_cb() - rssi breached NL event
6525 * @hddctx: HDD context
6526 * @data: rssi breached event data
6527 *
6528 * This function reads the rssi breached event %data and fill in the skb with
6529 * NL attributes and send up the NL event.
6530 * This callback execute in atomic context and must not invoke any
6531 * blocking calls.
6532 *
6533 * Return: none
6534 */
6535void hdd_rssi_threshold_breached_cb(void *hddctx,
6536 struct rssi_breach_event *data)
6537{
6538 hdd_context_t *pHddCtx = (hdd_context_t *)hddctx;
6539 int status;
6540 struct sk_buff *skb;
6541
6542 ENTER();
6543 status = wlan_hdd_validate_context(pHddCtx);
6544
6545 if (0 != status) {
6546 return;
6547 }
6548
6549 if (!data) {
6550 hddLog(LOGE, FL("data is null"));
6551 return;
6552 }
6553
6554 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
6555#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
6556 NULL,
6557#endif
6558 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
6559 QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX,
6560 GFP_KERNEL);
6561
6562 if (!skb) {
6563 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
6564 return;
6565 }
6566
6567 hddLog(LOG1, "Req Id: %u Current rssi: %d",
6568 data->request_id, data->curr_rssi);
6569 hddLog(LOG1, "Current BSSID: "MAC_ADDRESS_STR,
6570 MAC_ADDR_ARRAY(data->curr_bssid.bytes));
6571
6572 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
6573 data->request_id) ||
6574 nla_put(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID,
6575 sizeof(data->curr_bssid), data->curr_bssid.bytes) ||
6576 nla_put_s8(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI,
6577 data->curr_rssi)) {
6578 hddLog(LOGE, FL("nla put fail"));
6579 goto fail;
6580 }
6581
6582 cfg80211_vendor_event(skb, GFP_KERNEL);
6583 return;
6584
6585fail:
6586 kfree_skb(skb);
6587 return;
6588}
6589
6590
6591
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306592/**
6593 * __wlan_hdd_cfg80211_setband() - set band
6594 * @wiphy: Pointer to wireless phy
6595 * @wdev: Pointer to wireless device
6596 * @data: Pointer to data
6597 * @data_len: Data length
6598 *
6599 * Return: 0 on success, negative errno on failure
6600 */
6601static int
6602__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6603 struct wireless_dev *wdev,
6604 const void *data,
6605 int data_len)
6606{
6607 struct net_device *dev = wdev->netdev;
6608 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6609 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6610 int ret;
6611 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
6612 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
6613
6614 ENTER();
6615
6616 ret = wlan_hdd_validate_context(hdd_ctx);
6617 if (0 != ret) {
6618 hddLog(LOGE, FL("HDD context is not valid"));
6619 return ret;
6620 }
6621
6622 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
6623 policy)) {
6624 hddLog(LOGE, FL("Invalid ATTR"));
6625 return -EINVAL;
6626 }
6627
6628 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
6629 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
6630 return -EINVAL;
6631 }
6632
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306633 hdd_ctx->isSetBandByNL = TRUE;
6634 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306635 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306636 hdd_ctx->isSetBandByNL = FALSE;
6637
6638 EXIT();
6639 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306640}
6641
6642/**
6643 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
6644 * @wiphy: wiphy structure pointer
6645 * @wdev: Wireless device structure pointer
6646 * @data: Pointer to the data received
6647 * @data_len: Length of @data
6648 *
6649 * Return: 0 on success; errno on failure
6650 */
6651static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6652 struct wireless_dev *wdev,
6653 const void *data,
6654 int data_len)
6655{
6656 int ret = 0;
6657
6658 vos_ssr_protect(__func__);
6659 ret = __wlan_hdd_cfg80211_setband(wiphy,
6660 wdev, data, data_len);
6661 vos_ssr_unprotect(__func__);
6662
6663 return ret;
6664}
6665
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05306666#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
6667/**
6668 * hdd_map_req_id_to_pattern_id() - map request id to pattern id
6669 * @hdd_ctx: HDD context
6670 * @request_id: [input] request id
6671 * @pattern_id: [output] pattern id
6672 *
6673 * This function loops through request id to pattern id array
6674 * if the slot is available, store the request id and return pattern id
6675 * if entry exists, return the pattern id
6676 *
6677 * Return: 0 on success and errno on failure
6678 */
6679static int hdd_map_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
6680 uint32_t request_id,
6681 uint8_t *pattern_id)
6682{
6683 uint32_t i;
6684
6685 mutex_lock(&hdd_ctx->op_ctx.op_lock);
6686 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
6687 {
6688 if (hdd_ctx->op_ctx.op_table[i].request_id == 0)
6689 {
6690 hdd_ctx->op_ctx.op_table[i].request_id = request_id;
6691 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6692 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6693 return 0;
6694 } else if (hdd_ctx->op_ctx.op_table[i].request_id ==
6695 request_id) {
6696 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6697 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6698 return 0;
6699 }
6700 }
6701 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6702 return -EINVAL;
6703}
6704
6705/**
6706 * hdd_unmap_req_id_to_pattern_id() - unmap request id to pattern id
6707 * @hdd_ctx: HDD context
6708 * @request_id: [input] request id
6709 * @pattern_id: [output] pattern id
6710 *
6711 * This function loops through request id to pattern id array
6712 * reset request id to 0 (slot available again) and
6713 * return pattern id
6714 *
6715 * Return: 0 on success and errno on failure
6716 */
6717static int hdd_unmap_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
6718 uint32_t request_id,
6719 uint8_t *pattern_id)
6720{
6721 uint32_t i;
6722
6723 mutex_lock(&hdd_ctx->op_ctx.op_lock);
6724 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
6725 {
6726 if (hdd_ctx->op_ctx.op_table[i].request_id == request_id)
6727 {
6728 hdd_ctx->op_ctx.op_table[i].request_id = 0;
6729 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6730 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6731 return 0;
6732 }
6733 }
6734 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6735 return -EINVAL;
6736}
6737
6738
6739/*
6740 * define short names for the global vendor params
6741 * used by __wlan_hdd_cfg80211_offloaded_packets()
6742 */
6743#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX
6744#define PARAM_REQUEST_ID \
6745 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID
6746#define PARAM_CONTROL \
6747 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL
6748#define PARAM_IP_PACKET \
6749 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA
6750#define PARAM_SRC_MAC_ADDR \
6751 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR
6752#define PARAM_DST_MAC_ADDR \
6753 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR
6754#define PARAM_PERIOD QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD
6755
6756/**
6757 * wlan_hdd_add_tx_ptrn() - add tx pattern
6758 * @adapter: adapter pointer
6759 * @hdd_ctx: hdd context
6760 * @tb: nl attributes
6761 *
6762 * This function reads the NL attributes and forms a AddTxPtrn message
6763 * posts it to SME.
6764 *
6765 */
6766static int
6767wlan_hdd_add_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
6768 struct nlattr **tb)
6769{
6770 struct sSirAddPeriodicTxPtrn *add_req;
6771 eHalStatus status;
6772 uint32_t request_id, ret, len;
6773 uint8_t pattern_id = 0;
6774 v_MACADDR_t dst_addr;
6775 uint16_t eth_type = htons(ETH_P_IP);
6776
6777 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(adapter)))
6778 {
6779 hddLog(LOGE, FL("Not in Connected state!"));
6780 return -ENOTSUPP;
6781 }
6782
6783 add_req = vos_mem_malloc(sizeof(*add_req));
6784 if (!add_req)
6785 {
6786 hddLog(LOGE, FL("memory allocation failed"));
6787 return -ENOMEM;
6788 }
6789
6790 /* Parse and fetch request Id */
6791 if (!tb[PARAM_REQUEST_ID])
6792 {
6793 hddLog(LOGE, FL("attr request id failed"));
6794 goto fail;
6795 }
6796
6797 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
6798 hddLog(LOG1, FL("Request Id: %u"), request_id);
6799 if (request_id == 0)
6800 {
6801 hddLog(LOGE, FL("request_id cannot be zero"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306802 goto fail;
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05306803 }
6804
6805 if (!tb[PARAM_PERIOD])
6806 {
6807 hddLog(LOGE, FL("attr period failed"));
6808 goto fail;
6809 }
6810 add_req->usPtrnIntervalMs = nla_get_u32(tb[PARAM_PERIOD]);
6811 hddLog(LOG1, FL("Period: %u ms"), add_req->usPtrnIntervalMs);
6812 if (add_req->usPtrnIntervalMs == 0)
6813 {
6814 hddLog(LOGE, FL("Invalid interval zero, return failure"));
6815 goto fail;
6816 }
6817
6818 if (!tb[PARAM_SRC_MAC_ADDR])
6819 {
6820 hddLog(LOGE, FL("attr source mac address failed"));
6821 goto fail;
6822 }
6823 nla_memcpy(add_req->macAddress, tb[PARAM_SRC_MAC_ADDR],
6824 VOS_MAC_ADDR_SIZE);
6825 hddLog(LOG1, "input src mac address: "MAC_ADDRESS_STR,
6826 MAC_ADDR_ARRAY(add_req->macAddress));
6827
6828 if (memcmp(add_req->macAddress, adapter->macAddressCurrent.bytes,
6829 VOS_MAC_ADDR_SIZE))
6830 {
6831 hddLog(LOGE,
6832 FL("input src mac address and connected ap bssid are different"));
6833 goto fail;
6834 }
6835
6836 if (!tb[PARAM_DST_MAC_ADDR])
6837 {
6838 hddLog(LOGE, FL("attr dst mac address failed"));
6839 goto fail;
6840 }
6841 nla_memcpy(dst_addr.bytes, tb[PARAM_DST_MAC_ADDR], VOS_MAC_ADDR_SIZE);
6842 hddLog(LOG1, "input dst mac address: "MAC_ADDRESS_STR,
6843 MAC_ADDR_ARRAY(dst_addr.bytes));
6844
6845 if (!tb[PARAM_IP_PACKET])
6846 {
6847 hddLog(LOGE, FL("attr ip packet failed"));
6848 goto fail;
6849 }
6850 add_req->ucPtrnSize = nla_len(tb[PARAM_IP_PACKET]);
6851 hddLog(LOG1, FL("IP packet len: %u"), add_req->ucPtrnSize);
6852
6853 if (add_req->ucPtrnSize < 0 ||
6854 add_req->ucPtrnSize > (PERIODIC_TX_PTRN_MAX_SIZE -
6855 HDD_ETH_HEADER_LEN))
6856 {
6857 hddLog(LOGE, FL("Invalid IP packet len: %d"),
6858 add_req->ucPtrnSize);
6859 goto fail;
6860 }
6861
6862 len = 0;
6863 vos_mem_copy(&add_req->ucPattern[0], dst_addr.bytes, VOS_MAC_ADDR_SIZE);
6864 len += VOS_MAC_ADDR_SIZE;
6865 vos_mem_copy(&add_req->ucPattern[len], add_req->macAddress,
6866 VOS_MAC_ADDR_SIZE);
6867 len += VOS_MAC_ADDR_SIZE;
6868 vos_mem_copy(&add_req->ucPattern[len], &eth_type, 2);
6869 len += 2;
6870
6871 /*
6872 * This is the IP packet, add 14 bytes Ethernet (802.3) header
6873 * ------------------------------------------------------------
6874 * | 14 bytes Ethernet (802.3) header | IP header and payload |
6875 * ------------------------------------------------------------
6876 */
6877 vos_mem_copy(&add_req->ucPattern[len],
6878 nla_data(tb[PARAM_IP_PACKET]),
6879 add_req->ucPtrnSize);
6880 add_req->ucPtrnSize += len;
6881
6882 VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6883 add_req->ucPattern, add_req->ucPtrnSize);
6884
6885 ret = hdd_map_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
6886 if (ret)
6887 {
6888 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
6889 goto fail;
6890 }
6891 add_req->ucPtrnId = pattern_id;
6892 hddLog(LOG1, FL("pattern id: %d"), add_req->ucPtrnId);
6893
6894 status = sme_AddPeriodicTxPtrn(hdd_ctx->hHal, add_req);
6895 if (!HAL_STATUS_SUCCESS(status))
6896 {
6897 hddLog(LOGE,
6898 FL("sme_AddPeriodicTxPtrn failed (err=%d)"), status);
6899 goto fail;
6900 }
6901
6902 EXIT();
6903 vos_mem_free(add_req);
6904 return 0;
6905
6906fail:
6907 vos_mem_free(add_req);
6908 return -EINVAL;
6909}
6910
6911/**
6912 * wlan_hdd_del_tx_ptrn() - delete tx pattern
6913 * @adapter: adapter pointer
6914 * @hdd_ctx: hdd context
6915 * @tb: nl attributes
6916 *
6917 * This function reads the NL attributes and forms a DelTxPtrn message
6918 * posts it to SME.
6919 *
6920 */
6921static int
6922wlan_hdd_del_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
6923 struct nlattr **tb)
6924{
6925 struct sSirDelPeriodicTxPtrn *del_req;
6926 eHalStatus status;
6927 uint32_t request_id, ret;
6928 uint8_t pattern_id = 0;
6929
6930 /* Parse and fetch request Id */
6931 if (!tb[PARAM_REQUEST_ID])
6932 {
6933 hddLog(LOGE, FL("attr request id failed"));
6934 return -EINVAL;
6935 }
6936 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
6937 if (request_id == 0)
6938 {
6939 hddLog(LOGE, FL("request_id cannot be zero"));
6940 return -EINVAL;
6941 }
6942
6943 ret = hdd_unmap_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
6944 if (ret)
6945 {
6946 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
6947 return -EINVAL;
6948 }
6949
6950 del_req = vos_mem_malloc(sizeof(*del_req));
6951 if (!del_req)
6952 {
6953 hddLog(LOGE, FL("memory allocation failed"));
6954 return -ENOMEM;
6955 }
6956
6957 vos_mem_set(del_req, sizeof(*del_req), 0);
6958 vos_mem_copy(del_req->macAddress, adapter->macAddressCurrent.bytes,
6959 VOS_MAC_ADDR_SIZE);
6960 hddLog(LOG1, MAC_ADDRESS_STR, MAC_ADDR_ARRAY(del_req->macAddress));
6961 del_req->ucPatternIdBitmap |= (0x1 << pattern_id);
6962 hddLog(LOG1, FL("Request Id: %u Pattern id: %d, bitmap %04x"),
6963 request_id, pattern_id, del_req->ucPatternIdBitmap);
6964
6965 status = sme_DelPeriodicTxPtrn(hdd_ctx->hHal, del_req);
6966 if (!HAL_STATUS_SUCCESS(status))
6967 {
6968 hddLog(LOGE,
6969 FL("sme_DelPeriodicTxPtrn failed (err=%d)"), status);
6970 goto fail;
6971 }
6972
6973 EXIT();
6974 vos_mem_free(del_req);
6975 return 0;
6976
6977fail:
6978 vos_mem_free(del_req);
6979 return -EINVAL;
6980}
6981
6982
6983/**
6984 * __wlan_hdd_cfg80211_offloaded_packets() - send offloaded packets
6985 * @wiphy: Pointer to wireless phy
6986 * @wdev: Pointer to wireless device
6987 * @data: Pointer to data
6988 * @data_len: Data length
6989 *
6990 * Return: 0 on success, negative errno on failure
6991 */
6992static int
6993__wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
6994 struct wireless_dev *wdev,
6995 const void *data,
6996 int data_len)
6997{
6998 struct net_device *dev = wdev->netdev;
6999 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7000 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7001 struct nlattr *tb[PARAM_MAX + 1];
7002 uint8_t control;
7003 int ret;
7004 static const struct nla_policy policy[PARAM_MAX + 1] =
7005 {
7006 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
7007 [PARAM_CONTROL] = { .type = NLA_U32 },
7008 [PARAM_SRC_MAC_ADDR] = { .type = NLA_BINARY,
7009 .len = VOS_MAC_ADDR_SIZE },
7010 [PARAM_DST_MAC_ADDR] = { .type = NLA_BINARY,
7011 .len = VOS_MAC_ADDR_SIZE },
7012 [PARAM_PERIOD] = { .type = NLA_U32 },
7013 };
7014
7015 ENTER();
7016
7017 ret = wlan_hdd_validate_context(hdd_ctx);
7018 if (0 != ret)
7019 {
7020 hddLog(LOGE, FL("HDD context is not valid"));
7021 return ret;
7022 }
7023
7024 if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN))
7025 {
7026 hddLog(LOGE,
7027 FL("Periodic Tx Pattern Offload feature is not supported in FW!"));
7028 return -ENOTSUPP;
7029 }
7030
7031 if (nla_parse(tb, PARAM_MAX, data, data_len, policy))
7032 {
7033 hddLog(LOGE, FL("Invalid ATTR"));
7034 return -EINVAL;
7035 }
7036
7037 if (!tb[PARAM_CONTROL])
7038 {
7039 hddLog(LOGE, FL("attr control failed"));
7040 return -EINVAL;
7041 }
7042 control = nla_get_u32(tb[PARAM_CONTROL]);
7043 hddLog(LOG1, FL("Control: %d"), control);
7044
7045 if (control == WLAN_START_OFFLOADED_PACKETS)
7046 return wlan_hdd_add_tx_ptrn(adapter, hdd_ctx, tb);
7047 else if (control == WLAN_STOP_OFFLOADED_PACKETS)
7048 return wlan_hdd_del_tx_ptrn(adapter, hdd_ctx, tb);
7049 else
7050 {
7051 hddLog(LOGE, FL("Invalid control: %d"), control);
7052 return -EINVAL;
7053 }
7054}
7055
7056/*
7057 * done with short names for the global vendor params
7058 * used by __wlan_hdd_cfg80211_offloaded_packets()
7059 */
7060#undef PARAM_MAX
7061#undef PARAM_REQUEST_ID
7062#undef PARAM_CONTROL
7063#undef PARAM_IP_PACKET
7064#undef PARAM_SRC_MAC_ADDR
7065#undef PARAM_DST_MAC_ADDR
7066#undef PARAM_PERIOD
7067
7068/**
7069 * wlan_hdd_cfg80211_offloaded_packets() - Wrapper to offload packets
7070 * @wiphy: wiphy structure pointer
7071 * @wdev: Wireless device structure pointer
7072 * @data: Pointer to the data received
7073 * @data_len: Length of @data
7074 *
7075 * Return: 0 on success; errno on failure
7076 */
7077static int wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7078 struct wireless_dev *wdev,
7079 const void *data,
7080 int data_len)
7081{
7082 int ret = 0;
7083
7084 vos_ssr_protect(__func__);
7085 ret = __wlan_hdd_cfg80211_offloaded_packets(wiphy,
7086 wdev, data, data_len);
7087 vos_ssr_unprotect(__func__);
7088
7089 return ret;
7090}
7091#endif
7092
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307093static const struct
7094nla_policy
7095qca_wlan_vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05307096 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
7097 .type = NLA_BINARY,
7098 .len = HDD_MAC_ADDR_LEN},
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307099};
7100
7101/**
7102 * wlan_hdd_cfg80211_get_link_properties() - This function is used to
7103 * get link properties like nss, rate flags and operating frequency for
7104 * the connection with the given peer.
7105 * @wiphy: WIPHY structure pointer
7106 * @wdev: Wireless device structure pointer
7107 * @data: Pointer to the data received
7108 * @data_len: Length of the data received
7109 *
7110 * This function return the above link properties on success.
7111 *
7112 * Return: 0 on success and errno on failure
7113 */
7114static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
7115 struct wireless_dev *wdev,
7116 const void *data,
7117 int data_len)
7118{
7119 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7120 struct net_device *dev = wdev->netdev;
7121 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7122 hdd_station_ctx_t *hdd_sta_ctx;
7123 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX+1];
7124 uint8_t peer_mac[VOS_MAC_ADDR_SIZE];
7125 uint32_t sta_id;
7126 struct sk_buff *reply_skb;
7127 uint32_t rate_flags = 0;
7128 uint8_t nss;
7129 uint8_t final_rate_flags = 0;
7130 uint32_t freq;
7131 v_CONTEXT_t pVosContext = NULL;
7132 ptSapContext pSapCtx = NULL;
7133
7134 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
7135 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
7136 return -EINVAL;
7137 }
7138
7139 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7140 qca_wlan_vendor_attr_policy)) {
7141 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid attribute"));
7142 return -EINVAL;
7143 }
7144
7145 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
7146 hddLog(VOS_TRACE_LEVEL_ERROR,
7147 FL("Attribute peerMac not provided for mode=%d"),
7148 adapter->device_mode);
7149 return -EINVAL;
7150 }
7151
Ashish Kumar Dhanotiyaddaf0482017-06-23 15:22:42 +05307152 if (nla_len(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) < sizeof(peer_mac)) {
7153 hddLog(VOS_TRACE_LEVEL_ERROR,
7154 FL("Attribute peerMac is invalid=%d"),
7155 adapter->device_mode);
7156 return -EINVAL;
7157 }
7158
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307159 memcpy(peer_mac, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
7160 sizeof(peer_mac));
7161 hddLog(VOS_TRACE_LEVEL_INFO,
7162 FL("peerMac="MAC_ADDRESS_STR" for device_mode:%d"),
7163 MAC_ADDR_ARRAY(peer_mac), adapter->device_mode);
7164
7165 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
7166 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
7167 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
7168 if ((hdd_sta_ctx->conn_info.connState !=
7169 eConnectionState_Associated) ||
7170 !vos_mem_compare(hdd_sta_ctx->conn_info.bssId, peer_mac,
7171 VOS_MAC_ADDRESS_LEN)) {
7172 hddLog(VOS_TRACE_LEVEL_ERROR,
7173 FL("Not Associated to mac "MAC_ADDRESS_STR),
7174 MAC_ADDR_ARRAY(peer_mac));
7175 return -EINVAL;
7176 }
7177
7178 nss = 1; //pronto supports only one spatial stream
7179 freq = vos_chan_to_freq(
7180 hdd_sta_ctx->conn_info.operationChannel);
7181 rate_flags = hdd_sta_ctx->conn_info.rate_flags;
7182
7183 } else if (adapter->device_mode == WLAN_HDD_P2P_GO ||
7184 adapter->device_mode == WLAN_HDD_SOFTAP) {
7185
7186 pVosContext = ( WLAN_HDD_GET_CTX(adapter))->pvosContext;
7187 pSapCtx = VOS_GET_SAP_CB(pVosContext);
7188 if(pSapCtx == NULL){
7189 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7190 FL("psapCtx is NULL"));
7191 return -ENOENT;
7192 }
7193
7194
7195 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
7196 if (pSapCtx->aStaInfo[sta_id].isUsed &&
7197 !vos_is_macaddr_broadcast(
7198 &pSapCtx->aStaInfo[sta_id].macAddrSTA) &&
7199 vos_mem_compare(
7200 &pSapCtx->aStaInfo[sta_id].macAddrSTA,
7201 peer_mac, VOS_MAC_ADDRESS_LEN))
7202 break;
7203 }
7204
7205 if (WLAN_MAX_STA_COUNT == sta_id) {
7206 hddLog(VOS_TRACE_LEVEL_ERROR,
7207 FL("No active peer with mac="MAC_ADDRESS_STR),
7208 MAC_ADDR_ARRAY(peer_mac));
7209 return -EINVAL;
7210 }
7211
7212 nss = 1; //pronto supports only one spatial stream
7213 freq = vos_chan_to_freq(
7214 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operatingChannel);
7215 rate_flags = pSapCtx->aStaInfo[sta_id].rate_flags;
7216 } else {
7217 hddLog(VOS_TRACE_LEVEL_ERROR,
7218 FL("Not Associated! with mac"MAC_ADDRESS_STR),
7219 MAC_ADDR_ARRAY(peer_mac));
7220 return -EINVAL;
7221 }
7222
7223 if (!(rate_flags & eHAL_TX_RATE_LEGACY)) {
7224 if (rate_flags & eHAL_TX_RATE_VHT80) {
7225 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7226 final_rate_flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
7227 } else if (rate_flags & eHAL_TX_RATE_VHT40) {
7228 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7229 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7230 } else if (rate_flags & eHAL_TX_RATE_VHT20) {
7231 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7232 } else if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40)) {
7233 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7234 if (rate_flags & eHAL_TX_RATE_HT40)
7235 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7236 }
7237
7238 if (rate_flags & eHAL_TX_RATE_SGI) {
7239 if (!(final_rate_flags & RATE_INFO_FLAGS_VHT_MCS))
7240 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7241 final_rate_flags |= RATE_INFO_FLAGS_SHORT_GI;
7242 }
7243 }
7244
7245 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7246 sizeof(u8) + sizeof(u8) + sizeof(u32) + NLMSG_HDRLEN);
7247
7248 if (NULL == reply_skb) {
7249 hddLog(VOS_TRACE_LEVEL_ERROR,
7250 FL("getLinkProperties: skb alloc failed"));
7251 return -EINVAL;
7252 }
7253
7254 if (nla_put_u8(reply_skb,
7255 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS,
7256 nss) ||
7257 nla_put_u8(reply_skb,
7258 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS,
7259 final_rate_flags) ||
7260 nla_put_u32(reply_skb,
7261 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ,
7262 freq)) {
7263 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_put failed"));
7264 kfree_skb(reply_skb);
7265 return -EINVAL;
7266 }
7267
7268 return cfg80211_vendor_cmd_reply(reply_skb);
7269}
7270
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307271#define BEACON_MISS_THRESH_2_4 \
7272 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24
7273#define BEACON_MISS_THRESH_5_0 \
7274 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307275#define PARAM_WIFICONFIG_MAX QCA_WLAN_VENDOR_ATTR_CONFIG_MAX
7276#define PARAM_MODULATED_DTIM QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM
7277#define PARAM_STATS_AVG_FACTOR QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR
7278#define PARAM_GUARD_TIME QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307279#define PARAM_BCNMISS_PENALTY_PARAM_COUNT \
7280 QCA_WLAN_VENDOR_ATTR_CONFIG_PENALIZE_AFTER_NCONS_BEACON_MISS
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307281
7282/**
7283 * __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7284 * vendor command
7285 *
7286 * @wiphy: wiphy device pointer
7287 * @wdev: wireless device pointer
7288 * @data: Vendor command data buffer
7289 * @data_len: Buffer length
7290 *
7291 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7292 *
7293 * Return: EOK or other error codes.
7294 */
7295
7296static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7297 struct wireless_dev *wdev,
7298 const void *data,
7299 int data_len)
7300{
7301 struct net_device *dev = wdev->netdev;
7302 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7303 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7304 hdd_station_ctx_t *pHddStaCtx;
7305 struct nlattr *tb[PARAM_WIFICONFIG_MAX + 1];
7306 tpSetWifiConfigParams pReq;
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307307 tModifyRoamParamsReqParams modifyRoamParamsReq;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307308 eHalStatus status;
7309 int ret_val;
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307310 uint8_t hb_thresh_val;
7311
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307312 static const struct nla_policy policy[PARAM_WIFICONFIG_MAX + 1] = {
7313 [PARAM_STATS_AVG_FACTOR] = { .type = NLA_U16 },
7314 [PARAM_MODULATED_DTIM] = { .type = NLA_U32 },
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307315 [PARAM_GUARD_TIME] = { .type = NLA_U32},
7316 [PARAM_BCNMISS_PENALTY_PARAM_COUNT] =
7317 { .type = NLA_U32},
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307318 [BEACON_MISS_THRESH_2_4] = { .type = NLA_U8 },
7319 [BEACON_MISS_THRESH_5_0] = { .type = NLA_U8 },
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307320 };
7321
7322 ENTER();
7323
7324 if (VOS_FTM_MODE == hdd_get_conparam()) {
7325 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7326 return -EINVAL;
7327 }
7328
7329 ret_val = wlan_hdd_validate_context(pHddCtx);
7330 if (ret_val) {
7331 return ret_val;
7332 }
7333
7334 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7335
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307336 if (nla_parse(tb, PARAM_WIFICONFIG_MAX, data, data_len, policy)) {
7337 hddLog(LOGE, FL("Invalid ATTR"));
7338 return -EINVAL;
7339 }
7340
7341 /* check the Wifi Capability */
7342 if ( (TRUE != pHddCtx->cfg_ini->fEnableWifiConfig) &&
7343 (TRUE != sme_IsFeatureSupportedByFW(WIFI_CONFIG)))
7344 {
7345 hddLog(VOS_TRACE_LEVEL_ERROR,
7346 FL("WIFICONFIG not supported by Firmware"));
7347 return -EINVAL;
7348 }
7349
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307350 if (tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]) {
7351 modifyRoamParamsReq.param = WIFI_CONFIG_SET_BCNMISS_PENALTY_COUNT;
7352 modifyRoamParamsReq.value =
7353 nla_get_u32(tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]);
7354
7355 if (eHAL_STATUS_SUCCESS !=
7356 sme_setBcnMissPenaltyCount(pHddCtx->hHal,&modifyRoamParamsReq))
7357 {
7358 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed", __func__);
7359 ret_val = -EINVAL;
7360 }
7361 return ret_val;
7362 }
7363
7364 /* Moved this down in order to provide provision to set beacon
7365 * miss penalty count irrespective of connection state.
7366 */
7367 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
7368 hddLog(LOGE, FL("Not in Connected state!"));
7369 return -ENOTSUPP;
7370 }
7371
7372 pReq = vos_mem_malloc(sizeof(tSetWifiConfigParams));
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307373
7374 if (!pReq) {
7375 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7376 "%s: Not able to allocate memory for tSetWifiConfigParams",
7377 __func__);
7378 return eHAL_STATUS_E_MALLOC_FAILED;
7379 }
7380
7381 vos_mem_set(pReq, sizeof(tSetWifiConfigParams), 0);
7382
7383 pReq->sessionId = pAdapter->sessionId;
7384 vos_mem_copy( &pReq->bssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
7385
7386 if (tb[PARAM_MODULATED_DTIM]) {
7387 pReq->paramValue = nla_get_u32(
7388 tb[PARAM_MODULATED_DTIM]);
7389 hddLog(LOG1, FL("Modulated DTIM: pReq->paramValue:%d "),
7390 pReq->paramValue);
Arun Khandavalli876886f2015-11-23 11:42:27 +05307391 pHddCtx->cfg_ini->enableDynamicDTIM = pReq->paramValue;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307392 hdd_set_pwrparams(pHddCtx);
7393 if (BMPS == pmcGetPmcState(pHddCtx->hHal)) {
7394 hddLog( LOG1, FL("WifiConfig: Requesting FullPower!"));
7395
7396 sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
7397 iw_full_power_cbfn, pAdapter,
7398 eSME_FULL_PWR_NEEDED_BY_HDD);
7399 }
7400 else
7401 {
7402 hddLog( LOG1, FL("WifiConfig Not in BMPS state"));
7403 }
7404 }
7405
7406 if (tb[PARAM_STATS_AVG_FACTOR]) {
7407 pReq->paramType = WIFI_CONFIG_SET_AVG_STATS_FACTOR;
7408 pReq->paramValue = nla_get_u16(
7409 tb[PARAM_STATS_AVG_FACTOR]);
7410 hddLog(LOG1, FL("AVG_STATS_FACTOR 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 if (tb[PARAM_GUARD_TIME]) {
7425 pReq->paramType = WIFI_CONFIG_SET_GUARD_TIME;
7426 pReq->paramValue = nla_get_u32(
7427 tb[PARAM_GUARD_TIME]);
7428 hddLog(LOG1, FL("GUARD_TIME pReq->paramType:%d,pReq->paramValue:%d "),
7429 pReq->paramType, pReq->paramValue);
7430 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7431
7432 if (eHAL_STATUS_SUCCESS != status)
7433 {
7434 vos_mem_free(pReq);
7435 pReq = NULL;
7436 ret_val = -EPERM;
7437 return ret_val;
7438 }
7439
7440 }
7441
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307442 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]) {
7443 hb_thresh_val = nla_get_u8(
7444 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]);
7445
7446 hddLog(LOG1, "WLAN set heartbeat threshold for 2.4Ghz %d",
7447 hb_thresh_val);
7448 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7449 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
7450 NULL, eANI_BOOLEAN_FALSE);
7451
7452 status = sme_update_hb_threshold(
7453 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
7454 WNI_CFG_HEART_BEAT_THRESHOLD,
7455 hb_thresh_val, eCSR_BAND_24);
7456 if (eHAL_STATUS_SUCCESS != status) {
7457 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
7458 vos_mem_free(pReq);
7459 pReq = NULL;
7460 return -EPERM;
7461 }
7462 }
7463
7464 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]) {
7465 hb_thresh_val = nla_get_u8(
7466 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]);
7467
7468 hddLog(LOG1, "WLAN set heartbeat threshold for 5Ghz %d",
7469 hb_thresh_val);
7470 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7471 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
7472 NULL, eANI_BOOLEAN_FALSE);
7473
7474 status = sme_update_hb_threshold(
7475 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
7476 WNI_CFG_HEART_BEAT_THRESHOLD,
7477 hb_thresh_val, eCSR_BAND_5G);
7478 if (eHAL_STATUS_SUCCESS != status) {
7479 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
7480 vos_mem_free(pReq);
7481 pReq = NULL;
7482 return -EPERM;
7483 }
7484 }
7485
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307486 EXIT();
7487 return ret_val;
7488}
7489
7490/**
7491 * wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7492 * vendor command
7493 *
7494 * @wiphy: wiphy device pointer
7495 * @wdev: wireless device pointer
7496 * @data: Vendor command data buffer
7497 * @data_len: Buffer length
7498 *
7499 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7500 *
7501 * Return: EOK or other error codes.
7502 */
7503static int wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7504 struct wireless_dev *wdev,
7505 const void *data,
7506 int data_len)
7507{
7508 int ret;
7509
7510 vos_ssr_protect(__func__);
7511 ret = __wlan_hdd_cfg80211_wifi_configuration_set(wiphy, wdev,
7512 data, data_len);
7513 vos_ssr_unprotect(__func__);
7514
7515 return ret;
7516}
Anurag Chouhan6ee81542017-02-09 18:09:27 +05307517
7518/*
7519 * define short names for the global vendor params
7520 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
7521 */
7522#define STATS_SET_INVALID \
7523 QCA_ATTR_NUD_STATS_SET_INVALID
7524#define STATS_SET_START \
7525 QCA_ATTR_NUD_STATS_SET_START
7526#define STATS_GW_IPV4 \
7527 QCA_ATTR_NUD_STATS_GW_IPV4
7528#define STATS_SET_MAX \
7529 QCA_ATTR_NUD_STATS_SET_MAX
7530
7531const struct nla_policy
7532qca_wlan_vendor_set_nud_stats[STATS_SET_MAX +1] =
7533{
7534 [STATS_SET_START] = {.type = NLA_FLAG },
7535 [STATS_GW_IPV4] = {.type = NLA_U32 },
7536};
7537
7538/**
7539 * hdd_set_nud_stats_cb() - hdd callback api to get status
7540 * @data: pointer to adapter
7541 * @rsp: status
7542 *
7543 * Return: None
7544 */
7545static void hdd_set_nud_stats_cb(void *data, VOS_STATUS rsp)
7546{
7547
7548 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
7549
7550 if (NULL == adapter)
7551 return;
7552
7553 if (VOS_STATUS_SUCCESS == rsp) {
7554 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7555 "%s success received STATS_SET_START", __func__);
7556 } else {
7557 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7558 "%s STATS_SET_START Failed!!", __func__);
7559 }
7560 return;
7561}
7562
7563/**
7564 * __wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
7565 * @wiphy: pointer to wireless wiphy structure.
7566 * @wdev: pointer to wireless_dev structure.
7567 * @data: pointer to apfind configuration data.
7568 * @data_len: the length in byte of apfind data.
7569 *
7570 * This is called when wlan driver needs to send arp stats to
7571 * firmware.
7572 *
7573 * Return: An error code or 0 on success.
7574 */
7575static int __wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
7576 struct wireless_dev *wdev,
7577 const void *data, int data_len)
7578{
7579 struct nlattr *tb[STATS_SET_MAX + 1];
7580 struct net_device *dev = wdev->netdev;
7581 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7582 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05307583 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
Anurag Chouhan6ee81542017-02-09 18:09:27 +05307584 setArpStatsParams arp_stats_params;
7585 int err = 0;
7586
7587 ENTER();
7588
7589 err = wlan_hdd_validate_context(hdd_ctx);
7590 if (0 != err)
7591 return err;
7592
7593 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
7594 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7595 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
7596 return -EINVAL;
7597 }
7598
7599 err = nla_parse(tb, STATS_SET_MAX, data, data_len,
7600 qca_wlan_vendor_set_nud_stats);
7601 if (err)
7602 {
7603 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7604 "%s STATS_SET_START ATTR", __func__);
7605 return err;
7606 }
7607
7608 if (tb[STATS_SET_START])
7609 {
7610 if (!tb[STATS_GW_IPV4]) {
7611 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7612 "%s STATS_SET_START CMD", __func__);
7613 return -EINVAL;
7614 }
7615 arp_stats_params.flag = true;
7616 arp_stats_params.ip_addr = nla_get_u32(tb[STATS_GW_IPV4]);
7617 } else {
7618 arp_stats_params.flag = false;
7619 }
Anurag Chouhan630c5562017-03-23 14:51:47 +05307620 if (arp_stats_params.flag)
Anurag Chouhan6ee81542017-02-09 18:09:27 +05307621 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7622 "%s STATS_SET_START Cleared!!", __func__);
Anurag Chouhan630c5562017-03-23 14:51:47 +05307623 vos_mem_zero(&adapter->hdd_stats.hddArpStats,
7624 sizeof(adapter->hdd_stats.hddArpStats));
Anurag Chouhan6ee81542017-02-09 18:09:27 +05307625
7626 arp_stats_params.pkt_type = 1; // ARP packet type
7627
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05307628 if (arp_stats_params.flag) {
7629 hdd_ctx->track_arp_ip = arp_stats_params.ip_addr;
7630 WLANTL_SetARPFWDatapath(pVosContext, true);
7631 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7632 "%s Set FW in data path for ARP with tgt IP :%d",
7633 __func__, hdd_ctx->track_arp_ip);
7634 }
7635 else {
7636 WLANTL_SetARPFWDatapath(pVosContext, false);
7637 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7638 "%s Remove FW from data path", __func__);
7639 }
7640
Anurag Chouhan6ee81542017-02-09 18:09:27 +05307641 arp_stats_params.rsp_cb_fn = hdd_set_nud_stats_cb;
7642 arp_stats_params.data_ctx = adapter;
7643
7644 if (eHAL_STATUS_SUCCESS !=
7645 sme_set_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
7646 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7647 "%s STATS_SET_START CMD Failed!!", __func__);
7648 return -EINVAL;
7649 }
7650
7651 EXIT();
7652
7653 return err;
7654}
7655
7656/**
7657 * wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
7658 * @wiphy: pointer to wireless wiphy structure.
7659 * @wdev: pointer to wireless_dev structure.
7660 * @data: pointer to apfind configuration data.
7661 * @data_len: the length in byte of apfind data.
7662 *
7663 * This is called when wlan driver needs to send arp stats to
7664 * firmware.
7665 *
7666 * Return: An error code or 0 on success.
7667 */
7668static int wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
7669 struct wireless_dev *wdev,
7670 const void *data, int data_len)
7671{
7672 int ret;
7673
7674 vos_ssr_protect(__func__);
7675 ret = __wlan_hdd_cfg80211_set_nud_stats(wiphy, wdev, data, data_len);
7676 vos_ssr_unprotect(__func__);
7677
7678 return ret;
7679}
7680#undef STATS_SET_INVALID
7681#undef STATS_SET_START
7682#undef STATS_GW_IPV4
7683#undef STATS_SET_MAX
7684
7685/*
7686 * define short names for the global vendor params
7687 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
7688 */
7689#define STATS_GET_INVALID \
7690 QCA_ATTR_NUD_STATS_SET_INVALID
7691#define COUNT_FROM_NETDEV \
7692 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
7693#define COUNT_TO_LOWER_MAC \
7694 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
7695#define RX_COUNT_BY_LOWER_MAC \
7696 QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
7697#define COUNT_TX_SUCCESS \
7698 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
7699#define RSP_RX_COUNT_BY_LOWER_MAC \
7700 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
7701#define RSP_RX_COUNT_BY_UPPER_MAC \
7702 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
7703#define RSP_COUNT_TO_NETDEV \
7704 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
7705#define RSP_COUNT_OUT_OF_ORDER_DROP \
7706 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
7707#define AP_LINK_ACTIVE \
7708 QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
7709#define AP_LINK_DAD \
7710 QCA_ATTR_NUD_STATS_AP_LINK_DAD
7711#define STATS_GET_MAX \
7712 QCA_ATTR_NUD_STATS_GET_MAX
7713
7714const struct nla_policy
7715qca_wlan_vendor_get_nud_stats[STATS_GET_MAX +1] =
7716{
7717 [COUNT_FROM_NETDEV] = {.type = NLA_U16 },
7718 [COUNT_TO_LOWER_MAC] = {.type = NLA_U16 },
7719 [RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
7720 [COUNT_TX_SUCCESS] = {.type = NLA_U16 },
7721 [RSP_RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
7722 [RSP_RX_COUNT_BY_UPPER_MAC] = {.type = NLA_U16 },
7723 [RSP_COUNT_TO_NETDEV] = {.type = NLA_U16 },
7724 [RSP_COUNT_OUT_OF_ORDER_DROP] = {.type = NLA_U16 },
7725 [AP_LINK_ACTIVE] = {.type = NLA_FLAG },
7726 [AP_LINK_DAD] = {.type = NLA_FLAG },
7727};
7728
7729static void hdd_get_nud_stats_cb(void *data, rsp_stats *rsp)
7730{
7731
7732 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
7733 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
7734 struct hdd_nud_stats_context *context;
7735 int status;
7736
7737 ENTER();
7738
7739 if (NULL == adapter)
7740 return;
7741
7742 status = wlan_hdd_validate_context(hdd_ctx);
7743 if (0 != status) {
7744 return;
7745 }
7746
7747 if (!rsp) {
7748 hddLog(LOGE, FL("data is null"));
7749 return;
7750 }
7751
7752 adapter->hdd_stats.hddArpStats.tx_fw_cnt = rsp->tx_fw_cnt;
7753 adapter->hdd_stats.hddArpStats.rx_fw_cnt = rsp->rx_fw_cnt;
7754 adapter->hdd_stats.hddArpStats.tx_ack_cnt = rsp->tx_ack_cnt;
7755 adapter->dad |= rsp->dad;
7756
7757 spin_lock(&hdd_context_lock);
7758 context = &hdd_ctx->nud_stats_context;
7759 complete(&context->response_event);
7760 spin_unlock(&hdd_context_lock);
7761
7762 return;
7763}
7764static int __wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
7765 struct wireless_dev *wdev,
7766 const void *data, int data_len)
7767{
7768 int err = 0;
7769 unsigned long rc;
7770 struct hdd_nud_stats_context *context;
7771 struct net_device *dev = wdev->netdev;
7772 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7773 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7774 getArpStatsParams arp_stats_params;
7775 struct sk_buff *skb;
7776
7777 ENTER();
7778
7779 err = wlan_hdd_validate_context(hdd_ctx);
7780 if (0 != err)
7781 return err;
7782
7783 arp_stats_params.pkt_type = WLAN_NUD_STATS_ARP_PKT_TYPE;
7784 arp_stats_params.get_rsp_cb_fn = hdd_get_nud_stats_cb;
7785 arp_stats_params.data_ctx = adapter;
7786
7787 spin_lock(&hdd_context_lock);
7788 context = &hdd_ctx->nud_stats_context;
7789 INIT_COMPLETION(context->response_event);
7790 spin_unlock(&hdd_context_lock);
7791
7792 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
7793 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7794 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
7795 return -EINVAL;
7796 }
7797
7798 if (eHAL_STATUS_SUCCESS !=
7799 sme_get_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
7800 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7801 "%s STATS_SET_START CMD Failed!!", __func__);
7802 return -EINVAL;
7803 }
7804
7805 rc = wait_for_completion_timeout(&context->response_event,
7806 msecs_to_jiffies(WLAN_WAIT_TIME_NUD_STATS));
7807 if (!rc)
7808 {
7809 hddLog(LOGE,
7810 FL("Target response timed out request "));
7811 return -ETIMEDOUT;
7812 }
7813
7814 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7815 WLAN_NUD_STATS_LEN);
7816 if (!skb)
7817 {
7818 hddLog(VOS_TRACE_LEVEL_ERROR,
7819 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
7820 __func__);
7821 return -ENOMEM;
7822 }
7823
7824 if (nla_put_u16(skb, COUNT_FROM_NETDEV,
7825 adapter->hdd_stats.hddArpStats.txCount) ||
7826 nla_put_u16(skb, COUNT_TO_LOWER_MAC,
7827 adapter->hdd_stats.hddArpStats.tx_host_fw_sent) ||
7828 nla_put_u16(skb, RX_COUNT_BY_LOWER_MAC,
7829 adapter->hdd_stats.hddArpStats.tx_fw_cnt) ||
7830 nla_put_u16(skb, COUNT_TX_SUCCESS,
7831 adapter->hdd_stats.hddArpStats.tx_ack_cnt) ||
7832 nla_put_u16(skb, RSP_RX_COUNT_BY_LOWER_MAC,
7833 adapter->hdd_stats.hddArpStats.rx_fw_cnt) ||
7834 nla_put_u16(skb, RSP_RX_COUNT_BY_UPPER_MAC,
7835 adapter->hdd_stats.hddArpStats.rxCount) ||
7836 nla_put_u16(skb, RSP_COUNT_TO_NETDEV,
7837 adapter->hdd_stats.hddArpStats.rxDelivered) ||
7838 nla_put_u16(skb, RSP_COUNT_OUT_OF_ORDER_DROP,
7839 adapter->hdd_stats.hddArpStats.rx_host_drop_reorder)) {
7840 hddLog(LOGE, FL("nla put fail"));
7841 kfree_skb(skb);
7842 return -EINVAL;
7843 }
7844 if (adapter->con_status)
7845 nla_put_flag(skb, AP_LINK_ACTIVE);
7846 if (adapter->dad)
7847 nla_put_flag(skb, AP_LINK_DAD);
7848
7849 cfg80211_vendor_cmd_reply(skb);
7850 return err;
7851}
7852
7853static int wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
7854 struct wireless_dev *wdev,
7855 const void *data, int data_len)
7856{
7857 int ret;
7858
7859 vos_ssr_protect(__func__);
7860 ret = __wlan_hdd_cfg80211_get_nud_stats(wiphy, wdev, data, data_len);
7861 vos_ssr_unprotect(__func__);
7862
7863 return ret;
7864}
7865
7866#undef QCA_ATTR_NUD_STATS_SET_INVALID
7867#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
7868#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
7869#undef QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
7870#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
7871#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
7872#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
7873#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
7874#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
7875#undef QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
7876#undef QCA_ATTR_NUD_STATS_GET_MAX
7877
7878
7879
Kapil Guptaee33bf12016-12-20 18:27:37 +05307880#ifdef WLAN_FEATURE_APFIND
7881/**
7882 * __wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
7883 * @wiphy: pointer to wireless wiphy structure.
7884 * @wdev: pointer to wireless_dev structure.
7885 * @data: pointer to apfind configuration data.
7886 * @data_len: the length in byte of apfind data.
7887 *
7888 * This is called when wlan driver needs to send APFIND configurations to
7889 * firmware.
7890 *
7891 * Return: An error code or 0 on success.
7892 */
7893static int __wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
7894 struct wireless_dev *wdev,
7895 const void *data, int data_len)
7896{
7897 struct sme_ap_find_request_req apfind_req;
7898 VOS_STATUS status;
7899 int ret_val;
7900 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7901
7902 ENTER();
7903
7904 ret_val = wlan_hdd_validate_context(hdd_ctx);
7905 if (ret_val)
7906 return ret_val;
7907
7908 if (VOS_FTM_MODE == hdd_get_conparam()) {
7909 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7910 return -EPERM;
7911 }
7912
7913 apfind_req.request_data_len = data_len;
7914 apfind_req.request_data = data;
7915
7916 status = sme_apfind_set_cmd(&apfind_req);
7917 if (VOS_STATUS_SUCCESS != status) {
7918 ret_val = -EIO;
7919 }
7920 return ret_val;
7921}
7922
7923/**
7924 * wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
7925 * @wiphy: pointer to wireless wiphy structure.
7926 * @wdev: pointer to wireless_dev structure.
7927 * @data: pointer to apfind configuration data.
7928 * @data_len: the length in byte of apfind data.
7929 *
7930 * This is called when wlan driver needs to send APFIND configurations to
7931 * firmware.
7932 *
7933 * Return: An error code or 0 on success.
7934 */
7935static int wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
7936 struct wireless_dev *wdev,
7937 const void *data, int data_len)
7938{
7939 int ret;
7940
7941 vos_ssr_protect(__func__);
7942 ret = __wlan_hdd_cfg80211_apfind_cmd(wiphy, wdev, data, data_len);
7943 vos_ssr_unprotect(__func__);
7944
7945 return ret;
7946}
7947#endif /* WLAN_FEATURE_APFIND */
Sunil Duttc69bccb2014-05-26 21:30:20 +05307948const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
7949{
Mukul Sharma2a271632014-10-13 14:59:01 +05307950 {
7951 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7952 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
7953 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7954 WIPHY_VENDOR_CMD_NEED_NETDEV |
7955 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307956 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05307957 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05307958
7959 {
7960 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7961 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
7962 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7963 WIPHY_VENDOR_CMD_NEED_NETDEV |
7964 WIPHY_VENDOR_CMD_NEED_RUNNING,
7965 .doit = wlan_hdd_cfg80211_nan_request
7966 },
7967
Sunil Duttc69bccb2014-05-26 21:30:20 +05307968#ifdef WLAN_FEATURE_LINK_LAYER_STATS
7969 {
7970 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7971 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
7972 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7973 WIPHY_VENDOR_CMD_NEED_NETDEV |
7974 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307975 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05307976 },
7977
7978 {
7979 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7980 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
7981 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7982 WIPHY_VENDOR_CMD_NEED_NETDEV |
7983 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307984 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05307985 },
7986
7987 {
7988 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7989 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
7990 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7991 WIPHY_VENDOR_CMD_NEED_NETDEV |
7992 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307993 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05307994 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05307995#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05307996#ifdef WLAN_FEATURE_EXTSCAN
7997 {
7998 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7999 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
8000 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8001 WIPHY_VENDOR_CMD_NEED_NETDEV |
8002 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308003 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05308004 },
8005 {
8006 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8007 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
8008 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8009 WIPHY_VENDOR_CMD_NEED_NETDEV |
8010 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308011 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05308012 },
8013 {
8014 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8015 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
8016 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8017 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308018 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05308019 },
8020 {
8021 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8022 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
8023 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8024 WIPHY_VENDOR_CMD_NEED_NETDEV |
8025 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308026 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05308027 },
8028 {
8029 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8030 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
8031 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8032 WIPHY_VENDOR_CMD_NEED_NETDEV |
8033 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308034 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05308035 },
8036 {
8037 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8038 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
8039 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8040 WIPHY_VENDOR_CMD_NEED_NETDEV |
8041 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308042 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308043 },
8044 {
8045 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8046 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
8047 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8048 WIPHY_VENDOR_CMD_NEED_NETDEV |
8049 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308050 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308051 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308052#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308053/*EXT TDLS*/
8054 {
8055 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8056 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
8057 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8058 WIPHY_VENDOR_CMD_NEED_NETDEV |
8059 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308060 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05308061 },
8062 {
8063 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8064 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
8065 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8066 WIPHY_VENDOR_CMD_NEED_NETDEV |
8067 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308068 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05308069 },
8070 {
8071 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8072 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
8073 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8074 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308075 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05308076 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05308077 {
8078 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8079 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
8080 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8081 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308082 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05308083 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05308084 {
8085 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8086 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
8087 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8088 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308089 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05308090 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308091 {
8092 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8093 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
8094 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8095 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308096 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308097 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308098 {
8099 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8100 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
8101 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8102 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308103 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308104 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308105 {
8106 .info.vendor_id = QCA_NL80211_VENDOR_ID,
c_manjeecfd1efb2015-09-25 19:32:34 +05308107 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
8108 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8109 WIPHY_VENDOR_CMD_NEED_NETDEV |
8110 WIPHY_VENDOR_CMD_NEED_RUNNING,
8111 .doit = wlan_hdd_cfg80211_get_fw_mem_dump
8112 },
8113 {
8114 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308115 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
8116 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8117 WIPHY_VENDOR_CMD_NEED_NETDEV |
8118 WIPHY_VENDOR_CMD_NEED_RUNNING,
8119 .doit = wlan_hdd_cfg80211_setband
Sushant Kaushik8e644982015-09-23 12:18:54 +05308120 },
8121 {
8122 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8123 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
8124 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8125 WIPHY_VENDOR_CMD_NEED_NETDEV,
8126 .doit = wlan_hdd_cfg80211_wifi_logger_start
8127 },
Sushant Kaushik847890c2015-09-28 16:05:17 +05308128 {
8129 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8130 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
8131 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8132 WIPHY_VENDOR_CMD_NEED_NETDEV|
8133 WIPHY_VENDOR_CMD_NEED_RUNNING,
8134 .doit = wlan_hdd_cfg80211_get_wifi_info
Sachin Ahujac08f72a2015-09-22 15:25:47 +05308135 },
8136 {
8137 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8138 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
8139 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8140 WIPHY_VENDOR_CMD_NEED_NETDEV |
8141 WIPHY_VENDOR_CMD_NEED_RUNNING,
8142 .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308143 },
8144 {
8145 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8146 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,
8147 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8148 WIPHY_VENDOR_CMD_NEED_NETDEV |
8149 WIPHY_VENDOR_CMD_NEED_RUNNING,
8150 .doit = wlan_hdd_cfg80211_monitor_rssi
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308151 },
8152#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
8153 {
8154 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8155 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS,
8156 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8157 WIPHY_VENDOR_CMD_NEED_NETDEV |
8158 WIPHY_VENDOR_CMD_NEED_RUNNING,
8159 .doit = wlan_hdd_cfg80211_offloaded_packets
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308160 },
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308161#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308162 {
8163 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8164 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
8165 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8166 WIPHY_VENDOR_CMD_NEED_NETDEV |
8167 WIPHY_VENDOR_CMD_NEED_RUNNING,
8168 .doit = wlan_hdd_cfg80211_get_link_properties
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05308169 },
8170 {
8171 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8172 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION,
8173 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8174 WIPHY_VENDOR_CMD_NEED_NETDEV |
8175 WIPHY_VENDOR_CMD_NEED_RUNNING,
8176 .doit = wlan_hdd_cfg80211_wifi_configuration_set
Kapil Guptaee33bf12016-12-20 18:27:37 +05308177 },
8178#ifdef WLAN_FEATURE_APFIND
8179 {
8180 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8181 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_APFIND,
8182 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8183 WIPHY_VENDOR_CMD_NEED_NETDEV,
8184 .doit = wlan_hdd_cfg80211_apfind_cmd
8185 },
8186#endif /* WLAN_FEATURE_APFIND */
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308187 {
8188 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8189 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET,
8190 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8191 WIPHY_VENDOR_CMD_NEED_NETDEV |
8192 WIPHY_VENDOR_CMD_NEED_RUNNING,
8193 .doit = wlan_hdd_cfg80211_set_nud_stats
8194 },
8195 {
8196 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8197 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8198 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8199 WIPHY_VENDOR_CMD_NEED_NETDEV |
8200 WIPHY_VENDOR_CMD_NEED_RUNNING,
8201 .doit = wlan_hdd_cfg80211_get_nud_stats
8202 },
Anurag Chouhanfcd20172017-07-19 17:25:19 +05308203 {
8204 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8205 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_STATION,
8206 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8207 WIPHY_VENDOR_CMD_NEED_NETDEV |
8208 WIPHY_VENDOR_CMD_NEED_RUNNING,
8209 .doit = hdd_cfg80211_get_station_cmd
8210 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308211};
8212
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008213/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05308214static const
8215struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008216{
8217#ifdef FEATURE_WLAN_CH_AVOID
8218 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05308219 .vendor_id = QCA_NL80211_VENDOR_ID,
8220 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008221 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308222#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
8223#ifdef WLAN_FEATURE_LINK_LAYER_STATS
8224 {
8225 /* Index = 1*/
8226 .vendor_id = QCA_NL80211_VENDOR_ID,
8227 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
8228 },
8229 {
8230 /* Index = 2*/
8231 .vendor_id = QCA_NL80211_VENDOR_ID,
8232 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
8233 },
8234 {
8235 /* Index = 3*/
8236 .vendor_id = QCA_NL80211_VENDOR_ID,
8237 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
8238 },
8239 {
8240 /* Index = 4*/
8241 .vendor_id = QCA_NL80211_VENDOR_ID,
8242 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
8243 },
8244 {
8245 /* Index = 5*/
8246 .vendor_id = QCA_NL80211_VENDOR_ID,
8247 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
8248 },
8249 {
8250 /* Index = 6*/
8251 .vendor_id = QCA_NL80211_VENDOR_ID,
8252 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
8253 },
8254#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308255#ifdef WLAN_FEATURE_EXTSCAN
8256 {
8257 .vendor_id = QCA_NL80211_VENDOR_ID,
8258 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
8259 },
8260 {
8261 .vendor_id = QCA_NL80211_VENDOR_ID,
8262 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
8263 },
8264 {
8265 .vendor_id = QCA_NL80211_VENDOR_ID,
8266 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
8267 },
8268 {
8269 .vendor_id = QCA_NL80211_VENDOR_ID,
8270 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
8271 },
8272 {
8273 .vendor_id = QCA_NL80211_VENDOR_ID,
8274 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
8275 },
8276 {
8277 .vendor_id = QCA_NL80211_VENDOR_ID,
8278 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
8279 },
8280 {
8281 .vendor_id = QCA_NL80211_VENDOR_ID,
8282 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
8283 },
8284 {
8285 .vendor_id = QCA_NL80211_VENDOR_ID,
8286 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
8287 },
8288 {
8289 .vendor_id = QCA_NL80211_VENDOR_ID,
8290 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
8291 },
8292 {
8293 .vendor_id = QCA_NL80211_VENDOR_ID,
8294 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
8295 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308296#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308297/*EXT TDLS*/
8298 {
8299 .vendor_id = QCA_NL80211_VENDOR_ID,
8300 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
8301 },
c_manjeecfd1efb2015-09-25 19:32:34 +05308302 [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
8303 .vendor_id = QCA_NL80211_VENDOR_ID,
8304 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
8305 },
8306
Srinivas Dasari030bad32015-02-18 23:23:54 +05308307
Srinivas Dasaribd1cf642017-01-23 14:54:41 +05308308 [QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX] = {
Srinivas Dasari030bad32015-02-18 23:23:54 +05308309 .vendor_id = QCA_NL80211_VENDOR_ID,
8310 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
8311 },
8312
Sushant Kaushik084f6592015-09-10 13:11:56 +05308313 {
8314 .vendor_id = QCA_NL80211_VENDOR_ID,
8315 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308316 },
8317 [QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = {
8318 .vendor_id = QCA_NL80211_VENDOR_ID,
8319 .subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI
8320 },
Padma, Santhosh Kumar7bbc7d92015-12-08 20:23:19 +05308321 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX] = {
8322 .vendor_id = QCA_NL80211_VENDOR_ID,
8323 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST
8324 },
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308325 [QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET_INDEX] = {
8326 .vendor_id = QCA_NL80211_VENDOR_ID,
8327 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8328 },
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008329};
8330
Jeff Johnson295189b2012-06-20 16:38:30 -07008331/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308332 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308333 * This function is called by hdd_wlan_startup()
8334 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308335 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07008336 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308337struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07008338{
8339 struct wiphy *wiphy;
8340 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308341 /*
8342 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07008343 */
8344 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
8345
8346 if (!wiphy)
8347 {
8348 /* Print error and jump into err label and free the memory */
8349 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
8350 return NULL;
8351 }
8352
Sunil Duttc69bccb2014-05-26 21:30:20 +05308353
Jeff Johnson295189b2012-06-20 16:38:30 -07008354 return wiphy;
8355}
8356
Anurag Chouhan343af7e2016-12-16 13:11:19 +05308357#if (LINUX_VERSION_CODE > KERNEL_VERSION(4,4,0)) || \
8358 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
8359/**
8360 * hdd_config_sched_scan_plans_to_wiphy() - configure sched scan plans to wiphy
8361 * @wiphy: pointer to wiphy
8362 * @config: pointer to config
8363 *
8364 * Return: None
8365 */
8366static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
8367 hdd_config_t *config)
8368{
8369 wiphy->max_sched_scan_plans = MAX_SCHED_SCAN_PLANS;
8370 if (config->max_sched_scan_plan_interval)
8371 wiphy->max_sched_scan_plan_interval =
8372 config->max_sched_scan_plan_interval;
8373 if (config->max_sched_scan_plan_iterations)
8374 wiphy->max_sched_scan_plan_iterations =
8375 config->max_sched_scan_plan_iterations;
8376}
8377#else
8378static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
8379 hdd_config_t *config)
8380{
8381}
8382#endif
8383
Jeff Johnson295189b2012-06-20 16:38:30 -07008384/*
8385 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308386 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07008387 * private ioctl to change the band value
8388 */
8389int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
8390{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308391 int i, j;
8392 eNVChannelEnabledType channelEnabledState;
8393
Jeff Johnsone7245742012-09-05 17:12:55 -07008394 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308395
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308396 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07008397 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308398
8399 if (NULL == wiphy->bands[i])
8400 {
8401 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
8402 __func__, i);
8403 continue;
8404 }
8405
8406 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
8407 {
8408 struct ieee80211_supported_band *band = wiphy->bands[i];
8409
8410 channelEnabledState = vos_nv_getChannelEnabledState(
8411 band->channels[j].hw_value);
8412
8413 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
8414 {
Abhishek Singh678227a2014-11-04 10:52:38 +05308415 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308416 continue;
8417 }
8418 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
8419 {
8420 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8421 continue;
8422 }
8423
8424 if (NV_CHANNEL_DISABLE == channelEnabledState ||
8425 NV_CHANNEL_INVALID == channelEnabledState)
8426 {
8427 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8428 }
8429 else if (NV_CHANNEL_DFS == channelEnabledState)
8430 {
8431 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
8432 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
8433 }
8434 else
8435 {
8436 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
8437 |IEEE80211_CHAN_RADAR);
8438 }
8439 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008440 }
8441 return 0;
8442}
8443/*
8444 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308445 * This function is called by hdd_wlan_startup()
8446 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07008447 * This function is used to initialize and register wiphy structure.
8448 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308449int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07008450 struct wiphy *wiphy,
8451 hdd_config_t *pCfg
8452 )
8453{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308454 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05308455 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
8456
Jeff Johnsone7245742012-09-05 17:12:55 -07008457 ENTER();
8458
Jeff Johnson295189b2012-06-20 16:38:30 -07008459 /* Now bind the underlying wlan device with wiphy */
8460 set_wiphy_dev(wiphy, dev);
8461
8462 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07008463
Kiet Lam6c583332013-10-14 05:37:09 +05308464#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07008465 /* the flag for the other case would be initialzed in
8466 vos_init_wiphy_from_nv_bin */
Manjeet Singh9e19de62016-08-18 18:26:41 +05308467#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
8468 wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
8469#else
Amar Singhal0a402232013-10-11 20:57:16 -07008470 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05308471#endif
Manjeet Singh9e19de62016-08-18 18:26:41 +05308472#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07008473
Amar Singhalfddc28c2013-09-05 13:03:40 -07008474 /* This will disable updating of NL channels from passive to
8475 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308476#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
8477 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
8478#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07008479 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308480#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07008481
Amar Singhala49cbc52013-10-08 18:37:44 -07008482
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008483#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07008484 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
8485 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
8486 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07008487 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308488#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Rajeev Kumar Sirasanagandla0d6dd752016-08-17 15:01:39 +05308489 wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308490#else
8491 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
8492#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008493#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07008494
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08008495#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07008496 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08008497#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07008498 || pCfg->isFastRoamIniFeatureEnabled
8499#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08008500#ifdef FEATURE_WLAN_ESE
8501 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07008502#endif
8503 )
8504 {
8505 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
8506 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08008507#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008508#ifdef FEATURE_WLAN_TDLS
8509 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
8510 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
8511#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308512#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05308513 if (pCfg->configPNOScanSupport)
8514 {
8515 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
8516 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
8517 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
8518 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
8519 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308520#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008521
Abhishek Singh10d85972015-04-17 10:27:23 +05308522#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
8523 wiphy->features |= NL80211_FEATURE_HT_IBSS;
8524#endif
8525
Amar Singhalfddc28c2013-09-05 13:03:40 -07008526#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07008527 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
8528 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07008529 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07008530 driver need to determine what to do with both
8531 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07008532
8533 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07008534#else
8535 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07008536#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008537
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308538 wiphy->max_scan_ssids = MAX_SCAN_SSID;
8539
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05308540 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07008541
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308542 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
8543
Jeff Johnson295189b2012-06-20 16:38:30 -07008544 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05308545 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
8546 | BIT(NL80211_IFTYPE_ADHOC)
8547 | BIT(NL80211_IFTYPE_P2P_CLIENT)
8548 | BIT(NL80211_IFTYPE_P2P_GO)
8549 | BIT(NL80211_IFTYPE_AP);
8550
8551 if (VOS_MONITOR_MODE == hdd_get_conparam())
8552 {
8553 wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
8554 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008555
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308556 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008557 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308558#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
8559 if( pCfg->enableMCC )
8560 {
8561 /* Currently, supports up to two channels */
8562 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008563
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308564 if( !pCfg->allowMCCGODiffBI )
8565 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008566
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308567 }
8568 wiphy->iface_combinations = &wlan_hdd_iface_combination;
8569 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008570#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308571 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008572
Jeff Johnson295189b2012-06-20 16:38:30 -07008573 /* Before registering we need to update the ht capabilitied based
8574 * on ini values*/
8575 if( !pCfg->ShortGI20MhzEnable )
8576 {
8577 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
8578 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
Jeff Johnson295189b2012-06-20 16:38:30 -07008579 }
8580
8581 if( !pCfg->ShortGI40MhzEnable )
8582 {
8583 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
8584 }
8585
8586 if( !pCfg->nChannelBondingMode5GHz )
8587 {
8588 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
8589 }
Agrawal Ashish97dec502015-11-26 20:20:58 +05308590 /*
8591 * In case of static linked driver at the time of driver unload,
8592 * module exit doesn't happens. Module cleanup helps in cleaning
8593 * of static memory.
8594 * If driver load happens statically, at the time of driver unload,
8595 * wiphy flags don't get reset because of static memory.
8596 * It's better not to store channel in static memory.
8597 */
8598 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
8599 wiphy->bands[IEEE80211_BAND_2GHZ]->channels =
8600 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_2_4_GHZ));
8601 if (wiphy->bands[IEEE80211_BAND_2GHZ]->channels == NULL)
8602 {
8603 hddLog(VOS_TRACE_LEVEL_ERROR,
8604 FL("Not enough memory to allocate channels"));
8605 return -ENOMEM;
8606 }
8607 vos_mem_copy(wiphy->bands[IEEE80211_BAND_2GHZ]->channels,
8608 &hdd_channels_2_4_GHZ[0],
8609 sizeof(hdd_channels_2_4_GHZ));
Jeff Johnson295189b2012-06-20 16:38:30 -07008610
Agrawal Ashish97dec502015-11-26 20:20:58 +05308611 if (true == hdd_is_5g_supported(pHddCtx))
8612 {
8613 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
8614 wiphy->bands[IEEE80211_BAND_5GHZ]->channels =
8615 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_5_GHZ));
8616 if (wiphy->bands[IEEE80211_BAND_5GHZ]->channels == NULL)
8617 {
8618 hddLog(VOS_TRACE_LEVEL_ERROR,
8619 FL("Not enough memory to allocate channels"));
8620 vos_mem_free(wiphy->bands[IEEE80211_BAND_2GHZ]->channels);
8621 wiphy->bands[IEEE80211_BAND_2GHZ]->channels = NULL;
8622 return -ENOMEM;
8623 }
8624 vos_mem_copy(wiphy->bands[IEEE80211_BAND_5GHZ]->channels,
8625 &hdd_channels_5_GHZ[0],
8626 sizeof(hdd_channels_5_GHZ));
8627 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308628
8629 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
8630 {
8631
8632 if (NULL == wiphy->bands[i])
8633 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05308634 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308635 __func__, i);
8636 continue;
8637 }
8638
8639 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
8640 {
8641 struct ieee80211_supported_band *band = wiphy->bands[i];
8642
8643 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
8644 {
8645 // Enable social channels for P2P
8646 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
8647 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
8648 else
8649 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8650 continue;
8651 }
8652 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
8653 {
8654 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8655 continue;
8656 }
8657 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008658 }
8659 /*Initialise the supported cipher suite details*/
8660 wiphy->cipher_suites = hdd_cipher_suites;
8661 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
8662
8663 /*signal strength in mBm (100*dBm) */
8664 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
8665
8666#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05308667 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07008668#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008669
Sunil Duttc69bccb2014-05-26 21:30:20 +05308670 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
8671 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008672 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
8673 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
8674
Anurag Chouhan343af7e2016-12-16 13:11:19 +05308675 hdd_config_sched_scan_plans_to_wiphy(wiphy, pCfg);
8676
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308677 EXIT();
8678 return 0;
8679}
8680
8681/* In this function we are registering wiphy. */
8682int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
8683{
8684 ENTER();
8685 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008686 if (0 > wiphy_register(wiphy))
8687 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308688 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07008689 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8690 return -EIO;
8691 }
8692
8693 EXIT();
8694 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308695}
Jeff Johnson295189b2012-06-20 16:38:30 -07008696
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308697/* In this function we are updating channel list when,
8698 regulatory domain is FCC and country code is US.
8699 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
8700 As per FCC smart phone is not a indoor device.
8701 GO should not opeate on indoor channels */
8702void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
8703{
8704 int j;
8705 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
8706 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
8707 //Default counrtycode from NV at the time of wiphy initialization.
8708 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
8709 &defaultCountryCode[0]))
8710 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008711 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308712 }
8713 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
8714 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308715 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
8716 {
8717 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
8718 return;
8719 }
8720 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
8721 {
8722 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
8723 // Mark UNII -1 band channel as passive
8724 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
8725 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
8726 }
8727 }
8728}
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05308729/* This function registers for all frame which supplicant is interested in */
8730void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008731{
Jeff Johnson295189b2012-06-20 16:38:30 -07008732 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8733 /* Register for all P2P action, public action etc frames */
8734 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
Jeff Johnsone7245742012-09-05 17:12:55 -07008735 ENTER();
Abhishek Singh16e05762015-11-30 14:29:27 +05308736 /* Register frame indication call back */
8737 sme_register_mgmt_frame_ind_callback(hHal, hdd_indicate_mgmt_frame);
Jeff Johnson295189b2012-06-20 16:38:30 -07008738 /* Right now we are registering these frame when driver is getting
8739 initialized. Once we will move to 2.6.37 kernel, in which we have
8740 frame register ops, we will move this code as a part of that */
8741 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308742 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07008743 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
8744
8745 /* GAS Initial Response */
8746 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8747 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308748
Jeff Johnson295189b2012-06-20 16:38:30 -07008749 /* GAS Comeback Request */
8750 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8751 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
8752
8753 /* GAS Comeback Response */
8754 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8755 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
8756
8757 /* P2P Public Action */
8758 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308759 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07008760 P2P_PUBLIC_ACTION_FRAME_SIZE );
8761
8762 /* P2P Action */
8763 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8764 (v_U8_t*)P2P_ACTION_FRAME,
8765 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07008766
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05308767 /* WNM BSS Transition Request frame */
8768 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8769 (v_U8_t*)WNM_BSS_ACTION_FRAME,
8770 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07008771
8772 /* WNM-Notification */
8773 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8774 (v_U8_t*)WNM_NOTIFICATION_FRAME,
8775 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008776}
8777
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05308778void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008779{
Jeff Johnson295189b2012-06-20 16:38:30 -07008780 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8781 /* Register for all P2P action, public action etc frames */
8782 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
8783
Jeff Johnsone7245742012-09-05 17:12:55 -07008784 ENTER();
8785
Jeff Johnson295189b2012-06-20 16:38:30 -07008786 /* Right now we are registering these frame when driver is getting
8787 initialized. Once we will move to 2.6.37 kernel, in which we have
8788 frame register ops, we will move this code as a part of that */
8789 /* GAS Initial Request */
8790
8791 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8792 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
8793
8794 /* GAS Initial Response */
8795 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8796 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308797
Jeff Johnson295189b2012-06-20 16:38:30 -07008798 /* GAS Comeback Request */
8799 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8800 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
8801
8802 /* GAS Comeback Response */
8803 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8804 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
8805
8806 /* P2P Public Action */
8807 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308808 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07008809 P2P_PUBLIC_ACTION_FRAME_SIZE );
8810
8811 /* P2P Action */
8812 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8813 (v_U8_t*)P2P_ACTION_FRAME,
8814 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07008815 /* WNM-Notification */
8816 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8817 (v_U8_t*)WNM_NOTIFICATION_FRAME,
8818 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008819}
8820
8821#ifdef FEATURE_WLAN_WAPI
8822void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05308823 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07008824{
8825 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8826 tCsrRoamSetKey setKey;
8827 v_BOOL_t isConnected = TRUE;
8828 int status = 0;
8829 v_U32_t roamId= 0xFF;
8830 tANI_U8 *pKeyPtr = NULL;
8831 int n = 0;
8832
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308833 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
8834 __func__, hdd_device_modetoString(pAdapter->device_mode),
8835 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008836
Gopichand Nakkalae7480202013-02-11 15:24:22 +05308837 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07008838 setKey.keyId = key_index; // Store Key ID
8839 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
8840 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
8841 setKey.paeRole = 0 ; // the PAE role
8842 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
8843 {
8844 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
8845 }
8846 else
8847 {
8848 isConnected = hdd_connIsConnected(pHddStaCtx);
8849 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
8850 }
8851 setKey.keyLength = key_Len;
8852 pKeyPtr = setKey.Key;
8853 memcpy( pKeyPtr, key, key_Len);
8854
Arif Hussain6d2a3322013-11-17 19:50:10 -08008855 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07008856 __func__, key_Len);
8857 for (n = 0 ; n < key_Len; n++)
8858 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
8859 __func__,n,setKey.Key[n]);
8860
8861 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8862 if ( isConnected )
8863 {
8864 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8865 pAdapter->sessionId, &setKey, &roamId );
8866 }
8867 if ( status != 0 )
8868 {
8869 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8870 "[%4d] sme_RoamSetKey returned ERROR status= %d",
8871 __LINE__, status );
8872 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8873 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308874 /* Need to clear any trace of key value in the memory.
8875 * Thus zero out the memory even though it is local
8876 * variable.
8877 */
8878 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07008879}
8880#endif /* FEATURE_WLAN_WAPI*/
8881
8882#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308883int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07008884 beacon_data_t **ppBeacon,
8885 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008886#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308887int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008888 beacon_data_t **ppBeacon,
8889 struct cfg80211_beacon_data *params,
8890 int dtim_period)
8891#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308892{
Jeff Johnson295189b2012-06-20 16:38:30 -07008893 int size;
8894 beacon_data_t *beacon = NULL;
8895 beacon_data_t *old = NULL;
Kapil Gupta137ef892016-12-13 19:38:00 +05308896 int head_len, tail_len, proberesp_ies_len, assocresp_ies_len;
8897 const u8 *head, *tail, *proberesp_ies, *assocresp_ies;
Jeff Johnson295189b2012-06-20 16:38:30 -07008898
Jeff Johnsone7245742012-09-05 17:12:55 -07008899 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008900 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308901 {
8902 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8903 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008904 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308905 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008906
8907 old = pAdapter->sessionCtx.ap.beacon;
8908
8909 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308910 {
8911 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8912 FL("session(%d) old and new heads points to NULL"),
8913 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008914 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308915 }
8916
8917 if (params->tail && !params->tail_len)
8918 {
8919 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8920 FL("tail_len is zero but tail is not NULL"));
8921 return -EINVAL;
8922 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008923
Jeff Johnson295189b2012-06-20 16:38:30 -07008924#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
8925 /* Kernel 3.0 is not updating dtim_period for set beacon */
8926 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308927 {
8928 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8929 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008930 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308931 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008932#endif
8933
Kapil Gupta137ef892016-12-13 19:38:00 +05308934 if (params->head)
8935 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008936 head_len = params->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05308937 head = params->head;
8938 } else
8939 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008940 head_len = old->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05308941 head = old->head;
8942 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008943
Kapil Gupta137ef892016-12-13 19:38:00 +05308944 if (params->tail || !old)
8945 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008946 tail_len = params->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05308947 tail = params->tail;
8948 } else
8949 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008950 tail_len = old->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05308951 tail = old->tail;
8952 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008953
Kapil Gupta137ef892016-12-13 19:38:00 +05308954 if (params->proberesp_ies || !old)
8955 {
8956 proberesp_ies_len = params->proberesp_ies_len;
8957 proberesp_ies = params->proberesp_ies;
8958 } else
8959 {
8960 proberesp_ies_len = old->proberesp_ies_len;
8961 proberesp_ies = old->proberesp_ies;
8962 }
8963
8964 if (params->assocresp_ies || !old)
8965 {
8966 assocresp_ies_len = params->assocresp_ies_len;
8967 assocresp_ies = params->assocresp_ies;
8968 } else
8969 {
8970 assocresp_ies_len = old->assocresp_ies_len;
8971 assocresp_ies = old->assocresp_ies;
8972 }
8973
8974 size = sizeof(beacon_data_t) + head_len + tail_len +
8975 proberesp_ies_len + assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07008976
8977 beacon = kzalloc(size, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07008978 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308979 {
8980 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8981 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008982 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308983 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008984
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008985#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Kapil Gupta137ef892016-12-13 19:38:00 +05308986 if (params->dtim_period)
Jeff Johnson295189b2012-06-20 16:38:30 -07008987 beacon->dtim_period = params->dtim_period;
8988 else
8989 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008990#else
Kapil Gupta137ef892016-12-13 19:38:00 +05308991 if (dtim_period)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008992 beacon->dtim_period = dtim_period;
8993 else
8994 beacon->dtim_period = old->dtim_period;
8995#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308996
Jeff Johnson295189b2012-06-20 16:38:30 -07008997 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
8998 beacon->tail = beacon->head + head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05308999 beacon->proberesp_ies = beacon->tail + tail_len;
9000 beacon->assocresp_ies = beacon->proberesp_ies + proberesp_ies_len;
9001
Jeff Johnson295189b2012-06-20 16:38:30 -07009002 beacon->head_len = head_len;
9003 beacon->tail_len = tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309004 beacon->proberesp_ies_len = proberesp_ies_len;
9005 beacon->assocresp_ies_len= assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009006
c_manjee527ecac2017-01-25 12:25:27 +05309007 if (head && head_len)
9008 memcpy(beacon->head, head, head_len);
9009 if (tail && tail_len)
9010 memcpy(beacon->tail, tail, tail_len);
9011 if (proberesp_ies && proberesp_ies_len)
9012 memcpy(beacon->proberesp_ies, proberesp_ies, proberesp_ies_len);
9013 if (assocresp_ies && assocresp_ies_len)
9014 memcpy(beacon->assocresp_ies, assocresp_ies, assocresp_ies_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009015
9016 *ppBeacon = beacon;
9017
9018 kfree(old);
9019
9020 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009021}
Jeff Johnson295189b2012-06-20 16:38:30 -07009022
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309023v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
9024#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
9025 const v_U8_t *pIes,
9026#else
9027 v_U8_t *pIes,
9028#endif
9029 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009030{
9031 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309032 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07009033 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309034
Jeff Johnson295189b2012-06-20 16:38:30 -07009035 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309036 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009037 elem_id = ptr[0];
9038 elem_len = ptr[1];
9039 left -= 2;
9040 if(elem_len > left)
9041 {
9042 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07009043 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009044 eid,elem_len,left);
9045 return NULL;
9046 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309047 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009048 {
9049 return ptr;
9050 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309051
Jeff Johnson295189b2012-06-20 16:38:30 -07009052 left -= elem_len;
9053 ptr += (elem_len + 2);
9054 }
9055 return NULL;
9056}
9057
Jeff Johnson295189b2012-06-20 16:38:30 -07009058/* Check if rate is 11g rate or not */
9059static int wlan_hdd_rate_is_11g(u8 rate)
9060{
Sanjay Devnani28322e22013-06-21 16:13:40 -07009061 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009062 u8 i;
9063 for (i = 0; i < 8; i++)
9064 {
9065 if(rate == gRateArray[i])
9066 return TRUE;
9067 }
9068 return FALSE;
9069}
9070
9071/* Check for 11g rate and set proper 11g only mode */
9072static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
9073 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
9074{
9075 u8 i, num_rates = pIe[0];
9076
9077 pIe += 1;
9078 for ( i = 0; i < num_rates; i++)
9079 {
9080 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
9081 {
9082 /* If rate set have 11g rate than change the mode to 11G */
9083 *pSapHw_mode = eSAP_DOT11_MODE_11g;
9084 if (pIe[i] & BASIC_RATE_MASK)
9085 {
9086 /* If we have 11g rate as basic rate, it means mode
9087 is 11g only mode.
9088 */
9089 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
9090 *pCheckRatesfor11g = FALSE;
9091 }
9092 }
9093 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
9094 {
9095 *require_ht = TRUE;
9096 }
9097 }
9098 return;
9099}
9100
9101static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
9102{
9103 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9104 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9105 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9106 u8 checkRatesfor11g = TRUE;
9107 u8 require_ht = FALSE;
9108 u8 *pIe=NULL;
9109
9110 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
9111
9112 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
9113 pBeacon->head_len, WLAN_EID_SUPP_RATES);
9114 if (pIe != NULL)
9115 {
9116 pIe += 1;
9117 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9118 &pConfig->SapHw_mode);
9119 }
9120
9121 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9122 WLAN_EID_EXT_SUPP_RATES);
9123 if (pIe != NULL)
9124 {
9125
9126 pIe += 1;
9127 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9128 &pConfig->SapHw_mode);
9129 }
9130
9131 if( pConfig->channel > 14 )
9132 {
9133 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
9134 }
9135
9136 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9137 WLAN_EID_HT_CAPABILITY);
9138
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309139 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009140 {
9141 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
9142 if(require_ht)
9143 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
9144 }
9145}
9146
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309147static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
9148 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
9149{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009150 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309151 v_U8_t *pIe = NULL;
9152 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9153
9154 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
9155 pBeacon->tail, pBeacon->tail_len);
9156
9157 if (pIe)
9158 {
9159 ielen = pIe[1] + 2;
9160 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9161 {
9162 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
9163 }
9164 else
9165 {
9166 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
9167 return -EINVAL;
9168 }
9169 *total_ielen += ielen;
9170 }
9171 return 0;
9172}
9173
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009174static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
9175 v_U8_t *genie, v_U8_t *total_ielen)
9176{
9177 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9178 int left = pBeacon->tail_len;
9179 v_U8_t *ptr = pBeacon->tail;
9180 v_U8_t elem_id, elem_len;
9181 v_U16_t ielen = 0;
9182
9183 if ( NULL == ptr || 0 == left )
9184 return;
9185
9186 while (left >= 2)
9187 {
9188 elem_id = ptr[0];
9189 elem_len = ptr[1];
9190 left -= 2;
9191 if (elem_len > left)
9192 {
9193 hddLog( VOS_TRACE_LEVEL_ERROR,
9194 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
9195 elem_id, elem_len, left);
9196 return;
9197 }
Ashish Kumar Dhanotiya6af276b2017-08-22 16:53:48 +05309198 if ((IE_EID_VENDOR == elem_id) && (elem_len >= WPS_OUI_TYPE_SIZE))
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009199 {
9200 /* skipping the VSIE's which we don't want to include or
9201 * it will be included by existing code
9202 */
9203 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
9204#ifdef WLAN_FEATURE_WFD
9205 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
9206#endif
9207 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9208 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9209 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
9210 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9211 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
9212 {
9213 ielen = ptr[1] + 2;
9214 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9215 {
9216 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
9217 *total_ielen += ielen;
9218 }
9219 else
9220 {
9221 hddLog( VOS_TRACE_LEVEL_ERROR,
9222 "IE Length is too big "
9223 "IEs eid=%d elem_len=%d total_ie_lent=%d",
9224 elem_id, elem_len, *total_ielen);
9225 }
9226 }
9227 }
9228
9229 left -= elem_len;
9230 ptr += (elem_len + 2);
9231 }
9232 return;
9233}
9234
Kapil Gupta137ef892016-12-13 19:38:00 +05309235int wlan_hdd_cfg80211_update_apies(hdd_adapter_t *pHostapdAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009236{
9237 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309238 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009239 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07009240 int ret = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +05309241 beacon_data_t *pBeacon = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009242
9243 genie = vos_mem_malloc(MAX_GENIE_LEN);
9244
9245 if(genie == NULL) {
9246
9247 return -ENOMEM;
9248 }
9249
Kapil Gupta137ef892016-12-13 19:38:00 +05309250 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309251 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9252 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009253 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309254 hddLog(LOGE,
9255 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309256 ret = -EINVAL;
9257 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009258 }
9259
9260#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309261 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9262 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
9263 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309264 hddLog(LOGE,
9265 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309266 ret = -EINVAL;
9267 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009268 }
9269#endif
9270
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309271 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9272 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009273 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309274 hddLog(LOGE,
9275 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309276 ret = -EINVAL;
9277 goto done;
9278 }
9279
9280 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
9281 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009282 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07009283 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009284
9285 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9286 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
9287 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
9288 {
9289 hddLog(LOGE,
9290 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009291 ret = -EINVAL;
9292 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009293 }
9294
9295 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9296 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
9297 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9298 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9299 ==eHAL_STATUS_FAILURE)
9300 {
9301 hddLog(LOGE,
9302 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009303 ret = -EINVAL;
9304 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009305 }
9306
9307 // Added for ProResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +05309308 if ((pBeacon->proberesp_ies != NULL) && (pBeacon->proberesp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009309 {
Kapil Gupta137ef892016-12-13 19:38:00 +05309310 u16 rem_probe_resp_ie_len = pBeacon->proberesp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009311 u8 probe_rsp_ie_len[3] = {0};
9312 u8 counter = 0;
9313 /* Check Probe Resp Length if it is greater then 255 then Store
9314 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
9315 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
9316 Store More then 255 bytes into One Variable.
9317 */
9318 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
9319 {
9320 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
9321 {
9322 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
9323 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
9324 }
9325 else
9326 {
9327 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
9328 rem_probe_resp_ie_len = 0;
9329 }
9330 }
9331
9332 rem_probe_resp_ie_len = 0;
9333
9334 if (probe_rsp_ie_len[0] > 0)
9335 {
9336 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9337 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
Kapil Gupta137ef892016-12-13 19:38:00 +05309338 (tANI_U8*)&pBeacon->
9339 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07009340 probe_rsp_ie_len[0], NULL,
9341 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9342 {
9343 hddLog(LOGE,
9344 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009345 ret = -EINVAL;
9346 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009347 }
9348 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
9349 }
9350
9351 if (probe_rsp_ie_len[1] > 0)
9352 {
9353 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9354 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
Kapil Gupta137ef892016-12-13 19:38:00 +05309355 (tANI_U8*)&pBeacon->
9356 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07009357 probe_rsp_ie_len[1], NULL,
9358 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9359 {
9360 hddLog(LOGE,
9361 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009362 ret = -EINVAL;
9363 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009364 }
9365 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
9366 }
9367
9368 if (probe_rsp_ie_len[2] > 0)
9369 {
9370 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9371 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
Kapil Gupta137ef892016-12-13 19:38:00 +05309372 (tANI_U8*)&pBeacon->
9373 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07009374 probe_rsp_ie_len[2], NULL,
9375 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9376 {
9377 hddLog(LOGE,
9378 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009379 ret = -EINVAL;
9380 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009381 }
9382 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
9383 }
9384
9385 if (probe_rsp_ie_len[1] == 0 )
9386 {
9387 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9388 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
9389 eANI_BOOLEAN_FALSE) )
9390 {
9391 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009392 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009393 }
9394 }
9395
9396 if (probe_rsp_ie_len[2] == 0 )
9397 {
9398 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9399 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
9400 eANI_BOOLEAN_FALSE) )
9401 {
9402 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009403 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009404 }
9405 }
9406
9407 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9408 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
9409 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9410 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9411 == eHAL_STATUS_FAILURE)
9412 {
9413 hddLog(LOGE,
9414 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009415 ret = -EINVAL;
9416 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009417 }
9418 }
9419 else
9420 {
9421 // Reset WNI_CFG_PROBE_RSP Flags
9422 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
9423
9424 hddLog(VOS_TRACE_LEVEL_INFO,
9425 "%s: No Probe Response IE received in set beacon",
9426 __func__);
9427 }
9428
9429 // Added for AssocResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +05309430 if ((pBeacon->assocresp_ies != NULL) && (pBeacon->assocresp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009431 {
9432 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
Kapil Gupta137ef892016-12-13 19:38:00 +05309433 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)pBeacon->assocresp_ies,
9434 pBeacon->assocresp_ies_len, NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -07009435 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9436 {
9437 hddLog(LOGE,
9438 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009439 ret = -EINVAL;
9440 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009441 }
9442
9443 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9444 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
9445 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9446 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9447 == eHAL_STATUS_FAILURE)
9448 {
9449 hddLog(LOGE,
9450 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009451 ret = -EINVAL;
9452 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009453 }
9454 }
9455 else
9456 {
9457 hddLog(VOS_TRACE_LEVEL_INFO,
9458 "%s: No Assoc Response IE received in set beacon",
9459 __func__);
9460
9461 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9462 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
9463 eANI_BOOLEAN_FALSE) )
9464 {
9465 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009466 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009467 }
9468 }
9469
Jeff Johnsone7245742012-09-05 17:12:55 -07009470done:
Jeff Johnson295189b2012-06-20 16:38:30 -07009471 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309472 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009473}
Jeff Johnson295189b2012-06-20 16:38:30 -07009474
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309475/*
Jeff Johnson295189b2012-06-20 16:38:30 -07009476 * FUNCTION: wlan_hdd_validate_operation_channel
9477 * called by wlan_hdd_cfg80211_start_bss() and
9478 * wlan_hdd_cfg80211_set_channel()
9479 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309480 * channel list.
9481 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07009482VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07009483{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309484
Jeff Johnson295189b2012-06-20 16:38:30 -07009485 v_U32_t num_ch = 0;
9486 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
9487 u32 indx = 0;
9488 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309489 v_U8_t fValidChannel = FALSE, count = 0;
9490 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309491
Jeff Johnson295189b2012-06-20 16:38:30 -07009492 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
9493
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309494 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07009495 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309496 /* Validate the channel */
9497 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07009498 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309499 if ( channel == rfChannels[count].channelNum )
9500 {
9501 fValidChannel = TRUE;
9502 break;
9503 }
9504 }
9505 if (fValidChannel != TRUE)
9506 {
9507 hddLog(VOS_TRACE_LEVEL_ERROR,
9508 "%s: Invalid Channel [%d]", __func__, channel);
9509 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009510 }
9511 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309512 else
Jeff Johnson295189b2012-06-20 16:38:30 -07009513 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309514 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
9515 valid_ch, &num_ch))
9516 {
9517 hddLog(VOS_TRACE_LEVEL_ERROR,
9518 "%s: failed to get valid channel list", __func__);
9519 return VOS_STATUS_E_FAILURE;
9520 }
9521 for (indx = 0; indx < num_ch; indx++)
9522 {
9523 if (channel == valid_ch[indx])
9524 {
9525 break;
9526 }
9527 }
9528
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05309529 if (indx >= num_ch)
9530 {
9531 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
9532 {
9533 eCsrBand band;
9534 unsigned int freq;
9535
9536 sme_GetFreqBand(hHal, &band);
9537
9538 if (eCSR_BAND_5G == band)
9539 {
9540#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
9541 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
9542 {
9543 freq = ieee80211_channel_to_frequency(channel,
9544 IEEE80211_BAND_2GHZ);
9545 }
9546 else
9547 {
9548 freq = ieee80211_channel_to_frequency(channel,
9549 IEEE80211_BAND_5GHZ);
9550 }
9551#else
9552 freq = ieee80211_channel_to_frequency(channel);
9553#endif
9554 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
9555 return VOS_STATUS_SUCCESS;
9556 }
9557 }
9558
9559 hddLog(VOS_TRACE_LEVEL_ERROR,
9560 "%s: Invalid Channel [%d]", __func__, channel);
9561 return VOS_STATUS_E_FAILURE;
9562 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009563 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05309564
Jeff Johnson295189b2012-06-20 16:38:30 -07009565 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309566
Jeff Johnson295189b2012-06-20 16:38:30 -07009567}
9568
Viral Modi3a32cc52013-02-08 11:14:52 -08009569/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309570 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08009571 * This function is used to set the channel number
9572 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309573static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08009574 struct ieee80211_channel *chan,
9575 enum nl80211_channel_type channel_type
9576 )
9577{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309578 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08009579 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07009580 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08009581 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309582 hdd_context_t *pHddCtx;
9583 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009584
9585 ENTER();
9586
9587 if( NULL == dev )
9588 {
9589 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009590 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08009591 return -ENODEV;
9592 }
9593 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309594
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309595 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9596 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
9597 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08009598 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309599 "%s: device_mode = %s (%d) freq = %d", __func__,
9600 hdd_device_modetoString(pAdapter->device_mode),
9601 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309602
9603 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9604 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309605 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08009606 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309607 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009608 }
9609
9610 /*
9611 * Do freq to chan conversion
9612 * TODO: for 11a
9613 */
9614
9615 channel = ieee80211_frequency_to_channel(freq);
9616
9617 /* Check freq range */
9618 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
9619 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
9620 {
9621 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009622 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08009623 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
9624 WNI_CFG_CURRENT_CHANNEL_STAMAX);
9625 return -EINVAL;
9626 }
9627
9628 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
9629
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05309630 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
9631 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08009632 {
9633 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
9634 {
9635 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009636 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08009637 return -EINVAL;
9638 }
9639 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
9640 "%s: set channel to [%d] for device mode =%d",
9641 __func__, channel,pAdapter->device_mode);
9642 }
9643 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08009644 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08009645 )
9646 {
9647 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9648 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
9649 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9650
9651 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
9652 {
9653 /* Link is up then return cant set channel*/
9654 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009655 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08009656 return -EINVAL;
9657 }
9658
9659 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
9660 pHddStaCtx->conn_info.operationChannel = channel;
9661 pRoamProfile->ChannelInfo.ChannelList =
9662 &pHddStaCtx->conn_info.operationChannel;
9663 }
9664 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08009665 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08009666 )
9667 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309668 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
9669 {
9670 if(VOS_STATUS_SUCCESS !=
9671 wlan_hdd_validate_operation_channel(pAdapter,channel))
9672 {
9673 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009674 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309675 return -EINVAL;
9676 }
9677 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
9678 }
9679 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08009680 {
9681 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
9682
9683 /* If auto channel selection is configured as enable/ 1 then ignore
9684 channel set by supplicant
9685 */
9686 if ( cfg_param->apAutoChannelSelection )
9687 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309688 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
9689 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08009690 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309691 "%s: set channel to auto channel (0) for device mode =%s (%d)",
9692 __func__, hdd_device_modetoString(pAdapter->device_mode),
9693 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08009694 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309695 else
9696 {
9697 if(VOS_STATUS_SUCCESS !=
9698 wlan_hdd_validate_operation_channel(pAdapter,channel))
9699 {
9700 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009701 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309702 return -EINVAL;
9703 }
9704 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
9705 }
Viral Modi3a32cc52013-02-08 11:14:52 -08009706 }
9707 }
9708 else
9709 {
9710 hddLog(VOS_TRACE_LEVEL_FATAL,
9711 "%s: Invalid device mode failed to set valid channel", __func__);
9712 return -EINVAL;
9713 }
9714 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309715 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009716}
9717
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309718static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
9719 struct net_device *dev,
9720 struct ieee80211_channel *chan,
9721 enum nl80211_channel_type channel_type
9722 )
9723{
9724 int ret;
9725
9726 vos_ssr_protect(__func__);
9727 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
9728 vos_ssr_unprotect(__func__);
9729
9730 return ret;
9731}
9732
Anurag Chouhan83026002016-12-13 22:46:21 +05309733#ifdef DHCP_SERVER_OFFLOAD
9734void hdd_dhcp_server_offload_done(void *fw_dhcp_srv_offload_cb_context,
9735 VOS_STATUS status)
9736{
9737 hdd_adapter_t* adapter = (hdd_adapter_t*)fw_dhcp_srv_offload_cb_context;
9738
9739 ENTER();
9740
9741 if (NULL == adapter)
9742 {
9743 hddLog(VOS_TRACE_LEVEL_ERROR,
9744 "%s: adapter is NULL",__func__);
9745 return;
9746 }
9747
9748 adapter->dhcp_status.dhcp_offload_status = status;
9749 vos_event_set(&adapter->dhcp_status.vos_event);
9750 return;
9751}
9752
9753/**
9754 * wlan_hdd_set_dhcp_server_offload() - set dhcp server offload
9755 * @hostapd_adapter: pointer to hostapd adapter.
Anurag Chouhan638f5e22017-03-06 12:28:43 +05309756 * @re_init: flag set if api called post ssr
Anurag Chouhan83026002016-12-13 22:46:21 +05309757 *
9758 * Return: None
9759 */
Anurag Chouhan638f5e22017-03-06 12:28:43 +05309760VOS_STATUS wlan_hdd_set_dhcp_server_offload(hdd_adapter_t *hostapd_adapter,
9761 bool re_init)
Anurag Chouhan83026002016-12-13 22:46:21 +05309762{
9763 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter);
9764 sir_dhcp_srv_offload_info dhcp_srv_info;
9765 tANI_U8 num_entries = 0;
9766 tANI_U8 srv_ip[IPADDR_NUM_ENTRIES];
9767 tANI_U8 num;
9768 tANI_U32 temp;
9769 VOS_STATUS ret;
9770
9771 ENTER();
9772
Anurag Chouhan638f5e22017-03-06 12:28:43 +05309773 if (!re_init) {
9774 ret = wlan_hdd_validate_context(hdd_ctx);
9775 if (0 != ret)
9776 return VOS_STATUS_E_INVAL;
9777 }
Anurag Chouhan83026002016-12-13 22:46:21 +05309778
9779 /* Prepare the request to send to SME */
9780 dhcp_srv_info = vos_mem_malloc(sizeof(*dhcp_srv_info));
9781 if (NULL == dhcp_srv_info) {
9782 hddLog(VOS_TRACE_LEVEL_ERROR,
9783 "%s: could not allocate tDhcpSrvOffloadInfo!", __func__);
9784 return VOS_STATUS_E_NOMEM;
9785 }
9786
9787 vos_mem_zero(dhcp_srv_info, sizeof(*dhcp_srv_info));
9788
9789 dhcp_srv_info->bssidx = hostapd_adapter->sessionId;
9790 dhcp_srv_info->dhcp_srv_offload_enabled = TRUE;
9791 dhcp_srv_info->dhcp_client_num = hdd_ctx->cfg_ini->dhcp_max_num_clients;
9792 dhcp_srv_info->start_lsb = hdd_ctx->cfg_ini->dhcp_start_lsb;
9793 dhcp_srv_info->dhcp_offload_callback = hdd_dhcp_server_offload_done;
9794 dhcp_srv_info->dhcp_server_offload_cb_context = hostapd_adapter;
9795
9796 hdd_string_to_u8_array(hdd_ctx->cfg_ini->dhcp_srv_ip,
9797 srv_ip,
9798 &num_entries,
Anurag Chouhanac145c22016-11-22 16:51:47 +05309799 IPADDR_NUM_ENTRIES, ".");
Anurag Chouhan83026002016-12-13 22:46:21 +05309800 if (num_entries != IPADDR_NUM_ENTRIES) {
9801 hddLog(VOS_TRACE_LEVEL_ERROR,
9802 "%s: incorrect IP address (%s) assigned for DHCP server!",
9803 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
9804 vos_mem_free(dhcp_srv_info);
9805 return VOS_STATUS_E_FAILURE;
9806 }
9807
9808 if ((srv_ip[0] >= 224) && (srv_ip[0] <= 239)) {
9809 hddLog(VOS_TRACE_LEVEL_ERROR,
9810 "%s: invalid IP address (%s)! It could NOT be multicast IP address!",
9811 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
9812 vos_mem_free(dhcp_srv_info);
9813 return VOS_STATUS_E_FAILURE;
9814 }
9815
9816 if (srv_ip[IPADDR_NUM_ENTRIES-1] >= DHCP_START_POOL_ADDRESS) {
9817 hddLog(VOS_TRACE_LEVEL_ERROR,
9818 "%s: invalid IP address (%s)! The last field must be less than 100!",
9819 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
9820 vos_mem_free(dhcp_srv_info);
9821 return VOS_STATUS_E_FAILURE;
9822 }
9823
9824 for (num = 0; num < num_entries; num++) {
9825 temp = srv_ip[num];
9826 dhcp_srv_info->dhcp_srv_ip |= (temp << (8 * num));
9827 }
9828
9829 if (eHAL_STATUS_SUCCESS !=
9830 sme_set_dhcp_srv_offload(hdd_ctx->hHal, dhcp_srv_info)) {
9831 hddLog(VOS_TRACE_LEVEL_ERROR,
9832 "%s: sme_set_dhcp_srv_offload fail!", __func__);
9833 vos_mem_free(dhcp_srv_info);
9834 return VOS_STATUS_E_FAILURE;
9835 }
9836
9837 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
9838 "%s: enable DHCP Server offload successfully!", __func__);
9839
9840 vos_mem_free(dhcp_srv_info);
9841 return 0;
9842}
9843#endif /* DHCP_SERVER_OFFLOAD */
9844
Jeff Johnson295189b2012-06-20 16:38:30 -07009845#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9846static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
9847 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009848#else
9849static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
9850 struct cfg80211_beacon_data *params,
9851 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309852 enum nl80211_hidden_ssid hidden_ssid,
9853 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009854#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009855{
9856 tsap_Config_t *pConfig;
9857 beacon_data_t *pBeacon = NULL;
9858 struct ieee80211_mgmt *pMgmt_frame;
9859 v_U8_t *pIe=NULL;
9860 v_U16_t capab_info;
9861 eCsrAuthType RSNAuthType;
9862 eCsrEncryptionType RSNEncryptType;
9863 eCsrEncryptionType mcRSNEncryptType;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +05309864 int status = VOS_STATUS_SUCCESS, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009865 tpWLAN_SAPEventCB pSapEventCallback;
9866 hdd_hostapd_state_t *pHostapdState;
Jeff Johnson295189b2012-06-20 16:38:30 -07009867 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309868 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009869 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309870 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07009871 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08009872 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05309873 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07009874 v_BOOL_t MFPCapable = VOS_FALSE;
9875 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309876 v_BOOL_t sapEnable11AC =
9877 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Kapil Gupta137ef892016-12-13 19:38:00 +05309878 u_int16_t prev_rsn_length = 0;
9879
Jeff Johnson295189b2012-06-20 16:38:30 -07009880 ENTER();
9881
Nitesh Shah9b066282017-06-06 18:05:52 +05309882 wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309883 iniConfig = pHddCtx->cfg_ini;
9884
Jeff Johnson295189b2012-06-20 16:38:30 -07009885 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
9886
9887 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9888
9889 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9890
9891 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9892
9893 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
9894
9895 //channel is already set in the set_channel Call back
9896 //pConfig->channel = pCommitConfig->channel;
9897
9898 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309899 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07009900 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
9901
9902 pConfig->dtim_period = pBeacon->dtim_period;
9903
Arif Hussain6d2a3322013-11-17 19:50:10 -08009904 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07009905 pConfig->dtim_period);
9906
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08009907 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07009908 {
9909 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07009910 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05309911 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
9912 {
9913 tANI_BOOLEAN restartNeeded;
9914 pConfig->ieee80211d = 1;
9915 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
9916 sme_setRegInfo(hHal, pConfig->countryCode);
9917 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
9918 }
9919 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009920 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07009921 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07009922 pConfig->ieee80211d = 1;
9923 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
9924 sme_setRegInfo(hHal, pConfig->countryCode);
9925 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07009926 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07009927 else
9928 {
9929 pConfig->ieee80211d = 0;
9930 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309931 /*
9932 * If auto channel is configured i.e. channel is 0,
9933 * so skip channel validation.
9934 */
9935 if( AUTO_CHANNEL_SELECT != pConfig->channel )
9936 {
9937 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
9938 {
9939 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009940 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309941 return -EINVAL;
9942 }
9943 }
9944 else
9945 {
9946 if(1 != pHddCtx->is_dynamic_channel_range_set)
9947 {
9948 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
9949 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
9950 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
9951 }
9952 pHddCtx->is_dynamic_channel_range_set = 0;
9953 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009954 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07009955 else
Jeff Johnson295189b2012-06-20 16:38:30 -07009956 {
9957 pConfig->ieee80211d = 0;
9958 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309959
9960#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9961 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
9962 pConfig->authType = eSAP_OPEN_SYSTEM;
9963 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
9964 pConfig->authType = eSAP_SHARED_KEY;
9965 else
9966 pConfig->authType = eSAP_AUTO_SWITCH;
9967#else
9968 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
9969 pConfig->authType = eSAP_OPEN_SYSTEM;
9970 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
9971 pConfig->authType = eSAP_SHARED_KEY;
9972 else
9973 pConfig->authType = eSAP_AUTO_SWITCH;
9974#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009975
9976 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309977
9978 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07009979 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
Agrawal Ashisha8e8a722016-10-18 19:07:45 +05309980#ifdef SAP_AUTH_OFFLOAD
9981 /* In case of sap offload, hostapd.conf is configuted with open mode and
9982 * security is configured from ini file. Due to open mode in hostapd.conf
9983 * privacy bit is set to false which will result in not sending,
9984 * data packets as encrypted.
9985 * If enable_sap_auth_offload is enabled in ini and
9986 * sap_auth_offload_sec_type is type of WPA2-PSK,
9987 * driver will set privacy bit to 1.
9988 */
9989 if (pHddCtx->cfg_ini->enable_sap_auth_offload &&
9990 pHddCtx->cfg_ini->sap_auth_offload_sec_type)
9991 pConfig->privacy = VOS_TRUE;
9992#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009993
9994 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
9995
9996 /*Set wps station to configured*/
9997 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
9998
9999 if(pIe)
10000 {
10001 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
10002 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010003 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -070010004 return -EINVAL;
10005 }
10006 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
10007 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -070010008 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -070010009 /* Check 15 bit of WPS IE as it contain information for wps state
10010 * WPS state
10011 */
10012 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
10013 {
10014 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
10015 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
10016 {
10017 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
10018 }
10019 }
10020 }
10021 else
10022 {
10023 pConfig->wps_state = SAP_WPS_DISABLED;
10024 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010025 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -070010026
c_hpothufe599e92014-06-16 11:38:55 +053010027 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
10028 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
10029 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
10030 eCSR_ENCRYPT_TYPE_NONE;
10031
Jeff Johnson295189b2012-06-20 16:38:30 -070010032 pConfig->RSNWPAReqIELength = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +053010033 memset(&pConfig->RSNWPAReqIE[0], 0, sizeof(pConfig->RSNWPAReqIE));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010034 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070010035 WLAN_EID_RSN);
10036 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010037 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010038 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053010039 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
10040 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
10041 pConfig->RSNWPAReqIELength);
10042 else
10043 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
10044 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010045 /* The actual processing may eventually be more extensive than
10046 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -070010047 * by the app.
10048 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010049 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070010050 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
10051 &RSNEncryptType,
10052 &mcRSNEncryptType,
10053 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080010054 &MFPCapable,
10055 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053010056 pConfig->RSNWPAReqIE[1]+2,
10057 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010058
10059 if( VOS_STATUS_SUCCESS == status )
10060 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010061 /* Now copy over all the security attributes you have
10062 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070010063 * */
10064 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
10065 pConfig->mcRSNEncryptType = mcRSNEncryptType;
10066 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
10067 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010068 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080010069 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070010070 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
10071 }
10072 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010073
Jeff Johnson295189b2012-06-20 16:38:30 -070010074 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
10075 pBeacon->tail, pBeacon->tail_len);
10076
10077 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
10078 {
Kapil Gupta137ef892016-12-13 19:38:00 +053010079 if (pConfig->RSNWPAReqIE[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070010080 {
10081 /*Mixed mode WPA/WPA2*/
Kapil Gupta137ef892016-12-13 19:38:00 +053010082 prev_rsn_length = pConfig->RSNWPAReqIELength;
Jeff Johnson295189b2012-06-20 16:38:30 -070010083 pConfig->RSNWPAReqIELength += pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053010084 if (pConfig->RSNWPAReqIELength <=
10085 (sizeof(pConfig->RSNWPAReqIE) - prev_rsn_length))
10086 memcpy(&pConfig->RSNWPAReqIE[0] + prev_rsn_length, pIe,
10087 pIe[1] + 2);
10088 else
10089 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
10090 pConfig->RSNWPAReqIELength);
10091
Jeff Johnson295189b2012-06-20 16:38:30 -070010092 }
10093 else
10094 {
10095 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053010096 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
10097 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
10098 pConfig->RSNWPAReqIELength);
10099 else
10100 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
10101 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010102 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070010103 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
10104 &RSNEncryptType,
10105 &mcRSNEncryptType,
10106 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080010107 &MFPCapable,
10108 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053010109 pConfig->RSNWPAReqIE[1]+2,
10110 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010111
10112 if( VOS_STATUS_SUCCESS == status )
10113 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010114 /* Now copy over all the security attributes you have
10115 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070010116 * */
10117 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
10118 pConfig->mcRSNEncryptType = mcRSNEncryptType;
10119 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
10120 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010121 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080010122 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070010123 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
10124 }
10125 }
10126 }
10127
Kapil Gupta137ef892016-12-13 19:38:00 +053010128 if (pConfig->RSNWPAReqIELength > sizeof(pConfig->RSNWPAReqIE)) {
Jeff Johnson4416a782013-03-25 14:17:50 -070010129 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
10130 return -EINVAL;
10131 }
10132
Jeff Johnson295189b2012-06-20 16:38:30 -070010133 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
10134
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010135#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010136 if (params->ssid != NULL)
10137 {
10138 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
10139 pConfig->SSIDinfo.ssid.length = params->ssid_len;
10140 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
10141 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
10142 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010143#else
10144 if (ssid != NULL)
10145 {
10146 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
10147 pConfig->SSIDinfo.ssid.length = ssid_len;
10148 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
10149 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
10150 }
10151#endif
10152
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010153 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -070010154 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010155
Jeff Johnson295189b2012-06-20 16:38:30 -070010156 /* default value */
10157 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
10158 pConfig->num_accept_mac = 0;
10159 pConfig->num_deny_mac = 0;
10160
10161 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
10162 pBeacon->tail, pBeacon->tail_len);
10163
10164 /* pIe for black list is following form:
10165 type : 1 byte
10166 length : 1 byte
10167 OUI : 4 bytes
10168 acl type : 1 byte
10169 no of mac addr in black list: 1 byte
10170 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010171 */
10172 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010173 {
10174 pConfig->SapMacaddr_acl = pIe[6];
10175 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080010176 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010177 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053010178 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
10179 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010180 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
10181 for (i = 0; i < pConfig->num_deny_mac; i++)
10182 {
10183 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
10184 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010185 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010186 }
10187 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
10188 pBeacon->tail, pBeacon->tail_len);
10189
10190 /* pIe for white list is following form:
10191 type : 1 byte
10192 length : 1 byte
10193 OUI : 4 bytes
10194 acl type : 1 byte
10195 no of mac addr in white list: 1 byte
10196 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010197 */
10198 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010199 {
10200 pConfig->SapMacaddr_acl = pIe[6];
10201 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080010202 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010203 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053010204 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
10205 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010206 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
10207 for (i = 0; i < pConfig->num_accept_mac; i++)
10208 {
10209 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
10210 acl_entry++;
10211 }
10212 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053010213
Jeff Johnson295189b2012-06-20 16:38:30 -070010214 wlan_hdd_set_sapHwmode(pHostapdAdapter);
10215
Jeff Johnsone7245742012-09-05 17:12:55 -070010216#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080010217 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +053010218 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
10219 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +053010220 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
10221 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080010222 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
10223 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +053010224 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
10225 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -070010226 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053010227 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -070010228 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +053010229 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070010230
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010231 /* If ACS disable and selected channel <= 14
10232 * OR
10233 * ACS enabled and ACS operating band is choosen as 2.4
10234 * AND
10235 * VHT in 2.4G Disabled
10236 * THEN
10237 * Fallback to 11N mode
10238 */
10239 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
10240 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +053010241 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010242 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -070010243 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053010244 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
10245 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070010246 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
10247 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010248 }
10249#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010250
Jeff Johnson295189b2012-06-20 16:38:30 -070010251 // ht_capab is not what the name conveys,this is used for protection bitmap
10252 pConfig->ht_capab =
10253 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
10254
Kapil Gupta137ef892016-12-13 19:38:00 +053010255 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -070010256 {
10257 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
10258 return -EINVAL;
10259 }
10260
10261 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010262 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -070010263 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
10264 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010265 pConfig->obssProtEnabled =
10266 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -070010267
Chet Lanctot8cecea22014-02-11 19:09:36 -080010268#ifdef WLAN_FEATURE_11W
10269 pConfig->mfpCapable = MFPCapable;
10270 pConfig->mfpRequired = MFPRequired;
10271 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
10272 pConfig->mfpCapable, pConfig->mfpRequired);
10273#endif
10274
Arif Hussain6d2a3322013-11-17 19:50:10 -080010275 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -070010276 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -080010277 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
10278 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
10279 (int)pConfig->channel);
10280 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
10281 pConfig->SapHw_mode, pConfig->privacy,
10282 pConfig->authType);
10283 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
10284 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
10285 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
10286 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -070010287
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010288 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -070010289 {
10290 //Bss already started. just return.
10291 //TODO Probably it should update some beacon params.
10292 hddLog( LOGE, "Bss Already started...Ignore the request");
10293 EXIT();
10294 return 0;
10295 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010296
Agarwal Ashish51325b52014-06-16 16:50:49 +053010297 if (vos_max_concurrent_connections_reached()) {
10298 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10299 return -EINVAL;
10300 }
10301
Jeff Johnson295189b2012-06-20 16:38:30 -070010302 pConfig->persona = pHostapdAdapter->device_mode;
10303
Peng Xu2446a892014-09-05 17:21:18 +053010304 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
10305 if ( NULL != psmeConfig)
10306 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053010307 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +053010308 sme_GetConfigParam(hHal, psmeConfig);
10309 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053010310#ifdef WLAN_FEATURE_AP_HT40_24G
10311 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
10312 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
10313 && pHddCtx->cfg_ini->apHT40_24GEnabled)
10314 {
10315 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
10316 sme_UpdateConfig (hHal, psmeConfig);
10317 }
10318#endif
Peng Xu2446a892014-09-05 17:21:18 +053010319 vos_mem_free(psmeConfig);
10320 }
Peng Xuafc34e32014-09-25 13:23:55 +053010321 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +053010322
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010323 set_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
10324
Jeff Johnson295189b2012-06-20 16:38:30 -070010325 pSapEventCallback = hdd_hostapd_SAPEventCB;
10326 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
10327 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
10328 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010329 hddLog(LOGE,FL("SAP Start Bss fail"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010330 ret = -EINVAL;
10331 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070010332 }
10333
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010334 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -070010335 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
10336
10337 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010338
Jeff Johnson295189b2012-06-20 16:38:30 -070010339 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010340 {
10341 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010342 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -070010343 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070010344 VOS_ASSERT(0);
10345 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010346
Jeff Johnson295189b2012-06-20 16:38:30 -070010347 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053010348 if (WLANSAP_get_sessionId(pVosContext, &pHostapdAdapter->sessionId) !=
10349 VOS_STATUS_SUCCESS)
10350 {
10351 hddLog(LOGE,FL("Fail to get Softap sessionID"));
10352 VOS_ASSERT(0);
10353 }
Kaushik, Sushantf6070802014-10-15 15:09:23 +053010354 /* Initialize WMM configuation */
10355 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010356 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010357
Anurag Chouhan83026002016-12-13 22:46:21 +053010358#ifdef DHCP_SERVER_OFFLOAD
10359 /* set dhcp server offload */
10360 if (iniConfig->enable_dhcp_srv_offload &&
10361 sme_IsFeatureSupportedByFW(SAP_OFFLOADS)) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010362 vos_event_reset(&pHostapdAdapter->dhcp_status.vos_event);
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010363 status = wlan_hdd_set_dhcp_server_offload(pHostapdAdapter, false);
Anurag Chouhan83026002016-12-13 22:46:21 +053010364 if (!VOS_IS_STATUS_SUCCESS(status))
10365 {
10366 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10367 ("HDD DHCP Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010368 vos_event_reset(&pHostapdState->vosEvent);
10369 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
10370 status = vos_wait_single_event(&pHostapdState->vosEvent,
10371 10000);
10372 if (!VOS_IS_STATUS_SUCCESS(status)) {
10373 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010374 ret = -EINVAL;
10375 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010376 }
10377 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010378 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010379 status = vos_wait_single_event(&pHostapdAdapter->dhcp_status.vos_event, 2000);
10380 if (!VOS_IS_STATUS_SUCCESS(status) || pHostapdAdapter->dhcp_status.dhcp_offload_status)
10381 {
10382 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10383 ("ERROR: DHCP HDD vos wait for single_event failed!! %d"),
10384 pHostapdAdapter->dhcp_status.dhcp_offload_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010385 vos_event_reset(&pHostapdState->vosEvent);
10386 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
10387 status = vos_wait_single_event(&pHostapdState->vosEvent,
10388 10000);
10389 if (!VOS_IS_STATUS_SUCCESS(status)) {
10390 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010391 ret = -EINVAL;
10392 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010393 }
10394 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010395 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010396#ifdef MDNS_OFFLOAD
10397 if (iniConfig->enable_mdns_offload) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010398 vos_event_reset(&pHostapdAdapter->mdns_status.vos_event);
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010399 status = wlan_hdd_set_mdns_offload(pHostapdAdapter);
10400 if (VOS_IS_STATUS_SUCCESS(status))
10401 {
10402 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10403 ("HDD MDNS Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010404 vos_event_reset(&pHostapdState->vosEvent);
10405 if (VOS_STATUS_SUCCESS ==
10406 WLANSAP_StopBss(pHddCtx->pvosContext)) {
10407 status = vos_wait_single_event(&pHostapdState->vosEvent,
10408 10000);
10409 if (!VOS_IS_STATUS_SUCCESS(status)) {
10410 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010411 ret = -EINVAL;
10412 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010413 }
10414 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010415 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010416 status = vos_wait_single_event(&pHostapdAdapter->
10417 mdns_status.vos_event, 2000);
10418 if (!VOS_IS_STATUS_SUCCESS(status) ||
10419 pHostapdAdapter->mdns_status.mdns_enable_status ||
10420 pHostapdAdapter->mdns_status.mdns_fqdn_status ||
10421 pHostapdAdapter->mdns_status.mdns_resp_status)
10422 {
10423 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10424 ("MDNS HDD vos wait for single_event failed!! enable %d fqdn %d resp %d"),
10425 pHostapdAdapter->mdns_status.mdns_enable_status,
10426 pHostapdAdapter->mdns_status.mdns_fqdn_status,
10427 pHostapdAdapter->mdns_status.mdns_resp_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010428 vos_event_reset(&pHostapdState->vosEvent);
10429 if (VOS_STATUS_SUCCESS ==
10430 WLANSAP_StopBss(pHddCtx->pvosContext)) {
10431 status = vos_wait_single_event(&pHostapdState->vosEvent,
10432 10000);
10433 if (!VOS_IS_STATUS_SUCCESS(status)) {
10434 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010435 ret = -EINVAL;
10436 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010437 }
10438 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010439 }
10440 }
10441#endif /* MDNS_OFFLOAD */
10442 } else {
10443 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10444 ("DHCP Disabled ini %d, FW %d"),
10445 iniConfig->enable_dhcp_srv_offload,
10446 sme_IsFeatureSupportedByFW(SAP_OFFLOADS));
Anurag Chouhan83026002016-12-13 22:46:21 +053010447 }
10448#endif /* DHCP_SERVER_OFFLOAD */
10449
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010450#ifdef WLAN_FEATURE_P2P_DEBUG
10451 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
10452 {
10453 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
10454 {
10455 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
10456 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -080010457 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010458 }
10459 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
10460 {
10461 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
10462 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -080010463 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010464 }
10465 }
10466#endif
Ashish Kumar Dhanotiya42aa5152017-01-03 20:25:57 +053010467 /* Check and restart SAP if it is on Unsafe channel */
10468 hdd_check_for_unsafe_ch(pHostapdAdapter, pHddCtx);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010469
Jeff Johnson295189b2012-06-20 16:38:30 -070010470 pHostapdState->bCommit = TRUE;
10471 EXIT();
10472
10473 return 0;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010474error:
10475 clear_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
10476 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010477}
10478
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010479#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010480static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010481 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070010482 struct beacon_parameters *params)
10483{
10484 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010485 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010486 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010487
10488 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010489
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010490 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10491 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
10492 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010493 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
10494 hdd_device_modetoString(pAdapter->device_mode),
10495 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010496
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010497 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10498 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010499 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010500 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010501 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010502 }
10503
Agarwal Ashish51325b52014-06-16 16:50:49 +053010504 if (vos_max_concurrent_connections_reached()) {
10505 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10506 return -EINVAL;
10507 }
10508
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010509 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010510 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070010511 )
10512 {
10513 beacon_data_t *old,*new;
10514
10515 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010516
Jeff Johnson295189b2012-06-20 16:38:30 -070010517 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010518 {
10519 hddLog(VOS_TRACE_LEVEL_WARN,
10520 FL("already beacon info added to session(%d)"),
10521 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070010522 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010523 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010524
10525 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
10526
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010527 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -070010528 {
10529 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010530 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010531 return -EINVAL;
10532 }
10533
10534 pAdapter->sessionCtx.ap.beacon = new;
10535
10536 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
10537 }
10538
10539 EXIT();
10540 return status;
10541}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010542
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010543static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
10544 struct net_device *dev,
10545 struct beacon_parameters *params)
10546{
10547 int ret;
10548
10549 vos_ssr_protect(__func__);
10550 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
10551 vos_ssr_unprotect(__func__);
10552
10553 return ret;
10554}
10555
10556static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010557 struct net_device *dev,
10558 struct beacon_parameters *params)
10559{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010560 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010561 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10562 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010563 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010564
10565 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010566
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010567 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10568 TRACE_CODE_HDD_CFG80211_SET_BEACON,
10569 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
10570 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10571 __func__, hdd_device_modetoString(pAdapter->device_mode),
10572 pAdapter->device_mode);
10573
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010574 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10575 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010576 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010577 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010578 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010579 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010580
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010581 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010582 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010583 )
Jeff Johnson295189b2012-06-20 16:38:30 -070010584 {
10585 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010586
Jeff Johnson295189b2012-06-20 16:38:30 -070010587 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010588
Jeff Johnson295189b2012-06-20 16:38:30 -070010589 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010590 {
10591 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10592 FL("session(%d) old and new heads points to NULL"),
10593 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070010594 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010595 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010596
10597 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
10598
10599 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010600 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010601 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010602 return -EINVAL;
10603 }
10604
10605 pAdapter->sessionCtx.ap.beacon = new;
10606
10607 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
10608 }
10609
10610 EXIT();
10611 return status;
10612}
10613
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010614static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
10615 struct net_device *dev,
10616 struct beacon_parameters *params)
10617{
10618 int ret;
10619
10620 vos_ssr_protect(__func__);
10621 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
10622 vos_ssr_unprotect(__func__);
10623
10624 return ret;
10625}
10626
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010627#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10628
10629#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010630static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010631 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010632#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010633static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010634 struct net_device *dev)
10635#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010636{
10637 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -070010638 hdd_context_t *pHddCtx = NULL;
10639 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010640 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010641 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010642
10643 ENTER();
10644
10645 if (NULL == pAdapter)
10646 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010647 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010648 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010649 return -ENODEV;
10650 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010651
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010652 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10653 TRACE_CODE_HDD_CFG80211_STOP_AP,
10654 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010655 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10656 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010657 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010658 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010659 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -070010660 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010661
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010662 pScanInfo = &pHddCtx->scan_info;
10663
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010664 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10665 __func__, hdd_device_modetoString(pAdapter->device_mode),
10666 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010667
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010668 ret = wlan_hdd_scan_abort(pAdapter);
10669
Girish Gowli4bf7a632014-06-12 13:42:11 +053010670 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -070010671 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010672 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10673 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010674
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010675 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -070010676 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010677 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10678 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -080010679
Jeff Johnsone7245742012-09-05 17:12:55 -070010680 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010681 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -070010682 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010683 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070010684 }
10685
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010686 /* Delete all associated STAs before stopping AP/P2P GO */
10687 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +053010688 hdd_hostapd_stop(dev);
10689
Jeff Johnson295189b2012-06-20 16:38:30 -070010690 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010691 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070010692 )
10693 {
10694 beacon_data_t *old;
10695
10696 old = pAdapter->sessionCtx.ap.beacon;
10697
10698 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010699 {
10700 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10701 FL("session(%d) beacon data points to NULL"),
10702 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070010703 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010704 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010705
Jeff Johnson295189b2012-06-20 16:38:30 -070010706 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010707
10708 mutex_lock(&pHddCtx->sap_lock);
10709 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
10710 {
Jeff Johnson4416a782013-03-25 14:17:50 -070010711 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -070010712 {
10713 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
10714
10715 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
10716
10717 if (!VOS_IS_STATUS_SUCCESS(status))
10718 {
10719 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010720 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -070010721 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010722 }
10723 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010724 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010725 /* BSS stopped, clear the active sessions for this device mode */
10726 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010727 }
10728 mutex_unlock(&pHddCtx->sap_lock);
10729
10730 if(status != VOS_STATUS_SUCCESS)
10731 {
10732 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010733 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010734 return -EINVAL;
10735 }
10736
Jeff Johnson4416a782013-03-25 14:17:50 -070010737 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070010738 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
10739 ==eHAL_STATUS_FAILURE)
10740 {
10741 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010742 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010743 }
10744
Jeff Johnson4416a782013-03-25 14:17:50 -070010745 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070010746 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
10747 eANI_BOOLEAN_FALSE) )
10748 {
10749 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010750 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010751 }
10752
10753 // Reset WNI_CFG_PROBE_RSP Flags
10754 wlan_hdd_reset_prob_rspies(pAdapter);
10755
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010756 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
10757
Jeff Johnson295189b2012-06-20 16:38:30 -070010758 pAdapter->sessionCtx.ap.beacon = NULL;
10759 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010760#ifdef WLAN_FEATURE_P2P_DEBUG
10761 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
10762 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
10763 {
10764 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
10765 "GO got removed");
10766 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
10767 }
10768#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010769 }
10770 EXIT();
10771 return status;
10772}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010773
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010774#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10775static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
10776 struct net_device *dev)
10777{
10778 int ret;
10779
10780 vos_ssr_protect(__func__);
10781 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
10782 vos_ssr_unprotect(__func__);
10783
10784 return ret;
10785}
10786#else
10787static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
10788 struct net_device *dev)
10789{
10790 int ret;
10791
10792 vos_ssr_protect(__func__);
10793 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
10794 vos_ssr_unprotect(__func__);
10795
10796 return ret;
10797}
10798#endif
10799
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010800#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
10801
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010802static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010803 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010804 struct cfg80211_ap_settings *params)
10805{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010806 hdd_adapter_t *pAdapter;
10807 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010808 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010809
10810 ENTER();
10811
Girish Gowlib143d7a2015-02-18 19:39:55 +053010812 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010813 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010814 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +053010815 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010816 return -ENODEV;
10817 }
10818
10819 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
10820 if (NULL == pAdapter)
10821 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010822 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010823 "%s: HDD adapter is Null", __func__);
10824 return -ENODEV;
10825 }
10826
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010827 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10828 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
10829 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010830 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
10831 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010832 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010833 "%s: HDD adapter magic is invalid", __func__);
10834 return -ENODEV;
10835 }
10836
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010837 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
10838
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010839 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010840 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010841 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010842 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010843 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010844 }
10845
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010846 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
10847 __func__, hdd_device_modetoString(pAdapter->device_mode),
10848 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010849
10850 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010851 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010852 )
10853 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010854 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010855
10856 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010857
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010858 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010859 {
10860 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
10861 FL("already beacon info added to session(%d)"),
10862 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010863 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010864 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010865
Girish Gowlib143d7a2015-02-18 19:39:55 +053010866#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10867 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
10868 &new,
10869 &params->beacon);
10870#else
10871 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
10872 &new,
10873 &params->beacon,
10874 params->dtim_period);
10875#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010876
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010877 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010878 {
10879 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010880 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010881 return -EINVAL;
10882 }
10883 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -080010884#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -070010885 wlan_hdd_cfg80211_set_channel(wiphy, dev,
10886#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
10887 params->channel, params->channel_type);
10888#else
10889 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
10890#endif
Viral Modi3a32cc52013-02-08 11:14:52 -080010891#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010892 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010893 params->ssid_len, params->hidden_ssid,
10894 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010895 }
10896
10897 EXIT();
10898 return status;
10899}
10900
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010901static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
10902 struct net_device *dev,
10903 struct cfg80211_ap_settings *params)
10904{
10905 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010906
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010907 vos_ssr_protect(__func__);
10908 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
10909 vos_ssr_unprotect(__func__);
10910
10911 return ret;
10912}
10913
10914static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010915 struct net_device *dev,
10916 struct cfg80211_beacon_data *params)
10917{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010918 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010919 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010920 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010921
10922 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010923
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010924 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10925 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
10926 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -080010927 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010928 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010929
10930 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10931 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010932 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010933 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010934 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010935 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010936
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010937 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010938 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010939 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010940 {
10941 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010942
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010943 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010944
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010945 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010946 {
10947 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10948 FL("session(%d) beacon data points to NULL"),
10949 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010950 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010951 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010952
10953 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
10954
10955 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010956 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010957 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010958 return -EINVAL;
10959 }
10960
10961 pAdapter->sessionCtx.ap.beacon = new;
10962
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010963 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
10964 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010965 }
10966
10967 EXIT();
10968 return status;
10969}
10970
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010971static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
10972 struct net_device *dev,
10973 struct cfg80211_beacon_data *params)
10974{
10975 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010976
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010977 vos_ssr_protect(__func__);
10978 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
10979 vos_ssr_unprotect(__func__);
10980
10981 return ret;
10982}
10983
10984#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010985
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010986static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010987 struct net_device *dev,
10988 struct bss_parameters *params)
10989{
10990 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010991 hdd_context_t *pHddCtx;
10992 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010993
10994 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010995
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010996 if (NULL == pAdapter)
10997 {
10998 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10999 "%s: HDD adapter is Null", __func__);
11000 return -ENODEV;
11001 }
11002 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011003 ret = wlan_hdd_validate_context(pHddCtx);
11004 if (0 != ret)
11005 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011006 return ret;
11007 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011008 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11009 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
11010 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011011 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11012 __func__, hdd_device_modetoString(pAdapter->device_mode),
11013 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011014
11015 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011016 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011017 )
Jeff Johnson295189b2012-06-20 16:38:30 -070011018 {
11019 /* ap_isolate == -1 means that in change bss, upper layer doesn't
11020 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011021 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -070011022 {
11023 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011024 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011025 }
11026
11027 EXIT();
11028 return 0;
11029}
11030
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011031static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
11032 struct net_device *dev,
11033 struct bss_parameters *params)
11034{
11035 int ret;
11036
11037 vos_ssr_protect(__func__);
11038 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
11039 vos_ssr_unprotect(__func__);
11040
11041 return ret;
11042}
Kiet Lam10841362013-11-01 11:36:50 +053011043/* FUNCTION: wlan_hdd_change_country_code_cd
11044* to wait for contry code completion
11045*/
11046void* wlan_hdd_change_country_code_cb(void *pAdapter)
11047{
11048 hdd_adapter_t *call_back_pAdapter = pAdapter;
11049 complete(&call_back_pAdapter->change_country_code);
11050 return NULL;
11051}
11052
Jeff Johnson295189b2012-06-20 16:38:30 -070011053/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053011054 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -070011055 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
11056 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053011057int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011058 struct net_device *ndev,
11059 enum nl80211_iftype type,
11060 u32 *flags,
11061 struct vif_params *params
11062 )
11063{
11064 struct wireless_dev *wdev;
11065 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011066 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -070011067 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011068 tCsrRoamProfile *pRoamProfile = NULL;
11069 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011070 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011071 eMib_dot11DesiredBssType connectedBssType;
11072 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011073 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011074
11075 ENTER();
11076
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011077 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011078 {
11079 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11080 "%s: Adapter context is null", __func__);
11081 return VOS_STATUS_E_FAILURE;
11082 }
11083
11084 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11085 if (!pHddCtx)
11086 {
11087 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11088 "%s: HDD context is null", __func__);
11089 return VOS_STATUS_E_FAILURE;
11090 }
11091
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011092 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11093 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
11094 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011095 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011096 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011097 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011098 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011099 }
11100
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011101 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11102 __func__, hdd_device_modetoString(pAdapter->device_mode),
11103 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011104
Agarwal Ashish51325b52014-06-16 16:50:49 +053011105 if (vos_max_concurrent_connections_reached()) {
11106 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11107 return -EINVAL;
11108 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011109 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070011110 wdev = ndev->ieee80211_ptr;
11111
11112#ifdef WLAN_BTAMP_FEATURE
11113 if((NL80211_IFTYPE_P2P_CLIENT == type)||
11114 (NL80211_IFTYPE_ADHOC == type)||
11115 (NL80211_IFTYPE_AP == type)||
11116 (NL80211_IFTYPE_P2P_GO == type))
11117 {
11118 pHddCtx->isAmpAllowed = VOS_FALSE;
11119 // stop AMP traffic
11120 status = WLANBAP_StopAmp();
11121 if(VOS_STATUS_SUCCESS != status )
11122 {
11123 pHddCtx->isAmpAllowed = VOS_TRUE;
11124 hddLog(VOS_TRACE_LEVEL_FATAL,
11125 "%s: Failed to stop AMP", __func__);
11126 return -EINVAL;
11127 }
11128 }
11129#endif //WLAN_BTAMP_FEATURE
11130 /* Reset the current device mode bit mask*/
11131 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
11132
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +053011133 if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
11134 ((type == NL80211_IFTYPE_P2P_CLIENT) ||
11135 (type == NL80211_IFTYPE_P2P_GO)))
11136 {
11137 /* Notify Mode change in case of concurrency.
11138 * Below function invokes TDLS teardown Functionality Since TDLS is
11139 * not Supported in case of concurrency i.e Once P2P session
11140 * is detected disable offchannel and teardown TDLS links
11141 */
11142 hddLog(LOG1,
11143 FL("Device mode = %d Interface type = %d"),
11144 pAdapter->device_mode, type);
11145 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
11146 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +053011147
Jeff Johnson295189b2012-06-20 16:38:30 -070011148 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070011149 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -070011150 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -070011151 )
11152 {
11153 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011154 if (!pWextState)
11155 {
11156 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11157 "%s: pWextState is null", __func__);
11158 return VOS_STATUS_E_FAILURE;
11159 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011160 pRoamProfile = &pWextState->roamProfile;
11161 LastBSSType = pRoamProfile->BSSType;
11162
11163 switch (type)
11164 {
11165 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070011166 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070011167 hddLog(VOS_TRACE_LEVEL_INFO,
11168 "%s: setting interface Type to INFRASTRUCTURE", __func__);
11169 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -070011170#ifdef WLAN_FEATURE_11AC
11171 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
11172 {
11173 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
11174 }
11175#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011176 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -070011177 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011178 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080011179 //Check for sub-string p2p to confirm its a p2p interface
11180 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011181 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +053011182#ifdef FEATURE_WLAN_TDLS
11183 mutex_lock(&pHddCtx->tdls_lock);
11184 wlan_hdd_tdls_exit(pAdapter, TRUE);
11185 mutex_unlock(&pHddCtx->tdls_lock);
11186#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -080011187 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
11188 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
11189 }
11190 else
11191 {
11192 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070011193 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080011194 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011195 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +053011196
Jeff Johnson295189b2012-06-20 16:38:30 -070011197 case NL80211_IFTYPE_ADHOC:
11198 hddLog(VOS_TRACE_LEVEL_INFO,
11199 "%s: setting interface Type to ADHOC", __func__);
11200 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
11201 pRoamProfile->phyMode =
11202 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -070011203 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011204 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +053011205 hdd_set_ibss_ops( pAdapter );
11206 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +053011207
11208 status = hdd_sta_id_hash_attach(pAdapter);
11209 if (VOS_STATUS_SUCCESS != status) {
11210 hddLog(VOS_TRACE_LEVEL_ERROR,
11211 FL("Failed to initialize hash for IBSS"));
11212 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011213 break;
11214
11215 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070011216 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070011217 {
11218 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
11219 "%s: setting interface Type to %s", __func__,
11220 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
11221
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080011222 //Cancel any remain on channel for GO mode
11223 if (NL80211_IFTYPE_P2P_GO == type)
11224 {
11225 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
11226 }
Mohit Khanna0f232092012-09-11 14:46:08 -070011227 if (NL80211_IFTYPE_AP == type)
11228 {
11229 /* As Loading WLAN Driver one interface being created for p2p device
11230 * address. This will take one HW STA and the max number of clients
11231 * that can connect to softAP will be reduced by one. so while changing
11232 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
11233 * interface as it is not required in SoftAP mode.
11234 */
11235
11236 // Get P2P Adapter
11237 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
11238
11239 if (pP2pAdapter)
11240 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053011241 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +053011242 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -070011243 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
11244 }
11245 }
Swaroop Goltia2e32212014-04-09 23:37:33 +053011246 //Disable IMPS & BMPS for SAP/GO
11247 if(VOS_STATUS_E_FAILURE ==
11248 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
11249 {
11250 //Fail to Exit BMPS
11251 VOS_ASSERT(0);
11252 }
Deepthi Gowri500fc472014-08-11 19:53:10 +053011253
11254 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
11255
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011256#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -070011257
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011258 /* A Mutex Lock is introduced while changing the mode to
11259 * protect the concurrent access for the Adapters by TDLS
11260 * module.
11261 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011262 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011263#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011264 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +053011265 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011266 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -070011267 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
11268 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011269#ifdef FEATURE_WLAN_TDLS
11270 mutex_unlock(&pHddCtx->tdls_lock);
11271#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070011272 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
11273 (pConfig->apRandomBssidEnabled))
11274 {
11275 /* To meet Android requirements create a randomized
11276 MAC address of the form 02:1A:11:Fx:xx:xx */
11277 get_random_bytes(&ndev->dev_addr[3], 3);
11278 ndev->dev_addr[0] = 0x02;
11279 ndev->dev_addr[1] = 0x1A;
11280 ndev->dev_addr[2] = 0x11;
11281 ndev->dev_addr[3] |= 0xF0;
11282 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
11283 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -080011284 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
11285 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070011286 }
11287
Jeff Johnson295189b2012-06-20 16:38:30 -070011288 hdd_set_ap_ops( pAdapter->dev );
11289
Kiet Lam10841362013-11-01 11:36:50 +053011290 /* This is for only SAP mode where users can
11291 * control country through ini.
11292 * P2P GO follows station country code
11293 * acquired during the STA scanning. */
11294 if((NL80211_IFTYPE_AP == type) &&
11295 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
11296 {
11297 int status = 0;
11298 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
11299 "%s: setting country code from INI ", __func__);
11300 init_completion(&pAdapter->change_country_code);
11301 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
11302 (void *)(tSmeChangeCountryCallback)
11303 wlan_hdd_change_country_code_cb,
11304 pConfig->apCntryCode, pAdapter,
11305 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053011306 eSIR_FALSE,
11307 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +053011308 if (eHAL_STATUS_SUCCESS == status)
11309 {
11310 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011311 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +053011312 &pAdapter->change_country_code,
11313 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011314 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +053011315 {
11316 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011317 FL("SME Timed out while setting country code %ld"),
11318 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -080011319
11320 if (pHddCtx->isLogpInProgress)
11321 {
11322 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11323 "%s: LOGP in Progress. Ignore!!!", __func__);
11324 return -EAGAIN;
11325 }
Kiet Lam10841362013-11-01 11:36:50 +053011326 }
11327 }
11328 else
11329 {
11330 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011331 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +053011332 return -EINVAL;
11333 }
11334 }
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +053011335 status = hdd_init_ap_mode(pAdapter, false);
Jeff Johnson295189b2012-06-20 16:38:30 -070011336 if(status != VOS_STATUS_SUCCESS)
11337 {
11338 hddLog(VOS_TRACE_LEVEL_FATAL,
11339 "%s: Error initializing the ap mode", __func__);
11340 return -EINVAL;
11341 }
11342 hdd_set_conparam(1);
11343
Nirav Shah7e3c8132015-06-22 23:51:42 +053011344 status = hdd_sta_id_hash_attach(pAdapter);
11345 if (VOS_STATUS_SUCCESS != status)
11346 {
11347 hddLog(VOS_TRACE_LEVEL_ERROR,
11348 FL("Failed to initialize hash for AP"));
11349 return -EINVAL;
11350 }
11351
Jeff Johnson295189b2012-06-20 16:38:30 -070011352 /*interface type changed update in wiphy structure*/
11353 if(wdev)
11354 {
11355 wdev->iftype = type;
11356 pHddCtx->change_iface = type;
11357 }
11358 else
11359 {
11360 hddLog(VOS_TRACE_LEVEL_ERROR,
11361 "%s: ERROR !!!! Wireless dev is NULL", __func__);
11362 return -EINVAL;
11363 }
11364 goto done;
11365 }
11366
11367 default:
11368 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
11369 __func__);
11370 return -EOPNOTSUPP;
11371 }
11372 }
11373 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011374 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011375 )
11376 {
11377 switch(type)
11378 {
11379 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070011380 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070011381 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +053011382
11383 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011384#ifdef FEATURE_WLAN_TDLS
11385
11386 /* A Mutex Lock is introduced while changing the mode to
11387 * protect the concurrent access for the Adapters by TDLS
11388 * module.
11389 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011390 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011391#endif
c_hpothu002231a2015-02-05 14:58:51 +053011392 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011393 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080011394 //Check for sub-string p2p to confirm its a p2p interface
11395 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -080011396 {
11397 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
11398 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
11399 }
11400 else
11401 {
11402 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070011403 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080011404 }
Agrawal Ashishcfe83282016-09-29 13:03:45 +053011405
11406 /* set con_mode to STA only when no SAP concurrency mode */
11407 if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO)))
11408 hdd_set_conparam(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070011409 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070011410 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
11411 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011412#ifdef FEATURE_WLAN_TDLS
11413 mutex_unlock(&pHddCtx->tdls_lock);
11414#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +053011415 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -070011416 if( VOS_STATUS_SUCCESS != status )
11417 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -070011418 /* In case of JB, for P2P-GO, only change interface will be called,
11419 * This is the right place to enable back bmps_imps()
11420 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053011421 if (pHddCtx->hdd_wlan_suspended)
11422 {
11423 hdd_set_pwrparams(pHddCtx);
11424 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011425 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070011426 goto done;
11427 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070011428 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070011429 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070011430 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
11431 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -070011432 goto done;
11433 default:
11434 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
11435 __func__);
11436 return -EOPNOTSUPP;
11437
11438 }
11439
11440 }
11441 else
11442 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011443 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
11444 __func__, hdd_device_modetoString(pAdapter->device_mode),
11445 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011446 return -EOPNOTSUPP;
11447 }
11448
11449
11450 if(pRoamProfile)
11451 {
11452 if ( LastBSSType != pRoamProfile->BSSType )
11453 {
11454 /*interface type changed update in wiphy structure*/
11455 wdev->iftype = type;
11456
11457 /*the BSS mode changed, We need to issue disconnect
11458 if connected or in IBSS disconnect state*/
11459 if ( hdd_connGetConnectedBssType(
11460 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
11461 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
11462 {
11463 /*need to issue a disconnect to CSR.*/
11464 INIT_COMPLETION(pAdapter->disconnect_comp_var);
11465 if( eHAL_STATUS_SUCCESS ==
11466 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
11467 pAdapter->sessionId,
11468 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
11469 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011470 ret = wait_for_completion_interruptible_timeout(
11471 &pAdapter->disconnect_comp_var,
11472 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
11473 if (ret <= 0)
11474 {
11475 hddLog(VOS_TRACE_LEVEL_ERROR,
11476 FL("wait on disconnect_comp_var failed %ld"), ret);
11477 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011478 }
11479 }
11480 }
11481 }
11482
11483done:
11484 /*set bitmask based on updated value*/
11485 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -070011486
11487 /* Only STA mode support TM now
11488 * all other mode, TM feature should be disabled */
11489 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
11490 (~VOS_STA & pHddCtx->concurrency_mode) )
11491 {
11492 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
11493 }
11494
Jeff Johnson295189b2012-06-20 16:38:30 -070011495#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011496 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053011497 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -070011498 {
11499 //we are ok to do AMP
11500 pHddCtx->isAmpAllowed = VOS_TRUE;
11501 }
11502#endif //WLAN_BTAMP_FEATURE
11503 EXIT();
11504 return 0;
11505}
11506
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053011507/*
11508 * FUNCTION: wlan_hdd_cfg80211_change_iface
11509 * wrapper function to protect the actual implementation from SSR.
11510 */
11511int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
11512 struct net_device *ndev,
11513 enum nl80211_iftype type,
11514 u32 *flags,
11515 struct vif_params *params
11516 )
11517{
11518 int ret;
11519
11520 vos_ssr_protect(__func__);
11521 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
11522 vos_ssr_unprotect(__func__);
11523
11524 return ret;
11525}
11526
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011527#ifdef FEATURE_WLAN_TDLS
11528static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011529 struct net_device *dev,
11530#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
11531 const u8 *mac,
11532#else
11533 u8 *mac,
11534#endif
11535 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011536{
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011537 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011538 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011539 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011540 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053011541 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053011542 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011543
11544 ENTER();
11545
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053011546 if (!dev) {
11547 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
11548 return -EINVAL;
11549 }
11550
11551 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
11552 if (!pAdapter) {
11553 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
11554 return -EINVAL;
11555 }
11556
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053011557 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011558 {
11559 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11560 "Invalid arguments");
11561 return -EINVAL;
11562 }
Hoonki Lee27511902013-03-14 18:19:06 -070011563
11564 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
11565 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
11566 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011567 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070011568 "%s: TDLS mode is disabled OR not enabled in FW."
11569 MAC_ADDRESS_STR " Request declined.",
11570 __func__, MAC_ADDR_ARRAY(mac));
11571 return -ENOTSUPP;
11572 }
11573
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011574 if (pHddCtx->isLogpInProgress)
11575 {
11576 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11577 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053011578 wlan_hdd_tdls_set_link_status(pAdapter,
11579 mac,
11580 eTDLS_LINK_IDLE,
11581 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011582 return -EBUSY;
11583 }
11584
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053011585 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +053011586 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011587
11588 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011589 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011590 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
11591 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053011592 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011593 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070011594 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011595
11596 /* in add station, we accept existing valid staId if there is */
11597 if ((0 == update) &&
11598 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
11599 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011600 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011601 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011602 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011603 " link_status %d. staId %d. add station ignored.",
11604 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011605 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011606 return 0;
11607 }
11608 /* in change station, we accept only when staId is valid */
11609 if ((1 == update) &&
11610 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
11611 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
11612 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011613 tANI_U16 staId = pTdlsPeer->staId;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011614 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011615 "%s: " MAC_ADDRESS_STR
11616 " link status %d. staId %d. change station %s.",
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011617 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, staId,
11618 (TDLS_STA_INDEX_VALID(staId)) ? "ignored" : "declined");
11619 mutex_unlock(&pHddCtx->tdls_lock);
11620 return (TDLS_STA_INDEX_VALID(staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011621 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011622 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070011623
11624 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053011625 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011626 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011627 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11628 "%s: " MAC_ADDRESS_STR
11629 " TDLS setup is ongoing. Request declined.",
11630 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -070011631 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011632 }
11633
11634 /* first to check if we reached to maximum supported TDLS peer.
11635 TODO: for now, return -EPERM looks working fine,
11636 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011637 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
11638 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011639 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011640 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11641 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011642 " TDLS Max peer already connected. Request declined."
11643 " Num of peers (%d), Max allowed (%d).",
11644 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
11645 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070011646 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011647 }
11648 else
11649 {
11650 hddTdlsPeer_t *pTdlsPeer;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011651 mutex_lock(&pHddCtx->tdls_lock);
11652 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011653 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011654 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011655 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011656 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11657 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
11658 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011659 return -EPERM;
11660 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011661 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011662 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011663 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +053011664 wlan_hdd_tdls_set_link_status(pAdapter,
11665 mac,
11666 eTDLS_LINK_CONNECTING,
11667 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011668
Jeff Johnsond75fe012013-04-06 10:53:06 -070011669 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053011670 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011671 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011672 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011673 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -070011674 if(StaParams->htcap_present)
11675 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011676 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070011677 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011678 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070011679 "ht_capa->extended_capabilities: %0x",
11680 StaParams->HTCap.extendedHtCapInfo);
11681 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011682 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011683 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011684 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011685 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -070011686 if(StaParams->vhtcap_present)
11687 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011688 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070011689 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
11690 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
11691 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
11692 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011693 {
11694 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011695 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011696 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011697 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011698 "[%d]: %x ", i, StaParams->supported_rates[i]);
11699 }
Jeff Johnsond75fe012013-04-06 10:53:06 -070011700 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053011701 else if ((1 == update) && (NULL == StaParams))
11702 {
11703 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11704 "%s : update is true, but staParams is NULL. Error!", __func__);
11705 return -EPERM;
11706 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011707
11708 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
11709
11710 if (!update)
11711 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053011712 /*Before adding sta make sure that device exited from BMPS*/
11713 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
11714 {
11715 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11716 "%s: Adding tdls peer sta. Disable BMPS", __func__);
11717 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
11718 if (status != VOS_STATUS_SUCCESS) {
11719 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
11720 }
11721 }
11722
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011723 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011724 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011725 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053011726 hddLog(VOS_TRACE_LEVEL_ERROR,
11727 FL("Failed to add TDLS peer STA. Enable Bmps"));
11728 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011729 return -EPERM;
11730 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011731 }
11732 else
11733 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011734 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011735 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011736 if (ret != eHAL_STATUS_SUCCESS) {
11737 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
11738 return -EPERM;
11739 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011740 }
11741
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011742 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011743 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
11744
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053011745 mutex_lock(&pHddCtx->tdls_lock);
11746 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
11747
Masti, Narayanraddi07262462016-01-19 12:40:06 +053011748 if ((pTdlsPeer != NULL) &&
11749 (pTdlsPeer->link_status == eTDLS_LINK_TEARING))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011750 {
Masti, Narayanraddi07262462016-01-19 12:40:06 +053011751 hddLog(VOS_TRACE_LEVEL_ERROR,
11752 FL("peer link status %u"), pTdlsPeer->link_status);
11753 mutex_unlock(&pHddCtx->tdls_lock);
11754 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011755 }
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053011756 mutex_unlock(&pHddCtx->tdls_lock);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011757
Masti, Narayanraddi07262462016-01-19 12:40:06 +053011758 if (ret <= 0)
11759 {
11760 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11761 "%s: timeout waiting for tdls add station indication %ld",
11762 __func__, ret);
11763 goto error;
11764 }
11765
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011766 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
11767 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011768 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011769 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070011770 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011771 }
11772
11773 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -070011774
11775error:
Atul Mittal115287b2014-07-08 13:26:33 +053011776 wlan_hdd_tdls_set_link_status(pAdapter,
11777 mac,
11778 eTDLS_LINK_IDLE,
11779 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -070011780 return -EPERM;
11781
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011782}
11783#endif
11784
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011785static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011786 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011787#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
11788 const u8 *mac,
11789#else
Jeff Johnson295189b2012-06-20 16:38:30 -070011790 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011791#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011792 struct station_parameters *params)
11793{
11794 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011795 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +053011796 hdd_context_t *pHddCtx;
11797 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011798 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011799 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070011800#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011801 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011802 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011803 tANI_U8 isOffChannelSupported = 0;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011804 tANI_U8 isQosWmmSta = FALSE;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070011805#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070011806
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011807 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011808
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011809 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +053011810 if ((NULL == pAdapter))
11811 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011812 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053011813 "invalid adapter ");
11814 return -EINVAL;
11815 }
11816
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011817 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11818 TRACE_CODE_HDD_CHANGE_STATION,
11819 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +053011820 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +053011821
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011822 ret = wlan_hdd_validate_context(pHddCtx);
11823 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +053011824 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011825 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +053011826 }
11827
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011828 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11829
11830 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011831 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011832 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11833 "invalid HDD station context");
11834 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011835 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011836 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
11837
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011838 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
11839 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -070011840 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011841 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -070011842 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011843 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -070011844 WLANTL_STA_AUTHENTICATED);
11845
Gopichand Nakkala29149562013-05-10 21:43:41 +053011846 if (status != VOS_STATUS_SUCCESS)
11847 {
11848 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11849 "%s: Not able to change TL state to AUTHENTICATED", __func__);
11850 return -EINVAL;
11851 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011852 }
11853 }
Hoonki Leea6d49be2013-04-05 09:43:25 -070011854 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
11855 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +053011856#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011857 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
11858 StaParams.capability = params->capability;
11859 StaParams.uapsd_queues = params->uapsd_queues;
11860 StaParams.max_sp = params->max_sp;
11861
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011862 /* Convert (first channel , number of channels) tuple to
11863 * the total list of channels. This goes with the assumption
11864 * that if the first channel is < 14, then the next channels
11865 * are an incremental of 1 else an incremental of 4 till the number
11866 * of channels.
11867 */
11868 if (0 != params->supported_channels_len) {
11869 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
11870 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
11871 {
11872 int wifi_chan_index;
11873 StaParams.supported_channels[j] = params->supported_channels[i];
11874 wifi_chan_index =
11875 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
11876 no_of_channels = params->supported_channels[i+1];
11877 for(k=1; k <= no_of_channels; k++)
11878 {
11879 StaParams.supported_channels[j+1] =
11880 StaParams.supported_channels[j] + wifi_chan_index;
11881 j+=1;
11882 }
11883 }
11884 StaParams.supported_channels_len = j;
11885 }
SaidiReddy Yenuga0f1a1592017-04-05 13:18:26 +053011886 if (params->supported_oper_classes_len >
11887 SIR_MAC_MAX_SUPP_OPER_CLASSES) {
11888 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11889 "received oper classes:%d, resetting it to max supported %d",
11890 params->supported_oper_classes_len,
11891 SIR_MAC_MAX_SUPP_OPER_CLASSES);
11892 params->supported_oper_classes_len =
11893 SIR_MAC_MAX_SUPP_OPER_CLASSES;
11894 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011895 vos_mem_copy(StaParams.supported_oper_classes,
11896 params->supported_oper_classes,
11897 params->supported_oper_classes_len);
11898 StaParams.supported_oper_classes_len =
11899 params->supported_oper_classes_len;
11900
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053011901 if (params->ext_capab_len > sizeof(StaParams.extn_capability)) {
11902 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11903 "received extn capabilities:%d, resetting it to max supported",
11904 params->ext_capab_len);
11905 params->ext_capab_len = sizeof(StaParams.extn_capability);
11906 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011907 if (0 != params->ext_capab_len)
11908 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053011909 params->ext_capab_len);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011910
11911 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070011912 {
11913 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011914 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070011915 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011916
11917 StaParams.supported_rates_len = params->supported_rates_len;
11918
11919 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
11920 * The supported_rates array , for all the structures propogating till Add Sta
11921 * to the firmware has to be modified , if the supplicant (ieee80211) is
11922 * modified to send more rates.
11923 */
11924
11925 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
11926 */
11927 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
11928 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
11929
11930 if (0 != StaParams.supported_rates_len) {
11931 int i = 0;
11932 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
11933 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011934 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011935 "Supported Rates with Length %d", StaParams.supported_rates_len);
11936 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011937 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011938 "[%d]: %0x", i, StaParams.supported_rates[i]);
11939 }
11940
11941 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070011942 {
11943 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011944 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070011945 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011946
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011947 if (0 != params->ext_capab_len ) {
11948 /*Define A Macro : TODO Sunil*/
11949 if ((1<<4) & StaParams.extn_capability[3]) {
11950 isBufSta = 1;
11951 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011952 /* TDLS Channel Switching Support */
11953 if ((1<<6) & StaParams.extn_capability[3]) {
11954 isOffChannelSupported = 1;
11955 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011956 }
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011957
11958 if (pHddCtx->cfg_ini->fEnableTDLSWmmMode &&
Nitesh Shah48df4c02016-08-12 16:27:33 +053011959 (params->ht_capa || params->vht_capa ||
11960 (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME))))
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011961 /* TDLS Peer is WME/QoS capable */
11962 isQosWmmSta = TRUE;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011963
11964 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11965 "%s: TDLS Peer is QOS capable isQosWmmSta= %d HTcapPresent= %d",
11966 __func__, isQosWmmSta, StaParams.htcap_present);
11967
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011968 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
11969 &StaParams, isBufSta,
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011970 isOffChannelSupported,
11971 isQosWmmSta);
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011972
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053011973 if (VOS_STATUS_SUCCESS != status) {
11974 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11975 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
11976 return -EINVAL;
11977 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011978 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
11979
11980 if (VOS_STATUS_SUCCESS != status) {
11981 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11982 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
11983 return -EINVAL;
11984 }
11985 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -070011986#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +053011987 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011988 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011989 return status;
11990}
11991
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011992#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
11993static int wlan_hdd_change_station(struct wiphy *wiphy,
11994 struct net_device *dev,
11995 const u8 *mac,
11996 struct station_parameters *params)
11997#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011998static int wlan_hdd_change_station(struct wiphy *wiphy,
11999 struct net_device *dev,
12000 u8 *mac,
12001 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012002#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012003{
12004 int ret;
12005
12006 vos_ssr_protect(__func__);
12007 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
12008 vos_ssr_unprotect(__func__);
12009
12010 return ret;
12011}
12012
Jeff Johnson295189b2012-06-20 16:38:30 -070012013/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012014 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -070012015 * This function is used to initialize the key information
12016 */
12017#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012018static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012019 struct net_device *ndev,
12020 u8 key_index, bool pairwise,
12021 const u8 *mac_addr,
12022 struct key_params *params
12023 )
12024#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012025static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012026 struct net_device *ndev,
12027 u8 key_index, const u8 *mac_addr,
12028 struct key_params *params
12029 )
12030#endif
12031{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012032 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070012033 tCsrRoamSetKey setKey;
12034 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012035 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012036 v_U32_t roamId= 0xFF;
12037 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070012038 hdd_hostapd_state_t *pHostapdState;
12039 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012040 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012041 hdd_context_t *pHddCtx;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053012042 uint8_t i;
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053012043 v_MACADDR_t *peerMacAddr;
12044 u64 rsc_counter = 0;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053012045 uint8_t staid = HDD_MAX_STA_COUNT;
12046 bool pairwise_set_key = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070012047
12048 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012049
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012050 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12051 TRACE_CODE_HDD_CFG80211_ADD_KEY,
12052 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012053 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12054 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012055 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012056 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012057 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012058 }
12059
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012060 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12061 __func__, hdd_device_modetoString(pAdapter->device_mode),
12062 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012063
12064 if (CSR_MAX_NUM_KEY <= key_index)
12065 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012066 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012067 key_index);
12068
12069 return -EINVAL;
12070 }
12071
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012072 if (CSR_MAX_KEY_LEN < params->key_len)
12073 {
12074 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
12075 params->key_len);
12076
12077 return -EINVAL;
12078 }
12079
Jingxiang Gec438aea2017-10-26 16:44:00 +080012080 if (CSR_MAX_RSC_LEN < params->seq_len)
12081 {
12082 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Invalid seq length %d", __func__,
12083 params->seq_len);
12084 }
12085
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012086 hddLog(VOS_TRACE_LEVEL_INFO,
Jingxiang Gec438aea2017-10-26 16:44:00 +080012087 "%s: called with key index = %d & key length %d & seq length %d",
12088 __func__, key_index, params->key_len, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070012089
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053012090 peerMacAddr = (v_MACADDR_t *)mac_addr;
12091
Jeff Johnson295189b2012-06-20 16:38:30 -070012092 /*extract key idx, key len and key*/
12093 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
12094 setKey.keyId = key_index;
12095 setKey.keyLength = params->key_len;
12096 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
Jingxiang Gec438aea2017-10-26 16:44:00 +080012097 vos_mem_copy(&setKey.keyRsc[0], params->seq, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070012098
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012099 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070012100 {
12101 case WLAN_CIPHER_SUITE_WEP40:
12102 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
12103 break;
12104
12105 case WLAN_CIPHER_SUITE_WEP104:
12106 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
12107 break;
12108
12109 case WLAN_CIPHER_SUITE_TKIP:
12110 {
12111 u8 *pKey = &setKey.Key[0];
12112 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
12113
12114 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
12115
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012116 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -070012117
12118 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012119 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070012120 |--------------|----------|----------|
12121 <---16bytes---><--8bytes--><--8bytes-->
12122
12123 */
12124 /*Sme expects the 32 bytes key to be in the below order
12125
12126 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012127 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070012128 |--------------|----------|----------|
12129 <---16bytes---><--8bytes--><--8bytes-->
12130 */
12131 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012132 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -070012133
12134 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012135 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070012136
12137 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012138 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070012139
12140
12141 break;
12142 }
12143
12144 case WLAN_CIPHER_SUITE_CCMP:
12145 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
12146 break;
12147
12148#ifdef FEATURE_WLAN_WAPI
12149 case WLAN_CIPHER_SUITE_SMS4:
12150 {
12151 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
12152 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
12153 params->key, params->key_len);
12154 return 0;
12155 }
12156#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070012157
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080012158#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070012159 case WLAN_CIPHER_SUITE_KRK:
12160 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
12161 break;
12162#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070012163
12164#ifdef WLAN_FEATURE_11W
12165 case WLAN_CIPHER_SUITE_AES_CMAC:
12166 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -070012167 break;
Chet Lanctot186b5732013-03-18 10:26:30 -070012168#endif
12169
Jeff Johnson295189b2012-06-20 16:38:30 -070012170 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012171 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070012172 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012173 status = -EOPNOTSUPP;
12174 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012175 }
12176
12177 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
12178 __func__, setKey.encType);
12179
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012180 if (
Jeff Johnson295189b2012-06-20 16:38:30 -070012181#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12182 (!pairwise)
12183#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012184 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -070012185#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012186 )
12187 {
12188 /* set group key*/
12189 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12190 "%s- %d: setting Broadcast key",
12191 __func__, __LINE__);
12192 setKey.keyDirection = eSIR_RX_ONLY;
12193 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
12194 }
12195 else
12196 {
12197 /* set pairwise key*/
12198 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12199 "%s- %d: setting pairwise key",
12200 __func__, __LINE__);
12201 setKey.keyDirection = eSIR_TX_RX;
12202 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053012203 pairwise_set_key = true;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012204 }
12205 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
12206 {
12207 setKey.keyDirection = eSIR_TX_RX;
12208 /*Set the group key*/
12209 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
12210 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -070012211
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012212 if ( 0 != status )
12213 {
12214 hddLog(VOS_TRACE_LEVEL_ERROR,
12215 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012216 status = -EINVAL;
12217 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012218 }
12219 /*Save the keys here and call sme_RoamSetKey for setting
12220 the PTK after peer joins the IBSS network*/
12221 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
12222 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012223 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012224 }
Gopichand Nakkala29149562013-05-10 21:43:41 +053012225 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
12226 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
12227 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012228 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012229 if( pHostapdState->bssState == BSS_START )
12230 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012231 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12232 vos_status = wlan_hdd_check_ula_done(pAdapter);
12233
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053012234 if (peerMacAddr && (pairwise_set_key == true))
12235 staid = hdd_sta_id_find_from_mac_addr(pAdapter, peerMacAddr);
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053012236
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012237 if ( vos_status != VOS_STATUS_SUCCESS )
12238 {
12239 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12240 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
12241 __LINE__, vos_status );
12242
12243 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
12244
12245 status = -EINVAL;
12246 goto end;
12247 }
12248
Jeff Johnson295189b2012-06-20 16:38:30 -070012249 status = WLANSAP_SetKeySta( pVosContext, &setKey);
12250
12251 if ( status != eHAL_STATUS_SUCCESS )
12252 {
12253 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12254 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
12255 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012256 status = -EINVAL;
12257 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012258 }
12259 }
12260
12261 /* Saving WEP keys */
12262 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
12263 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
12264 {
12265 //Save the wep key in ap context. Issue setkey after the BSS is started.
12266 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
12267 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
12268 }
12269 else
12270 {
12271 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012272 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012273 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
12274 }
12275 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012276 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
12277 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012278 {
12279 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12280 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12281
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012282#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12283 if (!pairwise)
12284#else
12285 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
12286#endif
12287 {
12288 /* set group key*/
12289 if (pHddStaCtx->roam_info.deferKeyComplete)
12290 {
12291 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12292 "%s- %d: Perform Set key Complete",
12293 __func__, __LINE__);
12294 hdd_PerformRoamSetKeyComplete(pAdapter);
12295 }
12296 }
12297
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053012298 if (pairwise_set_key == true)
12299 staid = pHddStaCtx->conn_info.staId[0];
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053012300
Jeff Johnson295189b2012-06-20 16:38:30 -070012301 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
12302
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -080012303 pWextState->roamProfile.Keys.defaultIndex = key_index;
12304
12305
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012306 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070012307 params->key, params->key_len);
12308
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012309
Jeff Johnson295189b2012-06-20 16:38:30 -070012310 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
12311
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012312 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070012313 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012314 __func__, setKey.peerMac[0], setKey.peerMac[1],
12315 setKey.peerMac[2], setKey.peerMac[3],
12316 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070012317 setKey.keyDirection);
12318
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012319 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +053012320
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012321 if ( vos_status != VOS_STATUS_SUCCESS )
12322 {
12323 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012324 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
12325 __LINE__, vos_status );
12326
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012327 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012328
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012329 status = -EINVAL;
12330 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012331
12332 }
12333
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012334#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012335 /* The supplicant may attempt to set the PTK once pre-authentication
12336 is done. Save the key in the UMAC and include it in the ADD BSS
12337 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012338 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012339 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012340 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012341 hddLog(VOS_TRACE_LEVEL_INFO_MED,
12342 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012343 status = 0;
12344 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012345 }
12346 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
12347 {
12348 hddLog(VOS_TRACE_LEVEL_ERROR,
12349 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012350 status = -EINVAL;
12351 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012352 }
12353#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070012354
12355 /* issue set key request to SME*/
12356 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
12357 pAdapter->sessionId, &setKey, &roamId );
12358
12359 if ( 0 != status )
12360 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012361 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012362 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
12363 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012364 status = -EINVAL;
12365 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012366 }
12367
12368
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012369 /* in case of IBSS as there was no information available about WEP keys during
12370 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070012371 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012372 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
12373 !( ( IW_AUTH_KEY_MGMT_802_1X
12374 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070012375 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
12376 )
12377 &&
12378 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
12379 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
12380 )
12381 )
12382 {
12383 setKey.keyDirection = eSIR_RX_ONLY;
12384 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
12385
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012386 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070012387 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012388 __func__, setKey.peerMac[0], setKey.peerMac[1],
12389 setKey.peerMac[2], setKey.peerMac[3],
12390 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070012391 setKey.keyDirection);
12392
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012393 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070012394 pAdapter->sessionId, &setKey, &roamId );
12395
12396 if ( 0 != status )
12397 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012398 hddLog(VOS_TRACE_LEVEL_ERROR,
12399 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012400 __func__, status);
12401 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012402 status = -EINVAL;
12403 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012404 }
12405 }
12406 }
12407
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053012408 if (pairwise_set_key == true) {
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053012409 for (i = 0; i < params->seq_len; i++) {
12410 rsc_counter |= (params->seq[i] << i*8);
12411 }
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053012412 WLANTL_SetKeySeqCounter(pVosContext, rsc_counter, staid);
12413 }
12414
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012415end:
12416 /* Need to clear any trace of key value in the memory.
12417 * Thus zero out the memory even though it is local
12418 * variable.
12419 */
12420 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012421 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012422 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012423}
12424
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012425#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12426static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
12427 struct net_device *ndev,
12428 u8 key_index, bool pairwise,
12429 const u8 *mac_addr,
12430 struct key_params *params
12431 )
12432#else
12433static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
12434 struct net_device *ndev,
12435 u8 key_index, const u8 *mac_addr,
12436 struct key_params *params
12437 )
12438#endif
12439{
12440 int ret;
12441 vos_ssr_protect(__func__);
12442#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12443 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
12444 mac_addr, params);
12445#else
12446 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
12447 params);
12448#endif
12449 vos_ssr_unprotect(__func__);
12450
12451 return ret;
12452}
12453
Jeff Johnson295189b2012-06-20 16:38:30 -070012454/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012455 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070012456 * This function is used to get the key information
12457 */
12458#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012459static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012460 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012461 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012462 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070012463 const u8 *mac_addr, void *cookie,
12464 void (*callback)(void *cookie, struct key_params*)
12465 )
12466#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012467static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012468 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012469 struct net_device *ndev,
12470 u8 key_index, const u8 *mac_addr, void *cookie,
12471 void (*callback)(void *cookie, struct key_params*)
12472 )
12473#endif
12474{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012475 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012476 hdd_wext_state_t *pWextState = NULL;
12477 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012478 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012479 hdd_context_t *pHddCtx;
12480 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012481
12482 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012483
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012484 if (NULL == pAdapter)
12485 {
12486 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12487 "%s: HDD adapter is Null", __func__);
12488 return -ENODEV;
12489 }
12490
12491 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12492 ret = wlan_hdd_validate_context(pHddCtx);
12493 if (0 != ret)
12494 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012495 return ret;
12496 }
12497
12498 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12499 pRoamProfile = &(pWextState->roamProfile);
12500
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012501 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12502 __func__, hdd_device_modetoString(pAdapter->device_mode),
12503 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012504
Jeff Johnson295189b2012-06-20 16:38:30 -070012505 memset(&params, 0, sizeof(params));
12506
12507 if (CSR_MAX_NUM_KEY <= key_index)
12508 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012509 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070012510 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012511 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012512
12513 switch(pRoamProfile->EncryptionType.encryptionType[0])
12514 {
12515 case eCSR_ENCRYPT_TYPE_NONE:
12516 params.cipher = IW_AUTH_CIPHER_NONE;
12517 break;
12518
12519 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
12520 case eCSR_ENCRYPT_TYPE_WEP40:
12521 params.cipher = WLAN_CIPHER_SUITE_WEP40;
12522 break;
12523
12524 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
12525 case eCSR_ENCRYPT_TYPE_WEP104:
12526 params.cipher = WLAN_CIPHER_SUITE_WEP104;
12527 break;
12528
12529 case eCSR_ENCRYPT_TYPE_TKIP:
12530 params.cipher = WLAN_CIPHER_SUITE_TKIP;
12531 break;
12532
12533 case eCSR_ENCRYPT_TYPE_AES:
12534 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
12535 break;
12536
12537 default:
12538 params.cipher = IW_AUTH_CIPHER_NONE;
12539 break;
12540 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012541
c_hpothuaaf19692014-05-17 17:01:48 +053012542 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12543 TRACE_CODE_HDD_CFG80211_GET_KEY,
12544 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012545
Jeff Johnson295189b2012-06-20 16:38:30 -070012546 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
12547 params.seq_len = 0;
12548 params.seq = NULL;
12549 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
12550 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012551 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012552 return 0;
12553}
12554
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012555#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12556static int wlan_hdd_cfg80211_get_key(
12557 struct wiphy *wiphy,
12558 struct net_device *ndev,
12559 u8 key_index, bool pairwise,
12560 const u8 *mac_addr, void *cookie,
12561 void (*callback)(void *cookie, struct key_params*)
12562 )
12563#else
12564static int wlan_hdd_cfg80211_get_key(
12565 struct wiphy *wiphy,
12566 struct net_device *ndev,
12567 u8 key_index, const u8 *mac_addr, void *cookie,
12568 void (*callback)(void *cookie, struct key_params*)
12569 )
12570#endif
12571{
12572 int ret;
12573
12574 vos_ssr_protect(__func__);
12575#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12576 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
12577 mac_addr, cookie, callback);
12578#else
12579 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
12580 callback);
12581#endif
12582 vos_ssr_unprotect(__func__);
12583
12584 return ret;
12585}
12586
Jeff Johnson295189b2012-06-20 16:38:30 -070012587/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012588 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070012589 * This function is used to delete the key information
12590 */
12591#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012592static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012593 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012594 u8 key_index,
12595 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070012596 const u8 *mac_addr
12597 )
12598#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012599static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012600 struct net_device *ndev,
12601 u8 key_index,
12602 const u8 *mac_addr
12603 )
12604#endif
12605{
12606 int status = 0;
12607
12608 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012609 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070012610 //it is observed that this is invalidating peer
12611 //key index whenever re-key is done. This is affecting data link.
12612 //It should be ok to ignore del_key.
12613#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012614 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
12615 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070012616 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
12617 tCsrRoamSetKey setKey;
12618 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012619
Jeff Johnson295189b2012-06-20 16:38:30 -070012620 ENTER();
12621
12622 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
12623 __func__,pAdapter->device_mode);
12624
12625 if (CSR_MAX_NUM_KEY <= key_index)
12626 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012627 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012628 key_index);
12629
12630 return -EINVAL;
12631 }
12632
12633 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
12634 setKey.keyId = key_index;
12635
12636 if (mac_addr)
12637 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
12638 else
12639 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
12640
12641 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
12642
12643 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012644 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012645 )
12646 {
12647
12648 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070012649 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
12650 if( pHostapdState->bssState == BSS_START)
12651 {
12652 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012653
Jeff Johnson295189b2012-06-20 16:38:30 -070012654 if ( status != eHAL_STATUS_SUCCESS )
12655 {
12656 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12657 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
12658 __LINE__, status );
12659 }
12660 }
12661 }
12662 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012663 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070012664 )
12665 {
12666 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12667
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012668 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
12669
12670 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070012671 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012672 __func__, setKey.peerMac[0], setKey.peerMac[1],
12673 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070012674 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012675 if(pAdapter->sessionCtx.station.conn_info.connState ==
12676 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070012677 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012678 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070012679 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012680
Jeff Johnson295189b2012-06-20 16:38:30 -070012681 if ( 0 != status )
12682 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012683 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012684 "%s: sme_RoamSetKey failure, returned %d",
12685 __func__, status);
12686 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
12687 return -EINVAL;
12688 }
12689 }
12690 }
12691#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070012692 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012693 return status;
12694}
12695
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012696#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12697static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
12698 struct net_device *ndev,
12699 u8 key_index,
12700 bool pairwise,
12701 const u8 *mac_addr
12702 )
12703#else
12704static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
12705 struct net_device *ndev,
12706 u8 key_index,
12707 const u8 *mac_addr
12708 )
12709#endif
12710{
12711 int ret;
12712
12713 vos_ssr_protect(__func__);
12714#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12715 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
12716 mac_addr);
12717#else
12718 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
12719#endif
12720 vos_ssr_unprotect(__func__);
12721
12722 return ret;
12723}
12724
Jeff Johnson295189b2012-06-20 16:38:30 -070012725/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012726 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070012727 * This function is used to set the default tx key index
12728 */
12729#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012730static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012731 struct net_device *ndev,
12732 u8 key_index,
12733 bool unicast, bool multicast)
12734#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012735static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012736 struct net_device *ndev,
12737 u8 key_index)
12738#endif
12739{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012740 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012741 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053012742 hdd_wext_state_t *pWextState;
12743 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012744 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012745
12746 ENTER();
12747
Gopichand Nakkala29149562013-05-10 21:43:41 +053012748 if ((NULL == pAdapter))
12749 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012750 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053012751 "invalid adapter");
12752 return -EINVAL;
12753 }
12754
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012755 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12756 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
12757 pAdapter->sessionId, key_index));
12758
Gopichand Nakkala29149562013-05-10 21:43:41 +053012759 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12760 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12761
12762 if ((NULL == pWextState) || (NULL == pHddStaCtx))
12763 {
12764 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12765 "invalid Wext state or HDD context");
12766 return -EINVAL;
12767 }
12768
Arif Hussain6d2a3322013-11-17 19:50:10 -080012769 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012770 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012771
Jeff Johnson295189b2012-06-20 16:38:30 -070012772 if (CSR_MAX_NUM_KEY <= key_index)
12773 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012774 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012775 key_index);
12776
12777 return -EINVAL;
12778 }
12779
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012780 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12781 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012782 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012783 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012784 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012785 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012786
Jeff Johnson295189b2012-06-20 16:38:30 -070012787 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070012788 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012789 )
Jeff Johnson295189b2012-06-20 16:38:30 -070012790 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053012791 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080012792 pHddStaCtx->conn_info.ucEncryptionType) &&
Hu Wangb1f68cb2017-08-23 20:01:49 +080012793#ifdef FEATURE_WLAN_WAPI
12794 (eCSR_ENCRYPT_TYPE_WPI !=
12795 pHddStaCtx->conn_info.ucEncryptionType) &&
12796#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012797 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080012798 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070012799 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012800 {
12801 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070012802 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012803
Jeff Johnson295189b2012-06-20 16:38:30 -070012804 tCsrRoamSetKey setKey;
12805 v_U32_t roamId= 0xFF;
12806 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012807
12808 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012809 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012810
Jeff Johnson295189b2012-06-20 16:38:30 -070012811 Keys->defaultIndex = (u8)key_index;
12812 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
12813 setKey.keyId = key_index;
12814 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012815
12816 vos_mem_copy(&setKey.Key[0],
12817 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070012818 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012819
Gopichand Nakkala29149562013-05-10 21:43:41 +053012820 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012821
12822 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070012823 &pHddStaCtx->conn_info.bssId[0],
12824 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012825
Gopichand Nakkala29149562013-05-10 21:43:41 +053012826 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
12827 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
12828 eCSR_ENCRYPT_TYPE_WEP104)
12829 {
12830 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
12831 even though ap is configured for WEP-40 encryption. In this canse the key length
12832 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
12833 type(104) and switching encryption type to 40*/
12834 pWextState->roamProfile.EncryptionType.encryptionType[0] =
12835 eCSR_ENCRYPT_TYPE_WEP40;
12836 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
12837 eCSR_ENCRYPT_TYPE_WEP40;
12838 }
12839
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012840 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070012841 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012842
Jeff Johnson295189b2012-06-20 16:38:30 -070012843 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012844 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070012845 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012846
Jeff Johnson295189b2012-06-20 16:38:30 -070012847 if ( 0 != status )
12848 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012849 hddLog(VOS_TRACE_LEVEL_ERROR,
12850 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012851 status);
12852 return -EINVAL;
12853 }
12854 }
12855 }
12856
12857 /* In SoftAp mode setting key direction for default mode */
12858 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
12859 {
12860 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
12861 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
12862 (eCSR_ENCRYPT_TYPE_AES !=
12863 pWextState->roamProfile.EncryptionType.encryptionType[0])
12864 )
12865 {
12866 /* Saving key direction for default key index to TX default */
12867 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
12868 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
12869 }
12870 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012871 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012872 return status;
12873}
12874
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012875#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12876static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
12877 struct net_device *ndev,
12878 u8 key_index,
12879 bool unicast, bool multicast)
12880#else
12881static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
12882 struct net_device *ndev,
12883 u8 key_index)
12884#endif
12885{
12886 int ret;
12887 vos_ssr_protect(__func__);
12888#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12889 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
12890 multicast);
12891#else
12892 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
12893#endif
12894 vos_ssr_unprotect(__func__);
12895
12896 return ret;
12897}
12898
Jeff Johnson295189b2012-06-20 16:38:30 -070012899/*
12900 * FUNCTION: wlan_hdd_cfg80211_inform_bss
12901 * This function is used to inform the BSS details to nl80211 interface.
12902 */
12903static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
12904 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
12905{
12906 struct net_device *dev = pAdapter->dev;
12907 struct wireless_dev *wdev = dev->ieee80211_ptr;
12908 struct wiphy *wiphy = wdev->wiphy;
12909 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
12910 int chan_no;
12911 int ie_length;
12912 const char *ie;
12913 unsigned int freq;
12914 struct ieee80211_channel *chan;
12915 int rssi = 0;
12916 struct cfg80211_bss *bss = NULL;
12917
Jeff Johnson295189b2012-06-20 16:38:30 -070012918 if( NULL == pBssDesc )
12919 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012920 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012921 return bss;
12922 }
12923
12924 chan_no = pBssDesc->channelId;
12925 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
12926 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
12927
12928 if( NULL == ie )
12929 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012930 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012931 return bss;
12932 }
12933
12934#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
12935 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
12936 {
12937 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
12938 }
12939 else
12940 {
12941 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
12942 }
12943#else
12944 freq = ieee80211_channel_to_frequency(chan_no);
12945#endif
12946
12947 chan = __ieee80211_get_channel(wiphy, freq);
12948
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053012949 if (!chan) {
12950 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
12951 return NULL;
12952 }
12953
Abhishek Singhaee43942014-06-16 18:55:47 +053012954 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070012955
Anand N Sunkad9f80b742015-07-30 20:05:51 +053012956 return cfg80211_inform_bss(wiphy, chan,
12957#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12958 CFG80211_BSS_FTYPE_UNKNOWN,
12959#endif
12960 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012961 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070012962 pBssDesc->capabilityInfo,
12963 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053012964 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070012965}
12966
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053012967/*
12968 * wlan_hdd_cfg80211_update_bss_list :to inform nl80211
12969 * interface that BSS might have been lost.
12970 * @pAdapter: adaptor
12971 * @bssid: bssid which might have been lost
12972 *
12973 * Return: bss which is unlinked from kernel cache
12974 */
12975struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_list(
12976 hdd_adapter_t *pAdapter, tSirMacAddr bssid)
12977{
12978 struct net_device *dev = pAdapter->dev;
12979 struct wireless_dev *wdev = dev->ieee80211_ptr;
12980 struct wiphy *wiphy = wdev->wiphy;
12981 struct cfg80211_bss *bss = NULL;
12982
Abhishek Singh5a597e62016-12-05 15:16:30 +053012983 bss = hdd_get_bss_entry(wiphy,
12984 NULL, bssid,
12985 NULL, 0);
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053012986 if (bss == NULL) {
12987 hddLog(LOGE, FL("BSS not present"));
12988 } else {
12989 hddLog(LOG1, FL("cfg80211_unlink_bss called for BSSID "
12990 MAC_ADDRESS_STR), MAC_ADDR_ARRAY(bssid));
12991 cfg80211_unlink_bss(wiphy, bss);
12992 }
12993 return bss;
12994}
Jeff Johnson295189b2012-06-20 16:38:30 -070012995
12996
12997/*
12998 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
12999 * This function is used to inform the BSS details to nl80211 interface.
13000 */
13001struct cfg80211_bss*
13002wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
13003 tSirBssDescription *bss_desc
13004 )
13005{
13006 /*
13007 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
13008 already exists in bss data base of cfg80211 for that particular BSS ID.
13009 Using cfg80211_inform_bss_frame to update the bss entry instead of
13010 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
13011 now there is no possibility to get the mgmt(probe response) frame from PE,
13012 converting bss_desc to ieee80211_mgmt(probe response) and passing to
13013 cfg80211_inform_bss_frame.
13014 */
13015 struct net_device *dev = pAdapter->dev;
13016 struct wireless_dev *wdev = dev->ieee80211_ptr;
13017 struct wiphy *wiphy = wdev->wiphy;
13018 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080013019#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
13020 qcom_ie_age *qie_age = NULL;
13021 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
13022#else
Jeff Johnson295189b2012-06-20 16:38:30 -070013023 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080013024#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013025 const char *ie =
13026 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
13027 unsigned int freq;
13028 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053013029 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013030 struct cfg80211_bss *bss_status = NULL;
13031 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
13032 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070013033 hdd_context_t *pHddCtx;
13034 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070013035#ifdef WLAN_OPEN_SOURCE
13036 struct timespec ts;
13037#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013038
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013039
Wilson Yangf80a0542013-10-07 13:02:37 -070013040 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13041 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070013042 if (0 != status)
13043 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070013044 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070013045 }
13046
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053013047 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070013048 if (!mgmt)
13049 {
13050 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13051 "%s: memory allocation failed ", __func__);
13052 return NULL;
13053 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070013054
Jeff Johnson295189b2012-06-20 16:38:30 -070013055 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070013056
13057#ifdef WLAN_OPEN_SOURCE
13058 /* Android does not want the timestamp from the frame.
13059 Instead it wants a monotonic increasing value */
13060 get_monotonic_boottime(&ts);
13061 mgmt->u.probe_resp.timestamp =
13062 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
13063#else
13064 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070013065 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
13066 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070013067
13068#endif
13069
Jeff Johnson295189b2012-06-20 16:38:30 -070013070 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
13071 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080013072
13073#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
13074 /* GPS Requirement: need age ie per entry. Using vendor specific. */
13075 /* Assuming this is the last IE, copy at the end */
13076 ie_length -=sizeof(qcom_ie_age);
13077 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
13078 qie_age->element_id = QCOM_VENDOR_IE_ID;
13079 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
13080 qie_age->oui_1 = QCOM_OUI1;
13081 qie_age->oui_2 = QCOM_OUI2;
13082 qie_age->oui_3 = QCOM_OUI3;
13083 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
Selvaraj, Sridhar4b3a8362016-10-12 12:34:08 +053013084 /* Lowi expects the timestamp of bss in units of 1/10 ms. In driver all
13085 * bss related timestamp is in units of ms. Due to this when scan results
13086 * are sent to lowi the scan age is high.To address this, send age in units
13087 * of 1/10 ms.
13088 */
13089 qie_age->age = (vos_timer_get_system_time() -
13090 bss_desc->nReceivedTime)/10;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080013091#endif
13092
Jeff Johnson295189b2012-06-20 16:38:30 -070013093 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053013094 if (bss_desc->fProbeRsp)
13095 {
13096 mgmt->frame_control |=
13097 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
13098 }
13099 else
13100 {
13101 mgmt->frame_control |=
13102 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
13103 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013104
13105#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013106 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070013107 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
13108 {
13109 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
13110 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013111 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070013112 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
13113
13114 {
13115 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
13116 }
13117 else
13118 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013119 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
13120 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070013121 kfree(mgmt);
13122 return NULL;
13123 }
13124#else
13125 freq = ieee80211_channel_to_frequency(chan_no);
13126#endif
13127 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080013128 /*when the band is changed on the fly using the GUI, three things are done
13129 * 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)
13130 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
13131 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
13132 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
13133 * and discards the channels correponding to previous band and calls back with zero bss results.
13134 * 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
13135 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
13136 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
13137 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
13138 * So drop the bss and continue to next bss.
13139 */
13140 if(chan == NULL)
13141 {
Deepthi Gowri306657b2016-04-28 17:10:41 +053013142 hddLog(VOS_TRACE_LEVEL_ERROR,
13143 FL("chan pointer is NULL, chan_no: %d freq: %d"),
13144 chan_no, freq);
Chilam Ngc4244af2013-04-01 15:37:32 -070013145 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080013146 return NULL;
13147 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053013148 /*To keep the rssi icon of the connected AP in the scan window
13149 *and the rssi icon of the wireless networks in sync
13150 * */
13151 if (( eConnectionState_Associated ==
13152 pAdapter->sessionCtx.station.conn_info.connState ) &&
13153 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
13154 pAdapter->sessionCtx.station.conn_info.bssId,
13155 WNI_CFG_BSSID_LEN)) &&
13156 (pHddCtx->hdd_wlan_suspended == FALSE))
13157 {
13158 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
13159 rssi = (pAdapter->rssi * 100);
13160 }
13161 else
13162 {
13163 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
13164 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013165
Nirav Shah20ac06f2013-12-12 18:14:06 +053013166 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053013167 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
13168 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053013169
Jeff Johnson295189b2012-06-20 16:38:30 -070013170 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
13171 frame_len, rssi, GFP_KERNEL);
13172 kfree(mgmt);
13173 return bss_status;
13174}
13175
13176/*
13177 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
13178 * This function is used to update the BSS data base of CFG8011
13179 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013180struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070013181 tCsrRoamInfo *pRoamInfo
13182 )
13183{
13184 tCsrRoamConnectedProfile roamProfile;
13185 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13186 struct cfg80211_bss *bss = NULL;
13187
13188 ENTER();
13189
13190 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
13191 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
13192
13193 if (NULL != roamProfile.pBssDesc)
13194 {
Girish Gowlif4b68022014-08-28 23:18:57 +053013195 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
13196 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070013197
13198 if (NULL == bss)
13199 {
13200 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
13201 __func__);
13202 }
13203
13204 sme_RoamFreeConnectProfile(hHal, &roamProfile);
13205 }
13206 else
13207 {
13208 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
13209 __func__);
13210 }
13211 return bss;
13212}
13213
13214/*
13215 * FUNCTION: wlan_hdd_cfg80211_update_bss
13216 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013217static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
13218 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070013219 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013220{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013221 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013222 tCsrScanResultInfo *pScanResult;
13223 eHalStatus status = 0;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013224 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013225 tScanResultHandle pResult;
13226 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070013227 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013228 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070013229 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013230
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013231 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13232 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
13233 NO_SESSION, pAdapter->sessionId));
13234
Wilson Yangf80a0542013-10-07 13:02:37 -070013235 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013236 ret = wlan_hdd_validate_context(pHddCtx);
13237 if (0 != ret)
Jeff Johnson295189b2012-06-20 16:38:30 -070013238 {
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013239 return ret;
Wilson Yangf80a0542013-10-07 13:02:37 -070013240 }
13241
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013242 if (pAdapter->request != NULL)
13243 {
13244 if ((pAdapter->request->n_ssids == 1)
13245 && (pAdapter->request->ssids != NULL)
13246 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
13247 is_p2p_scan = true;
13248 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013249 /*
13250 * start getting scan results and populate cgf80211 BSS database
13251 */
13252 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
13253
13254 /* no scan results */
13255 if (NULL == pResult)
13256 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013257 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
13258 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053013259 wlan_hdd_get_frame_logs(pAdapter,
13260 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070013261 return status;
13262 }
13263
13264 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
13265
13266 while (pScanResult)
13267 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013268 /*
13269 * cfg80211_inform_bss() is not updating ie field of bss entry, if
13270 * entry already exists in bss data base of cfg80211 for that
13271 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
13272 * bss entry instead of cfg80211_inform_bss, But this call expects
13273 * mgmt packet as input. As of now there is no possibility to get
13274 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070013275 * ieee80211_mgmt(probe response) and passing to c
13276 * fg80211_inform_bss_frame.
13277 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013278 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
13279 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
13280 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013281 pScanResult = sme_ScanResultGetNext(hHal, pResult);
13282 continue; //Skip the non p2p bss entries
13283 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013284 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
13285 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013286
Jeff Johnson295189b2012-06-20 16:38:30 -070013287
13288 if (NULL == bss_status)
13289 {
13290 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013291 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013292 }
13293 else
13294 {
Yue Maf49ba872013-08-19 12:04:25 -070013295 cfg80211_put_bss(
13296#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
13297 wiphy,
13298#endif
13299 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070013300 }
13301
13302 pScanResult = sme_ScanResultGetNext(hHal, pResult);
13303 }
13304
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013305 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013306 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013307 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013308}
13309
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013310void
13311hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
13312{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013313 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080013314 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013315} /****** end hddPrintMacAddr() ******/
13316
13317void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070013318hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013319{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013320 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013321 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070013322 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
13323 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
13324 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013325} /****** end hddPrintPmkId() ******/
13326
13327//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
13328//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
13329
13330//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
13331//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
13332
13333#define dump_bssid(bssid) \
13334 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070013335 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
13336 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013337 }
13338
13339#define dump_pmkid(pMac, pmkid) \
13340 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070013341 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
13342 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013343 }
13344
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070013345#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013346/*
13347 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
13348 * This function is used to notify the supplicant of a new PMKSA candidate.
13349 */
13350int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013351 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013352 int index, bool preauth )
13353{
Jeff Johnsone7245742012-09-05 17:12:55 -070013354#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013355 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070013356 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013357
13358 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070013359 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013360
13361 if( NULL == pRoamInfo )
13362 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013363 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013364 return -EINVAL;
13365 }
13366
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070013367 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
13368 {
13369 dump_bssid(pRoamInfo->bssid);
13370 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013371 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070013372 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013373#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013374 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013375}
13376#endif //FEATURE_WLAN_LFR
13377
Yue Maef608272013-04-08 23:09:17 -070013378#ifdef FEATURE_WLAN_LFR_METRICS
13379/*
13380 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
13381 * 802.11r/LFR metrics reporting function to report preauth initiation
13382 *
13383 */
13384#define MAX_LFR_METRICS_EVENT_LENGTH 100
13385VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
13386 tCsrRoamInfo *pRoamInfo)
13387{
13388 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
13389 union iwreq_data wrqu;
13390
13391 ENTER();
13392
13393 if (NULL == pAdapter)
13394 {
13395 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
13396 return VOS_STATUS_E_FAILURE;
13397 }
13398
13399 /* create the event */
13400 memset(&wrqu, 0, sizeof(wrqu));
13401 memset(metrics_notification, 0, sizeof(metrics_notification));
13402
13403 wrqu.data.pointer = metrics_notification;
13404 wrqu.data.length = scnprintf(metrics_notification,
13405 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
13406 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
13407
13408 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
13409
13410 EXIT();
13411
13412 return VOS_STATUS_SUCCESS;
13413}
13414
13415/*
13416 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
13417 * 802.11r/LFR metrics reporting function to report preauth completion
13418 * or failure
13419 */
13420VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
13421 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
13422{
13423 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
13424 union iwreq_data wrqu;
13425
13426 ENTER();
13427
13428 if (NULL == pAdapter)
13429 {
13430 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
13431 return VOS_STATUS_E_FAILURE;
13432 }
13433
13434 /* create the event */
13435 memset(&wrqu, 0, sizeof(wrqu));
13436 memset(metrics_notification, 0, sizeof(metrics_notification));
13437
13438 scnprintf(metrics_notification, sizeof(metrics_notification),
13439 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
13440 MAC_ADDR_ARRAY(pRoamInfo->bssid));
13441
13442 if (1 == preauth_status)
13443 strncat(metrics_notification, " TRUE", 5);
13444 else
13445 strncat(metrics_notification, " FALSE", 6);
13446
13447 wrqu.data.pointer = metrics_notification;
13448 wrqu.data.length = strlen(metrics_notification);
13449
13450 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
13451
13452 EXIT();
13453
13454 return VOS_STATUS_SUCCESS;
13455}
13456
13457/*
13458 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
13459 * 802.11r/LFR metrics reporting function to report handover initiation
13460 *
13461 */
13462VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
13463 tCsrRoamInfo *pRoamInfo)
13464{
13465 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
13466 union iwreq_data wrqu;
13467
13468 ENTER();
13469
13470 if (NULL == pAdapter)
13471 {
13472 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
13473 return VOS_STATUS_E_FAILURE;
13474 }
13475
13476 /* create the event */
13477 memset(&wrqu, 0, sizeof(wrqu));
13478 memset(metrics_notification, 0, sizeof(metrics_notification));
13479
13480 wrqu.data.pointer = metrics_notification;
13481 wrqu.data.length = scnprintf(metrics_notification,
13482 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
13483 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
13484
13485 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
13486
13487 EXIT();
13488
13489 return VOS_STATUS_SUCCESS;
13490}
13491#endif
13492
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013493
13494/**
13495 * wlan_hdd_cfg80211_validate_scan_req - validate scan request
13496 * @scan_req: scan request to be checked
13497 *
13498 * Return: true or false
13499 */
13500#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
13501static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
13502 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053013503 *scan_req, hdd_context_t
13504 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013505{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053013506 if (!scan_req || !scan_req->wiphy ||
13507 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013508 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
13509 return false;
13510 }
13511 if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HDD, NULL)) {
13512 hddLog(VOS_TRACE_LEVEL_ERROR, "Load/Unload in progress");
13513 return false;
13514 }
13515 return true;
13516}
13517#else
13518static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
13519 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053013520 *scan_req, hdd_context_t
13521 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013522{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053013523 if (!scan_req || !scan_req->wiphy ||
13524 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013525 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
13526 return false;
13527 }
13528 return true;
13529}
13530#endif
13531
Mukul Sharmab392b642017-08-17 17:45:29 +053013532#define NET_DEV_IS_IFF_UP(pAdapter) (pAdapter->dev->flags & IFF_UP)
Jeff Johnson295189b2012-06-20 16:38:30 -070013533/*
13534 * FUNCTION: hdd_cfg80211_scan_done_callback
13535 * scanning callback function, called after finishing scan
13536 *
13537 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013538static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070013539 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
13540{
13541 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013542 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070013543 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013544 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070013545 struct cfg80211_scan_request *req = NULL;
13546 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053013547 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013548 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013549 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013550 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013551
13552 ENTER();
13553
c_manjee1b4ab9a2016-10-26 11:36:55 +053013554 if (!pAdapter || pAdapter->magic != WLAN_HDD_ADAPTER_MAGIC ||
13555 !pAdapter->dev) {
13556 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Adapter is not valid"));
13557 return 0;
13558 }
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013559 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053013560 if (NULL == pHddCtx) {
13561 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013562 return 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013563 }
13564
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053013565#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053013566 if (!NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053013567 {
13568 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Interface is down"));
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053013569 }
13570#endif
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013571 pScanInfo = &pHddCtx->scan_info;
13572
Jeff Johnson295189b2012-06-20 16:38:30 -070013573 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070013574 "%s called with halHandle = %pK, pContext = %pK,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080013575 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013576 __func__, halHandle, pContext, (int) scanId, (int) status);
13577
Kiet Lamac06e2c2013-10-23 16:25:07 +053013578 pScanInfo->mScanPendingCounter = 0;
13579
Jeff Johnson295189b2012-06-20 16:38:30 -070013580 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013581 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070013582 &pScanInfo->scan_req_completion_event,
13583 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013584 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070013585 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013586 hddLog(VOS_TRACE_LEVEL_ERROR,
13587 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070013588 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070013589 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070013590 }
13591
Yue Maef608272013-04-08 23:09:17 -070013592 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070013593 {
13594 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070013595 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070013596 }
13597
13598 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013599 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070013600 {
13601 hddLog(VOS_TRACE_LEVEL_INFO,
13602 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080013603 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070013604 (int) scanId);
13605 }
13606
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053013607#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053013608 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053013609#endif
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013610 {
13611 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
13612 pAdapter);
13613 if (0 > ret)
13614 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053013615 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013616
Jeff Johnson295189b2012-06-20 16:38:30 -070013617 /* If any client wait scan result through WEXT
13618 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013619 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070013620 {
13621 /* The other scan request waiting for current scan finish
13622 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013623 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070013624 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013625 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070013626 }
13627 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013628 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070013629 {
13630 struct net_device *dev = pAdapter->dev;
13631 union iwreq_data wrqu;
13632 int we_event;
13633 char *msg;
13634
13635 memset(&wrqu, '\0', sizeof(wrqu));
13636 we_event = SIOCGIWSCAN;
13637 msg = NULL;
13638 wireless_send_event(dev, we_event, &wrqu, msg);
13639 }
13640 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013641 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013642
13643 /* Get the Scan Req */
13644 req = pAdapter->request;
mukul sharmae7041822015-12-03 15:09:21 +053013645 pAdapter->request = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013646
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013647 /* Scan is no longer pending */
13648 pScanInfo->mScanPending = VOS_FALSE;
13649
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053013650 if (!wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Jeff Johnson295189b2012-06-20 16:38:30 -070013651 {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013652#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
13653 hddLog(VOS_TRACE_LEVEL_ERROR, FL("interface state %s"),
Mukul Sharmab392b642017-08-17 17:45:29 +053013654 NET_DEV_IS_IFF_UP(pAdapter) ? "up" : "down");
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013655#endif
13656
13657 if (pAdapter->dev) {
13658 hddLog(VOS_TRACE_LEVEL_ERROR, FL("device name %s"),
13659 pAdapter->dev->name);
13660 }
mukul sharmae7041822015-12-03 15:09:21 +053013661 complete(&pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -070013662 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070013663 }
13664
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013665 /* last_scan_timestamp is used to decide if new scan
13666 * is needed or not on station interface. If last station
13667 * scan time and new station scan time is less then
13668 * last_scan_timestamp ; driver will return cached scan.
13669 */
13670 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
13671 {
13672 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
13673
13674 if ( req->n_channels )
13675 {
13676 for (i = 0; i < req->n_channels ; i++ )
13677 {
13678 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
13679 }
13680 /* store no of channel scanned */
13681 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
13682 }
13683
13684 }
13685
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070013686 /*
13687 * cfg80211_scan_done informing NL80211 about completion
13688 * of scanning
13689 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053013690 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
13691 {
13692 aborted = true;
13693 }
mukul sharmae7041822015-12-03 15:09:21 +053013694
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013695#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053013696 if (NET_DEV_IS_IFF_UP(pAdapter) &&
13697 wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013698#endif
13699 cfg80211_scan_done(req, aborted);
mukul sharmae7041822015-12-03 15:09:21 +053013700
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080013701 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070013702
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013703allow_suspend:
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053013704 if ((pHddCtx->cfg_ini->enableMacSpoofing == MAC_ADDR_SPOOFING_FW_HOST_ENABLE
13705 ) && (pHddCtx->spoofMacAddr.isEnabled
13706 || pHddCtx->spoofMacAddr.isReqDeferred)) {
Siddharth Bhal76972212014-10-15 16:22:51 +053013707 /* Generate new random mac addr for next scan */
13708 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +053013709
13710 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
13711 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhal76972212014-10-15 16:22:51 +053013712 }
13713
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070013714 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013715 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070013716
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070013717 /* Acquire wakelock to handle the case where APP's tries to suspend
13718 * immediatly after the driver gets connect request(i.e after scan)
13719 * from supplicant, this result in app's is suspending and not able
13720 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013721 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070013722
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013723#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053013724 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013725#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070013726#ifdef FEATURE_WLAN_TDLS
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013727 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070013728#endif
13729
Jeff Johnson295189b2012-06-20 16:38:30 -070013730 EXIT();
13731 return 0;
13732}
13733
13734/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053013735 * FUNCTION: hdd_isConnectionInProgress
13736 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013737 *
13738 */
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013739v_BOOL_t hdd_isConnectionInProgress(hdd_context_t *pHddCtx, v_U8_t *session_id,
13740 scan_reject_states *reason)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013741{
13742 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
13743 hdd_station_ctx_t *pHddStaCtx = NULL;
13744 hdd_adapter_t *pAdapter = NULL;
13745 VOS_STATUS status = 0;
13746 v_U8_t staId = 0;
13747 v_U8_t *staMac = NULL;
13748
13749 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
13750
13751 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
13752 {
13753 pAdapter = pAdapterNode->pAdapter;
13754
13755 if( pAdapter )
13756 {
13757 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013758 "%s: Adapter with device mode %s (%d) exists",
13759 __func__, hdd_device_modetoString(pAdapter->device_mode),
13760 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013761 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053013762 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
13763 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
13764 (eConnectionState_Connecting ==
13765 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
13766 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053013767 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070013768 "%s: %pK(%d) Connection is in progress", __func__,
Rashmi Ramannab1429032014-04-26 14:59:09 +053013769 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013770 if (session_id && reason)
13771 {
13772 *session_id = pAdapter->sessionId;
13773 *reason = eHDD_CONNECTION_IN_PROGRESS;
13774 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053013775 return VOS_TRUE;
13776 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013777 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053013778 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013779 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053013780 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070013781 "%s: %pK(%d) Reassociation is in progress", __func__,
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013782 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013783 if (session_id && reason)
13784 {
13785 *session_id = pAdapter->sessionId;
13786 *reason = eHDD_REASSOC_IN_PROGRESS;
13787 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013788 return VOS_TRUE;
13789 }
13790 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013791 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
13792 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013793 {
13794 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13795 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013796 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013797 {
13798 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053013799 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080013800 "%s: client " MAC_ADDRESS_STR
13801 " is in the middle of WPS/EAPOL exchange.", __func__,
13802 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013803 if (session_id && reason)
13804 {
13805 *session_id = pAdapter->sessionId;
13806 *reason = eHDD_EAPOL_IN_PROGRESS;
13807 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053013808 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013809 }
13810 }
13811 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
13812 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
13813 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013814 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
13815 ptSapContext pSapCtx = NULL;
13816 pSapCtx = VOS_GET_SAP_CB(pVosContext);
13817 if(pSapCtx == NULL){
13818 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13819 FL("psapCtx is NULL"));
13820 return VOS_FALSE;
13821 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013822 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
13823 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013824 if ((pSapCtx->aStaInfo[staId].isUsed) &&
13825 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013826 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013827 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013828
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053013829 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080013830 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
13831 "middle of WPS/EAPOL exchange.", __func__,
13832 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013833 if (session_id && reason)
13834 {
13835 *session_id = pAdapter->sessionId;
13836 *reason = eHDD_SAP_EAPOL_IN_PROGRESS;
13837 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053013838 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013839 }
13840 }
13841 }
13842 }
13843 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13844 pAdapterNode = pNext;
13845 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053013846 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013847}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013848
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053013849/**
13850 * csr_scan_request_assign_bssid() - Set the BSSID received from Supplicant
13851 * to the Scan request
13852 * @scanRequest: Pointer to the csr scan request
13853 * @request: Pointer to the scan request from supplicant
13854 *
13855 * Return: None
13856 */
13857#ifdef CFG80211_SCAN_BSSID
13858static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
13859 struct cfg80211_scan_request *request)
13860{
13861 vos_mem_copy(scanRequest->bssid, request->bssid, VOS_MAC_ADDR_SIZE);
13862}
13863#else
13864static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
13865 struct cfg80211_scan_request *request)
13866{
13867}
13868#endif
13869
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013870/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013871 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070013872 * this scan respond to scan trigger and update cfg80211 scan database
13873 * later, scan dump command can be used to recieve scan results
13874 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013875int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080013876#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13877 struct net_device *dev,
13878#endif
13879 struct cfg80211_scan_request *request)
13880{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013881 hdd_adapter_t *pAdapter = NULL;
13882 hdd_context_t *pHddCtx = NULL;
13883 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013884 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013885 tCsrScanRequest scanRequest;
13886 tANI_U8 *channelList = NULL, i;
13887 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013888 int status;
13889 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013890 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013891 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053013892 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013893 bool is_p2p_scan = false;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013894 v_U8_t curr_session_id;
13895 scan_reject_states curr_reason;
Jeff Johnson295189b2012-06-20 16:38:30 -070013896
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013897#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
13898 struct net_device *dev = NULL;
13899 if (NULL == request)
13900 {
13901 hddLog(VOS_TRACE_LEVEL_ERROR,
13902 "%s: scan req param null", __func__);
13903 return -EINVAL;
13904 }
13905 dev = request->wdev->netdev;
13906#endif
13907
13908 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
13909 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
13910 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13911
Jeff Johnson295189b2012-06-20 16:38:30 -070013912 ENTER();
13913
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013914 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13915 __func__, hdd_device_modetoString(pAdapter->device_mode),
13916 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013917
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013918 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013919 if (0 != status)
13920 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013921 return status;
13922 }
13923
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013924 if (NULL == pwextBuf)
13925 {
13926 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
13927 __func__);
13928 return -EIO;
13929 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013930 cfg_param = pHddCtx->cfg_ini;
13931 pScanInfo = &pHddCtx->scan_info;
13932
Jeff Johnson295189b2012-06-20 16:38:30 -070013933#ifdef WLAN_BTAMP_FEATURE
13934 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013935 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070013936 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080013937 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013938 "%s: No scanning when AMP is on", __func__);
13939 return -EOPNOTSUPP;
13940 }
13941#endif
13942 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013943 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070013944 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013945 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013946 "%s: Not scanning on device_mode = %s (%d)",
13947 __func__, hdd_device_modetoString(pAdapter->device_mode),
13948 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013949 return -EOPNOTSUPP;
13950 }
13951
13952 if (TRUE == pScanInfo->mScanPending)
13953 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053013954 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
13955 {
13956 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
13957 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013958 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070013959 }
13960
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053013961 // Don't allow scan if PNO scan is going on.
13962 if (pHddCtx->isPnoEnable)
13963 {
13964 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13965 FL("pno scan in progress"));
13966 return -EBUSY;
13967 }
13968
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013969 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070013970 //Channel and action frame is pending
13971 //Otherwise Cancel Remain On Channel and allow Scan
13972 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013973 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070013974 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053013975 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070013976 return -EBUSY;
13977 }
13978
Jeff Johnson295189b2012-06-20 16:38:30 -070013979 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
13980 {
13981 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080013982 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013983 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013984 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013985 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
13986 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013987 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013988 "%s: MAX TM Level Scan not allowed", __func__);
13989 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013990 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070013991 }
13992 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
13993
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013994 /* Check if scan is allowed at this point of time.
13995 */
Hanumanth Reddy Pothulaec960842016-09-14 19:04:26 +053013996 if (TRUE == pHddCtx->btCoexModeSet)
13997 {
13998 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13999 FL("BTCoex Mode operation in progress"));
14000 return -EBUSY;
14001 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014002 if (hdd_isConnectionInProgress(pHddCtx, &curr_session_id, &curr_reason))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014003 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014004
14005 if (!(pHddCtx->scan_reject_cnt % HDD_SCAN_REJECT_RATE_LIMIT))
14006 hddLog(LOGE, FL("Scan not allowed Session %d reason %d"),
14007 curr_session_id, curr_reason);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014008 if (pHddCtx->last_scan_reject_session_id != curr_session_id ||
14009 pHddCtx->last_scan_reject_reason != curr_reason ||
14010 !pHddCtx->last_scan_reject_timestamp)
14011 {
14012 pHddCtx->last_scan_reject_session_id = curr_session_id;
14013 pHddCtx->last_scan_reject_reason = curr_reason;
Abhishek Singh3e500772017-07-17 10:13:43 +053014014 pHddCtx->last_scan_reject_timestamp =
14015 jiffies_to_msecs(jiffies) + SCAN_REJECT_THRESHOLD_TIME;
Abhishek Singhe4b12562017-06-20 16:53:39 +053014016 pHddCtx->scan_reject_cnt = 0;
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053014017 }
Abhishek Singhe4b12562017-06-20 16:53:39 +053014018 else
14019 {
14020 pHddCtx->scan_reject_cnt++;
14021
Abhishek Singhe4b12562017-06-20 16:53:39 +053014022 if ((pHddCtx->scan_reject_cnt >=
14023 SCAN_REJECT_THRESHOLD) &&
Abhishek Singh3e500772017-07-17 10:13:43 +053014024 vos_system_time_after(jiffies_to_msecs(jiffies),
14025 pHddCtx->last_scan_reject_timestamp))
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014026 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014027 hddLog(LOGE, FL("Session %d reason %d reject cnt %d threshold time has elapsed? %d"),
14028 curr_session_id, curr_reason, pHddCtx->scan_reject_cnt,
14029 vos_system_time_after(jiffies_to_msecs(jiffies),
14030 pHddCtx->last_scan_reject_timestamp));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014031 pHddCtx->last_scan_reject_timestamp = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053014032 pHddCtx->scan_reject_cnt = 0;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014033 if (pHddCtx->cfg_ini->enableFatalEvent)
14034 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
14035 WLAN_LOG_INDICATOR_HOST_DRIVER,
14036 WLAN_LOG_REASON_SCAN_NOT_ALLOWED,
14037 FALSE, FALSE);
14038 else
14039 {
14040 hddLog(LOGE, FL("Triggering SSR"));
14041 vos_wlanRestart();
14042 }
14043 }
14044 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014045 return -EBUSY;
14046 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014047 pHddCtx->last_scan_reject_timestamp = 0;
14048 pHddCtx->last_scan_reject_session_id = 0xFF;
14049 pHddCtx->last_scan_reject_reason = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053014050 pHddCtx->scan_reject_cnt = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014051
Jeff Johnson295189b2012-06-20 16:38:30 -070014052 vos_mem_zero( &scanRequest, sizeof(scanRequest));
14053
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014054 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
14055 * Becasue of this, driver is assuming that this is not wildcard scan and so
14056 * is not aging out the scan results.
14057 */
14058 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070014059 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014060 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014061 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014062
14063 if ((request->ssids) && (0 < request->n_ssids))
14064 {
14065 tCsrSSIDInfo *SsidInfo;
14066 int j;
14067 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
14068 /* Allocate num_ssid tCsrSSIDInfo structure */
14069 SsidInfo = scanRequest.SSIDs.SSIDList =
14070 ( tCsrSSIDInfo *)vos_mem_malloc(
14071 request->n_ssids*sizeof(tCsrSSIDInfo));
14072
14073 if(NULL == scanRequest.SSIDs.SSIDList)
14074 {
14075 hddLog(VOS_TRACE_LEVEL_ERROR,
14076 "%s: memory alloc failed SSIDInfo buffer", __func__);
14077 return -ENOMEM;
14078 }
14079
14080 /* copy all the ssid's and their length */
14081 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
14082 {
14083 /* get the ssid length */
14084 SsidInfo->SSID.length = request->ssids[j].ssid_len;
14085 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
14086 SsidInfo->SSID.length);
14087 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
14088 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
14089 j, SsidInfo->SSID.ssId);
14090 }
14091 /* set the scan type to active */
14092 scanRequest.scanType = eSIR_ACTIVE_SCAN;
14093 }
14094 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070014095 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053014096 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14097 TRACE_CODE_HDD_CFG80211_SCAN,
14098 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070014099 /* set the scan type to active */
14100 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070014101 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014102 else
14103 {
14104 /*Set the scan type to default type, in this case it is ACTIVE*/
14105 scanRequest.scanType = pScanInfo->scan_mode;
14106 }
14107 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
14108 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070014109
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053014110 csr_scan_request_assign_bssid(&scanRequest, request);
14111
Jeff Johnson295189b2012-06-20 16:38:30 -070014112 /* set BSSType to default type */
14113 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
14114
14115 /*TODO: scan the requested channels only*/
14116
14117 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014118 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070014119 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014120 hddLog(VOS_TRACE_LEVEL_WARN,
14121 "No of Scan Channels exceeded limit: %d", request->n_channels);
14122 request->n_channels = MAX_CHANNEL;
14123 }
14124
14125 hddLog(VOS_TRACE_LEVEL_INFO,
14126 "No of Scan Channels: %d", request->n_channels);
14127
14128
14129 if( request->n_channels )
14130 {
14131 char chList [(request->n_channels*5)+1];
14132 int len;
14133 channelList = vos_mem_malloc( request->n_channels );
14134 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053014135 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014136 hddLog(VOS_TRACE_LEVEL_ERROR,
14137 "%s: memory alloc failed channelList", __func__);
14138 status = -ENOMEM;
14139 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053014140 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014141
14142 for( i = 0, len = 0; i < request->n_channels ; i++ )
14143 {
14144 channelList[i] = request->channels[i]->hw_value;
14145 len += snprintf(chList+len, 5, "%d ", channelList[i]);
14146 }
14147
Nirav Shah20ac06f2013-12-12 18:14:06 +053014148 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014149 "Channel-List: %s ", chList);
14150 }
c_hpothu53512302014-04-15 18:49:53 +053014151
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014152 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
14153 scanRequest.ChannelInfo.ChannelList = channelList;
14154
14155 /* set requestType to full scan */
14156 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
14157
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014158 /* if there is back to back scan happening in driver with in
14159 * nDeferScanTimeInterval interval driver should defer new scan request
14160 * and should provide last cached scan results instead of new channel list.
14161 * This rule is not applicable if scan is p2p scan.
14162 * This condition will work only in case when last request no of channels
14163 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053014164 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053014165 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014166 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014167
Sushant Kaushik86592172015-04-27 16:35:03 +053014168 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
14169 /* if wps ie is NULL , then only defer scan */
14170 if ( pWpsIe == NULL &&
14171 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053014172 {
14173 if ( pScanInfo->last_scan_timestamp !=0 &&
14174 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
14175 {
14176 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
14177 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
14178 vos_mem_compare(pScanInfo->last_scan_channelList,
14179 channelList, pScanInfo->last_scan_numChannels))
14180 {
14181 hddLog(VOS_TRACE_LEVEL_WARN,
14182 " New and old station scan time differ is less then %u",
14183 pHddCtx->cfg_ini->nDeferScanTimeInterval);
14184
14185 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014186 pAdapter);
14187
Agarwal Ashish57e84372014-12-05 18:26:53 +053014188 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053014189 "Return old cached scan as all channels and no of channels are same");
14190
Agarwal Ashish57e84372014-12-05 18:26:53 +053014191 if (0 > ret)
14192 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014193
Agarwal Ashish57e84372014-12-05 18:26:53 +053014194 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053014195
14196 status = eHAL_STATUS_SUCCESS;
14197 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053014198 }
14199 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014200 }
14201
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014202 /* Flush the scan results(only p2p beacons) for STA scan and P2P
14203 * search (Flush on both full scan and social scan but not on single
14204 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
14205 */
14206
14207 /* Supplicant does single channel scan after 8-way handshake
14208 * and in that case driver shoudnt flush scan results. If
14209 * driver flushes the scan results here and unfortunately if
14210 * the AP doesnt respond to our probe req then association
14211 * fails which is not desired
14212 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053014213 if ((request->n_ssids == 1)
14214 && (request->ssids != NULL)
14215 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
14216 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014217
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053014218 if( is_p2p_scan ||
14219 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014220 {
14221 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
14222 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
14223 pAdapter->sessionId );
14224 }
14225
14226 if( request->ie_len )
14227 {
14228 /* save this for future association (join requires this) */
14229 /*TODO: Array needs to be converted to dynamic allocation,
14230 * as multiple ie.s can be sent in cfg80211_scan_request structure
14231 * CR 597966
14232 */
14233 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
14234 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
14235 pScanInfo->scanAddIE.length = request->ie_len;
14236
14237 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
14238 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
14239 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070014240 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014241 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070014242 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014243 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
14244 memcpy( pwextBuf->roamProfile.addIEScan,
14245 request->ie, request->ie_len);
14246 }
14247 else
14248 {
14249 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
14250 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070014251 }
14252
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014253 }
14254 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
14255 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
14256
14257 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
14258 request->ie_len);
14259 if (pP2pIe != NULL)
14260 {
14261#ifdef WLAN_FEATURE_P2P_DEBUG
14262 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
14263 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
14264 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053014265 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014266 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
14267 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
14268 "Go nego completed to Connection is started");
14269 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
14270 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053014271 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014272 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
14273 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070014274 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014275 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
14276 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
14277 "Disconnected state to Connection is started");
14278 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
14279 "for 4way Handshake");
14280 }
14281#endif
14282
14283 /* no_cck will be set during p2p find to disable 11b rates */
14284 if(TRUE == request->no_cck)
14285 {
14286 hddLog(VOS_TRACE_LEVEL_INFO,
14287 "%s: This is a P2P Search", __func__);
14288 scanRequest.p2pSearch = 1;
14289
14290 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053014291 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014292 /* set requestType to P2P Discovery */
14293 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
14294 }
14295
14296 /*
14297 Skip Dfs Channel in case of P2P Search
14298 if it is set in ini file
14299 */
14300 if(cfg_param->skipDfsChnlInP2pSearch)
14301 {
14302 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053014303 }
14304 else
14305 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014306 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053014307 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014308
Agarwal Ashish4f616132013-12-30 23:32:50 +053014309 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014310 }
14311 }
14312
14313 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
14314
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014315#ifdef FEATURE_WLAN_TDLS
14316 /* if tdls disagree scan right now, return immediately.
14317 tdls will schedule the scan when scan is allowed. (return SUCCESS)
14318 or will reject the scan if any TDLS is in progress. (return -EBUSY)
14319 */
14320 status = wlan_hdd_tdls_scan_callback (pAdapter,
14321 wiphy,
14322#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
14323 dev,
14324#endif
14325 request);
Abhishek Singhe2b63952016-01-05 18:27:29 +053014326 if (status <= 0)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014327 {
Abhishek Singhe2b63952016-01-05 18:27:29 +053014328 if (!status)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014329 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
14330 "scan rejected %d", __func__, status);
14331 else
14332 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
14333 __func__, status);
Abhishek Singhe2b63952016-01-05 18:27:29 +053014334 hdd_wlan_block_scan_by_tdls();
Gupta, Kapil2ebf3e02016-03-17 19:45:19 +053014335 goto free_mem;
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014336 }
14337#endif
14338
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070014339 /* acquire the wakelock to avoid the apps suspend during the scan. To
14340 * address the following issues.
14341 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
14342 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
14343 * for long time, this result in apps running at full power for long time.
14344 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
14345 * be stuck in full power because of resume BMPS
14346 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014347 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070014348
Nirav Shah20ac06f2013-12-12 18:14:06 +053014349 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
14350 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014351 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
14352 scanRequest.requestType, scanRequest.scanType,
14353 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053014354 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
14355
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053014356 if (pHddCtx->spoofMacAddr.isEnabled &&
14357 pHddCtx->cfg_ini->enableMacSpoofing == 1)
Siddharth Bhal76972212014-10-15 16:22:51 +053014358 {
14359 hddLog(VOS_TRACE_LEVEL_INFO,
14360 "%s: MAC Spoofing enabled for current scan", __func__);
14361 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
14362 * to fill TxBds for probe request during current scan
14363 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053014364 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053014365 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053014366
14367 if(status != VOS_STATUS_SUCCESS)
14368 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014369 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053014370 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053014371#ifdef FEATURE_WLAN_TDLS
14372 wlan_hdd_tdls_scan_done_callback(pAdapter);
14373#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053014374 goto free_mem;
14375 }
Siddharth Bhal76972212014-10-15 16:22:51 +053014376 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053014377 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070014378 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070014379 pAdapter->sessionId, &scanRequest, &scanId,
14380 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070014381
Jeff Johnson295189b2012-06-20 16:38:30 -070014382 if (eHAL_STATUS_SUCCESS != status)
14383 {
14384 hddLog(VOS_TRACE_LEVEL_ERROR,
14385 "%s: sme_ScanRequest returned error %d", __func__, status);
14386 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070014387 if(eHAL_STATUS_RESOURCES == status)
14388 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014389 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
14390 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070014391 status = -EBUSY;
14392 } else {
14393 status = -EIO;
14394 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014395 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014396
14397#ifdef FEATURE_WLAN_TDLS
14398 wlan_hdd_tdls_scan_done_callback(pAdapter);
14399#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014400 goto free_mem;
14401 }
14402
14403 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053014404 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070014405 pAdapter->request = request;
14406 pScanInfo->scanId = scanId;
14407
14408 complete(&pScanInfo->scan_req_completion_event);
14409
14410free_mem:
14411 if( scanRequest.SSIDs.SSIDList )
14412 {
14413 vos_mem_free(scanRequest.SSIDs.SSIDList);
14414 }
14415
14416 if( channelList )
14417 vos_mem_free( channelList );
14418
14419 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014420 return status;
14421}
14422
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014423int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
14424#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
14425 struct net_device *dev,
14426#endif
14427 struct cfg80211_scan_request *request)
14428{
14429 int ret;
14430
14431 vos_ssr_protect(__func__);
14432 ret = __wlan_hdd_cfg80211_scan(wiphy,
14433#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
14434 dev,
14435#endif
14436 request);
14437 vos_ssr_unprotect(__func__);
14438
14439 return ret;
14440}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014441
14442void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
14443{
14444 v_U8_t iniDot11Mode =
14445 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
14446 eHddDot11Mode hddDot11Mode = iniDot11Mode;
14447
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014448 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
14449 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014450 switch ( iniDot11Mode )
14451 {
14452 case eHDD_DOT11_MODE_AUTO:
14453 case eHDD_DOT11_MODE_11ac:
14454 case eHDD_DOT11_MODE_11ac_ONLY:
14455#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053014456 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
14457 sme_IsFeatureSupportedByFW(DOT11AC) )
14458 hddDot11Mode = eHDD_DOT11_MODE_11ac;
14459 else
14460 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014461#else
14462 hddDot11Mode = eHDD_DOT11_MODE_11n;
14463#endif
14464 break;
14465 case eHDD_DOT11_MODE_11n:
14466 case eHDD_DOT11_MODE_11n_ONLY:
14467 hddDot11Mode = eHDD_DOT11_MODE_11n;
14468 break;
14469 default:
14470 hddDot11Mode = iniDot11Mode;
14471 break;
14472 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053014473#ifdef WLAN_FEATURE_AP_HT40_24G
14474 if (operationChannel > SIR_11B_CHANNEL_END)
14475#endif
14476 {
14477 /* This call decides required channel bonding mode */
14478 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014479 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
14480 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053014481 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014482}
14483
Jeff Johnson295189b2012-06-20 16:38:30 -070014484/*
14485 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014486 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070014487 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014488int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053014489 const u8 *ssid, size_t ssid_len, const u8 *bssid,
14490 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070014491{
14492 int status = 0;
14493 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080014494 hdd_context_t *pHddCtx;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053014495 hdd_station_ctx_t *hdd_sta_ctx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014496 v_U32_t roamId;
14497 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070014498 eCsrAuthType RSNAuthType;
14499
14500 ENTER();
14501
14502 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080014503 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053014504 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080014505
14506 status = wlan_hdd_validate_context(pHddCtx);
14507 if (status)
14508 {
Yue Mae36e3552014-03-05 17:06:20 -080014509 return status;
14510 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014511
Jeff Johnson295189b2012-06-20 16:38:30 -070014512 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
14513 {
14514 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
14515 return -EINVAL;
14516 }
14517
Nitesh Shah9b066282017-06-06 18:05:52 +053014518 wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
14519
Jeff Johnson295189b2012-06-20 16:38:30 -070014520 pRoamProfile = &pWextState->roamProfile;
14521
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014522 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070014523 {
Jeff Johnsone7245742012-09-05 17:12:55 -070014524 hdd_station_ctx_t *pHddStaCtx;
14525 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Abhishek Singh6782c9e2017-06-06 13:37:45 +053014526 pHddStaCtx->get_mgmt_log_sent = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014527
Siddharth Bhalda0d1622015-04-24 15:47:49 +053014528 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
14529
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014530 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070014531 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
14532 {
14533 /*QoS not enabled in cfg file*/
14534 pRoamProfile->uapsd_mask = 0;
14535 }
14536 else
14537 {
14538 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014539 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070014540 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
14541 }
14542
14543 pRoamProfile->SSIDs.numOfSSIDs = 1;
14544 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
14545 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014546 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070014547 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
14548 ssid, ssid_len);
14549
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014550 vos_mem_zero(pRoamProfile->BSSIDs.bssid, WNI_CFG_BSSID_LEN);
14551 vos_mem_zero(pRoamProfile->bssid_hint, WNI_CFG_BSSID_LEN);
14552
Jeff Johnson295189b2012-06-20 16:38:30 -070014553 if (bssid)
14554 {
14555 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014556 vos_mem_copy(pRoamProfile->BSSIDs.bssid, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070014557 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014558 /* Save BSSID in seperate variable as well, as RoamProfile
14559 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070014560 case of join failure we should send valid BSSID to supplicant
14561 */
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014562 vos_mem_copy(pWextState->req_bssId, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070014563 WNI_CFG_BSSID_LEN);
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014564
Jeff Johnson295189b2012-06-20 16:38:30 -070014565 }
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014566 else if (bssid_hint)
Dhanashri Atre51981c62013-06-13 11:47:57 -070014567 {
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014568 /* Store bssid_hint to use in the scan filter. */
14569 vos_mem_copy(pRoamProfile->bssid_hint, bssid_hint,
14570 WNI_CFG_BSSID_LEN);
14571 /*
14572 * Save BSSID in seperate variable as well, as RoamProfile
14573 * BSSID is getting zeroed out in the association process. And in
14574 * case of join failure we should send valid BSSID to supplicant
14575 */
14576 vos_mem_copy(pWextState->req_bssId, bssid_hint,
14577 WNI_CFG_BSSID_LEN);
14578 hddLog(LOG1, FL(" bssid_hint: "MAC_ADDRESS_STR),
14579 MAC_ADDR_ARRAY(pRoamProfile->bssid_hint));
Dhanashri Atre51981c62013-06-13 11:47:57 -070014580 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014581
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014582
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014583 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
14584 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070014585 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
14586 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014587 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014588 /*set gen ie*/
14589 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
14590 /*set auth*/
14591 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
14592 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014593#ifdef FEATURE_WLAN_WAPI
14594 if (pAdapter->wapi_info.nWapiMode)
14595 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014596 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014597 switch (pAdapter->wapi_info.wapiAuthMode)
14598 {
14599 case WAPI_AUTH_MODE_PSK:
14600 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014601 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014602 pAdapter->wapi_info.wapiAuthMode);
14603 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
14604 break;
14605 }
14606 case WAPI_AUTH_MODE_CERT:
14607 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014608 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014609 pAdapter->wapi_info.wapiAuthMode);
14610 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
14611 break;
14612 }
14613 } // End of switch
14614 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
14615 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
14616 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014617 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014618 pRoamProfile->AuthType.numEntries = 1;
14619 pRoamProfile->EncryptionType.numEntries = 1;
14620 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
14621 pRoamProfile->mcEncryptionType.numEntries = 1;
14622 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
14623 }
14624 }
14625#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014626#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014627 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014628 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
14629 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
14630 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014631 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
14632 sizeof (tSirGtkOffloadParams));
14633 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014634 }
14635#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014636 pRoamProfile->csrPersona = pAdapter->device_mode;
14637
Jeff Johnson32d95a32012-09-10 13:15:23 -070014638 if( operatingChannel )
14639 {
14640 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
14641 pRoamProfile->ChannelInfo.numOfChannels = 1;
14642 }
Chet Lanctot186b5732013-03-18 10:26:30 -070014643 else
14644 {
14645 pRoamProfile->ChannelInfo.ChannelList = NULL;
14646 pRoamProfile->ChannelInfo.numOfChannels = 0;
14647 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014648 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
14649 {
14650 hdd_select_cbmode(pAdapter,operatingChannel);
14651 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014652
Agarwal Ashish40f9b872015-09-01 16:17:35 +053014653 /*
14654 * Change conn_state to connecting before sme_RoamConnect(),
14655 * because sme_RoamConnect() has a direct path to call
14656 * hdd_smeRoamCallback(), which will change the conn_state
14657 * If direct path, conn_state will be accordingly changed
14658 * to NotConnected or Associated by either
14659 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
14660 * in sme_RoamCallback()
14661 * if sme_RomConnect is to be queued,
14662 * Connecting state will remain until it is completed.
14663 * If connection state is not changed,
14664 * connection state will remain in eConnectionState_NotConnected state.
14665 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
14666 * if conn state is eConnectionState_NotConnected.
14667 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
14668 * informed of connect result indication which is an issue.
14669 */
14670
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053014671 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
14672 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053014673 {
14674 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053014675 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080014676 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
14677 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053014678 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014679 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070014680 pAdapter->sessionId, pRoamProfile, &roamId);
14681
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053014682 if ((eHAL_STATUS_SUCCESS != status) &&
14683 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
14684 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053014685
14686 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053014687 hddLog(VOS_TRACE_LEVEL_ERROR,
14688 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
14689 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080014690 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053014691 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080014692 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053014693 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080014694
14695 pRoamProfile->ChannelInfo.ChannelList = NULL;
14696 pRoamProfile->ChannelInfo.numOfChannels = 0;
14697
Jeff Johnson295189b2012-06-20 16:38:30 -070014698 }
14699 else
14700 {
14701 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
14702 return -EINVAL;
14703 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080014704 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014705 return status;
14706}
14707
14708/*
14709 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
14710 * This function is used to set the authentication type (OPEN/SHARED).
14711 *
14712 */
14713static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
14714 enum nl80211_auth_type auth_type)
14715{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014716 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014717 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14718
14719 ENTER();
14720
14721 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014722 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070014723 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014724 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053014725 hddLog(VOS_TRACE_LEVEL_INFO,
14726 "%s: set authentication type to AUTOSWITCH", __func__);
14727 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
14728 break;
14729
14730 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014731#ifdef WLAN_FEATURE_VOWIFI_11R
14732 case NL80211_AUTHTYPE_FT:
14733#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014734 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070014735 "%s: set authentication type to OPEN", __func__);
14736 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
14737 break;
14738
14739 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014740 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070014741 "%s: set authentication type to SHARED", __func__);
14742 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
14743 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080014744#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070014745 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014746 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070014747 "%s: set authentication type to CCKM WPA", __func__);
14748 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
14749 break;
14750#endif
14751
14752
14753 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014754 hddLog(VOS_TRACE_LEVEL_ERROR,
14755 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014756 auth_type);
14757 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
14758 return -EINVAL;
14759 }
14760
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014761 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070014762 pHddStaCtx->conn_info.authType;
14763 return 0;
14764}
14765
14766/*
14767 * FUNCTION: wlan_hdd_set_akm_suite
14768 * This function is used to set the key mgmt type(PSK/8021x).
14769 *
14770 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014771static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014772 u32 key_mgmt
14773 )
14774{
14775 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
14776 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053014777 /* Should be in ieee802_11_defs.h */
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053014778#ifndef WLAN_AKM_SUITE_8021X_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053014779#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053014780#endif
14781#ifndef WLAN_AKM_SUITE_PSK_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053014782#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053014783#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014784 /*set key mgmt type*/
14785 switch(key_mgmt)
14786 {
14787 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053014788 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053014789#ifdef WLAN_FEATURE_VOWIFI_11R
14790 case WLAN_AKM_SUITE_FT_PSK:
14791#endif
14792 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070014793 __func__);
14794 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
14795 break;
14796
14797 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053014798 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053014799#ifdef WLAN_FEATURE_VOWIFI_11R
14800 case WLAN_AKM_SUITE_FT_8021X:
14801#endif
14802 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070014803 __func__);
14804 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
14805 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080014806#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070014807#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
14808#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
14809 case WLAN_AKM_SUITE_CCKM:
14810 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
14811 __func__);
14812 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
14813 break;
14814#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070014815#ifndef WLAN_AKM_SUITE_OSEN
14816#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
14817 case WLAN_AKM_SUITE_OSEN:
14818 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
14819 __func__);
14820 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
14821 break;
14822#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014823
14824 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014825 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014826 __func__, key_mgmt);
14827 return -EINVAL;
14828
14829 }
14830 return 0;
14831}
14832
14833/*
14834 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014835 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070014836 * (NONE/WEP40/WEP104/TKIP/CCMP).
14837 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014838static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
14839 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070014840 bool ucast
14841 )
14842{
14843 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014844 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014845 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14846
14847 ENTER();
14848
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014849 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070014850 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053014851 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070014852 __func__, cipher);
14853 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
14854 }
14855 else
14856 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014857
Jeff Johnson295189b2012-06-20 16:38:30 -070014858 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014859 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070014860 {
14861 case IW_AUTH_CIPHER_NONE:
14862 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
14863 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014864
Jeff Johnson295189b2012-06-20 16:38:30 -070014865 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053014866 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070014867 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014868
Jeff Johnson295189b2012-06-20 16:38:30 -070014869 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053014870 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070014871 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014872
Jeff Johnson295189b2012-06-20 16:38:30 -070014873 case WLAN_CIPHER_SUITE_TKIP:
14874 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
14875 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014876
Jeff Johnson295189b2012-06-20 16:38:30 -070014877 case WLAN_CIPHER_SUITE_CCMP:
14878 encryptionType = eCSR_ENCRYPT_TYPE_AES;
14879 break;
14880#ifdef FEATURE_WLAN_WAPI
14881 case WLAN_CIPHER_SUITE_SMS4:
14882 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
14883 break;
14884#endif
14885
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080014886#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070014887 case WLAN_CIPHER_SUITE_KRK:
14888 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
14889 break;
14890#endif
14891 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014892 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014893 __func__, cipher);
14894 return -EOPNOTSUPP;
14895 }
14896 }
14897
14898 if (ucast)
14899 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014900 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014901 __func__, encryptionType);
14902 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
14903 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014904 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070014905 encryptionType;
14906 }
14907 else
14908 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014909 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014910 __func__, encryptionType);
14911 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
14912 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
14913 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
14914 }
14915
14916 return 0;
14917}
14918
14919
14920/*
14921 * FUNCTION: wlan_hdd_cfg80211_set_ie
14922 * This function is used to parse WPA/RSN IE's.
14923 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014924int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014925#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14926 const u8 *ie,
14927#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014928 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014929#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014930 size_t ie_len
14931 )
14932{
14933 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014934#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14935 const u8 *genie = ie;
14936#else
Jeff Johnson295189b2012-06-20 16:38:30 -070014937 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014938#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014939 v_U16_t remLen = ie_len;
14940#ifdef FEATURE_WLAN_WAPI
14941 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
14942 u16 *tmp;
14943 v_U16_t akmsuiteCount;
14944 int *akmlist;
14945#endif
14946 ENTER();
14947
14948 /* clear previous assocAddIE */
14949 pWextState->assocAddIE.length = 0;
14950 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070014951 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014952
14953 while (remLen >= 2)
14954 {
14955 v_U16_t eLen = 0;
14956 v_U8_t elementId;
14957 elementId = *genie++;
14958 eLen = *genie++;
14959 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014960
Nachiket Kukade4aba5f02017-06-09 15:43:48 +053014961 /* Sanity check on eLen */
14962 if (eLen > remLen) {
14963 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid IE length[%d] for IE[0x%X]",
14964 __func__, eLen, elementId);
14965 VOS_ASSERT(0);
14966 return -EINVAL;
14967 }
14968
Arif Hussain6d2a3322013-11-17 19:50:10 -080014969 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070014970 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014971
14972 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070014973 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014974 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014975 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 -070014976 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014977 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014978 "%s: Invalid WPA IE", __func__);
14979 return -EINVAL;
14980 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014981 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070014982 {
14983 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014984 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070014985 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014986
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014987 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070014988 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014989 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
14990 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070014991 VOS_ASSERT(0);
14992 return -ENOMEM;
14993 }
14994 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
14995 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14996 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014997
Jeff Johnson295189b2012-06-20 16:38:30 -070014998 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
14999 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15000 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15001 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015002 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
15003 {
Nachiket Kukade3d72b7e2017-06-09 16:58:24 +053015004 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
15005 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d]",
15006 __func__, eLen);
15007 VOS_ASSERT(0);
15008 return -EINVAL;
15009 }
15010
Jeff Johnson295189b2012-06-20 16:38:30 -070015011 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
15012 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
15013 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
15014 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
15015 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
15016 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015017 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053015018 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070015019 {
15020 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015021 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070015022 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015023
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015024 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015025 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015026 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15027 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070015028 VOS_ASSERT(0);
15029 return -ENOMEM;
15030 }
15031 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
15032 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15033 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015034
Jeff Johnson295189b2012-06-20 16:38:30 -070015035 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15036 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15037 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015038#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015039 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
15040 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015041 /*Consider WFD IE, only for P2P Client */
15042 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
15043 {
15044 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015045 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070015046 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015047
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015048 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015049 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015050 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15051 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070015052 VOS_ASSERT(0);
15053 return -ENOMEM;
15054 }
15055 // WFD IE is saved to Additional IE ; it should be accumulated to handle
15056 // WPS IE + P2P IE + WFD IE
15057 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15058 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015059
Jeff Johnson295189b2012-06-20 16:38:30 -070015060 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15061 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15062 }
15063#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015064 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015065 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015066 HS20_OUI_TYPE_SIZE)) )
15067 {
15068 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015069 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015070 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015071
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015072 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015073 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015074 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15075 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015076 VOS_ASSERT(0);
15077 return -ENOMEM;
15078 }
15079 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15080 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015081
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015082 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15083 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15084 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070015085 /* Appending OSEN Information Element in Assiciation Request */
15086 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
15087 OSEN_OUI_TYPE_SIZE)) )
15088 {
15089 v_U16_t curAddIELen = pWextState->assocAddIE.length;
15090 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
15091 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015092
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015093 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070015094 {
15095 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15096 "Need bigger buffer space");
15097 VOS_ASSERT(0);
15098 return -ENOMEM;
15099 }
15100 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15101 pWextState->assocAddIE.length += eLen + 2;
15102
15103 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
15104 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15105 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15106 }
15107
Abhishek Singh4322e622015-06-10 15:42:54 +053015108 /* Update only for WPA IE */
15109 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
15110 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070015111
15112 /* populating as ADDIE in beacon frames */
15113 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015114 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070015115 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
15116 {
15117 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
15118 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
15119 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
15120 {
15121 hddLog(LOGE,
15122 "Coldn't pass "
15123 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
15124 }
15125 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
15126 else
15127 hddLog(LOGE,
15128 "Could not pass on "
15129 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
15130
15131 /* IBSS mode doesn't contain params->proberesp_ies still
15132 beaconIE's need to be populated in probe response frames */
15133 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
15134 {
15135 u16 rem_probe_resp_ie_len = eLen + 2;
15136 u8 probe_rsp_ie_len[3] = {0};
15137 u8 counter = 0;
15138
15139 /* Check Probe Resp Length if it is greater then 255 then
15140 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
15141 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
15142 not able Store More then 255 bytes into One Variable */
15143
15144 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
15145 {
15146 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
15147 {
15148 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
15149 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
15150 }
15151 else
15152 {
15153 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
15154 rem_probe_resp_ie_len = 0;
15155 }
15156 }
15157
15158 rem_probe_resp_ie_len = 0;
15159
15160 if (probe_rsp_ie_len[0] > 0)
15161 {
15162 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
15163 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
15164 (tANI_U8*)(genie - 2),
15165 probe_rsp_ie_len[0], NULL,
15166 eANI_BOOLEAN_FALSE)
15167 == eHAL_STATUS_FAILURE)
15168 {
15169 hddLog(LOGE,
15170 "Could not pass"
15171 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
15172 }
15173 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
15174 }
15175
15176 if (probe_rsp_ie_len[1] > 0)
15177 {
15178 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
15179 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
15180 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
15181 probe_rsp_ie_len[1], NULL,
15182 eANI_BOOLEAN_FALSE)
15183 == eHAL_STATUS_FAILURE)
15184 {
15185 hddLog(LOGE,
15186 "Could not pass"
15187 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
15188 }
15189 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
15190 }
15191
15192 if (probe_rsp_ie_len[2] > 0)
15193 {
15194 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
15195 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
15196 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
15197 probe_rsp_ie_len[2], NULL,
15198 eANI_BOOLEAN_FALSE)
15199 == eHAL_STATUS_FAILURE)
15200 {
15201 hddLog(LOGE,
15202 "Could not pass"
15203 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
15204 }
15205 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
15206 }
15207
15208 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
15209 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
15210 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
15211 {
15212 hddLog(LOGE,
15213 "Could not pass"
15214 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
15215 }
15216 }
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070015217 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070015218 break;
15219 case DOT11F_EID_RSN:
15220 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
15221 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
15222 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
15223 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
15224 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
15225 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053015226
Abhishek Singhb16f3562016-01-20 11:08:32 +053015227 /* Appending extended capabilities with Interworking or
15228 * bsstransition bit set in Assoc Req.
Abhishek Singh15d95602015-03-24 15:52:57 +053015229 *
15230 * In assoc req this EXT Cap will only be taken into account if
Abhishek Singhb16f3562016-01-20 11:08:32 +053015231 * interworkingService or bsstransition bit is set to 1.
15232 * Driver is only interested in interworkingService and
15233 * bsstransition capability from supplicant.
15234 * If in future any other EXT Cap info is
Abhishek Singh15d95602015-03-24 15:52:57 +053015235 * required from supplicat, it needs to be handled while
15236 * sending Assoc Req in LIM.
15237 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015238 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015239 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015240 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015241 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015242 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015243
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015244 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015245 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015246 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15247 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015248 VOS_ASSERT(0);
15249 return -ENOMEM;
15250 }
15251 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15252 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015253
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015254 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15255 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15256 break;
15257 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015258#ifdef FEATURE_WLAN_WAPI
15259 case WLAN_EID_WAPI:
15260 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070015261 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070015262 pAdapter->wapi_info.nWapiMode);
15263 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015264 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070015265 akmsuiteCount = WPA_GET_LE16(tmp);
15266 tmp = tmp + 1;
15267 akmlist = (int *)(tmp);
15268 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
15269 {
15270 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
15271 }
15272 else
15273 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015274 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070015275 VOS_ASSERT(0);
15276 return -EINVAL;
15277 }
15278
15279 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
15280 {
15281 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015282 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015283 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015284 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015285 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015286 {
Jeff Johnson295189b2012-06-20 16:38:30 -070015287 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015288 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015289 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
15290 }
15291 break;
15292#endif
15293 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015294 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015295 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015296 /* when Unknown IE is received we should break and continue
15297 * to the next IE in the buffer instead we were returning
15298 * so changing this to break */
15299 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070015300 }
15301 genie += eLen;
15302 remLen -= eLen;
15303 }
15304 EXIT();
15305 return 0;
15306}
15307
15308/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053015309 * FUNCTION: hdd_isWPAIEPresent
15310 * Parse the received IE to find the WPA IE
15311 *
15312 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015313static bool hdd_isWPAIEPresent(
15314#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
15315 const u8 *ie,
15316#else
15317 u8 *ie,
15318#endif
15319 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053015320{
15321 v_U8_t eLen = 0;
15322 v_U16_t remLen = ie_len;
15323 v_U8_t elementId = 0;
15324
15325 while (remLen >= 2)
15326 {
15327 elementId = *ie++;
15328 eLen = *ie++;
15329 remLen -= 2;
15330 if (eLen > remLen)
15331 {
15332 hddLog(VOS_TRACE_LEVEL_ERROR,
15333 "%s: IE length is wrong %d", __func__, eLen);
15334 return FALSE;
15335 }
15336 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
15337 {
15338 /* OUI - 0x00 0X50 0XF2
15339 WPA Information Element - 0x01
15340 WPA version - 0x01*/
15341 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
15342 return TRUE;
15343 }
15344 ie += eLen;
15345 remLen -= eLen;
15346 }
15347 return FALSE;
15348}
15349
15350/*
Jeff Johnson295189b2012-06-20 16:38:30 -070015351 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015352 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070015353 * parameters during connect operation.
15354 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015355int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070015356 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015357 )
Jeff Johnson295189b2012-06-20 16:38:30 -070015358{
15359 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015360 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070015361 ENTER();
15362
15363 /*set wpa version*/
15364 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
15365
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015366 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070015367 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053015368 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070015369 {
15370 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
15371 }
15372 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
15373 {
15374 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
15375 }
15376 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015377
15378 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015379 pWextState->wpaVersion);
15380
15381 /*set authentication type*/
15382 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
15383
15384 if (0 > status)
15385 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015386 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015387 "%s: failed to set authentication type ", __func__);
15388 return status;
15389 }
15390
15391 /*set key mgmt type*/
15392 if (req->crypto.n_akm_suites)
15393 {
15394 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
15395 if (0 > status)
15396 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015397 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070015398 __func__);
15399 return status;
15400 }
15401 }
15402
15403 /*set pairwise cipher type*/
15404 if (req->crypto.n_ciphers_pairwise)
15405 {
15406 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
15407 req->crypto.ciphers_pairwise[0], true);
15408 if (0 > status)
15409 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015410 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015411 "%s: failed to set unicast cipher type", __func__);
15412 return status;
15413 }
15414 }
15415 else
15416 {
15417 /*Reset previous cipher suite to none*/
15418 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
15419 if (0 > status)
15420 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015421 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015422 "%s: failed to set unicast cipher type", __func__);
15423 return status;
15424 }
15425 }
15426
15427 /*set group cipher type*/
15428 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
15429 false);
15430
15431 if (0 > status)
15432 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015433 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070015434 __func__);
15435 return status;
15436 }
15437
Chet Lanctot186b5732013-03-18 10:26:30 -070015438#ifdef WLAN_FEATURE_11W
15439 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
15440#endif
15441
Jeff Johnson295189b2012-06-20 16:38:30 -070015442 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
15443 if (req->ie_len)
15444 {
15445 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
15446 if ( 0 > status)
15447 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015448 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070015449 __func__);
15450 return status;
15451 }
15452 }
15453
15454 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015455 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070015456 {
15457 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
15458 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
15459 )
15460 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015461 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070015462 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
15463 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015464 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070015465 __func__);
15466 return -EOPNOTSUPP;
15467 }
15468 else
15469 {
15470 u8 key_len = req->key_len;
15471 u8 key_idx = req->key_idx;
15472
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015473 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070015474 && (CSR_MAX_NUM_KEY > key_idx)
15475 )
15476 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015477 hddLog(VOS_TRACE_LEVEL_INFO,
15478 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015479 __func__, key_idx, key_len);
15480 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015481 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070015482 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015483 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070015484 (u8)key_len;
15485 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
15486 }
15487 }
15488 }
15489 }
15490
15491 return status;
15492}
15493
15494/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015495 * FUNCTION: wlan_hdd_try_disconnect
15496 * This function is used to disconnect from previous
15497 * connection
15498 */
Agrawal Ashishc407f192017-01-23 17:18:35 +053015499int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015500{
15501 long ret = 0;
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015502 int status, result = 0;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015503 hdd_station_ctx_t *pHddStaCtx;
15504 eMib_dot11DesiredBssType connectedBssType;
Abhishek Singh19a7dd92015-12-30 16:31:51 +053015505 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015506
Abhishek Singh19a7dd92015-12-30 16:31:51 +053015507 ret = wlan_hdd_validate_context(pHddCtx);
15508 if (0 != ret)
15509 {
15510 return ret;
15511 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015512 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15513
15514 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
15515
15516 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
15517 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
Abhishek Singh630ff592016-01-07 18:15:53 +053015518 (eConnectionState_Connecting == pHddStaCtx->conn_info.connState) ||
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015519 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
15520 {
Abhishek Singh9f4df782017-03-15 17:29:10 +053015521 /* Indicate disconnect to SME so that in-progress connection or preauth
15522 * can be aborted
15523 */
15524 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
15525 pAdapter->sessionId);
Abhishek Singh19a7dd92015-12-30 16:31:51 +053015526 spin_lock_bh(&pAdapter->lock_for_active_session);
15527 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
15528 {
15529 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
15530 }
15531 spin_unlock_bh(&pAdapter->lock_for_active_session);
Abhishek Singhf7962582015-10-23 10:54:06 +053015532 hdd_connSetConnectionState(pHddStaCtx,
15533 eConnectionState_Disconnecting);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015534 /* Issue disconnect to CSR */
15535 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015536 status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015537 pAdapter->sessionId,
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015538 eCSR_DISCONNECT_REASON_UNSPECIFIED);
15539 if(eHAL_STATUS_CMD_NOT_QUEUED == status) {
15540 hddLog(LOG1,
15541 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
15542 } else if ( 0 != status ) {
15543 hddLog(LOGE,
15544 FL("csrRoamDisconnect failure, returned %d"),
15545 (int)status );
15546 result = -EINVAL;
15547 goto disconnected;
15548 }
15549 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015550 &pAdapter->disconnect_comp_var,
15551 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015552 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status)) {
15553 hddLog(LOGE,
15554 "%s: Failed to disconnect, timed out", __func__);
15555 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015556 }
15557 }
15558 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
15559 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015560 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015561 &pAdapter->disconnect_comp_var,
15562 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015563 if (!ret)
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015564 {
15565 hddLog(LOGE, FL("Failed to receive disconnect event"));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015566 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015567 }
15568 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015569disconnected:
15570 hddLog(LOG1,
15571 FL("Set HDD connState to eConnectionState_NotConnected"));
15572 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
15573 return result;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015574}
15575
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053015576/**
15577 * wlan_hdd_reassoc_bssid_hint() - Start reassociation if bssid is present
15578 * @adapter: Pointer to the HDD adapter
15579 * @req: Pointer to the structure cfg_connect_params receieved from user space
15580 *
15581 * This function will start reassociation if bssid hint, channel hint and
15582 * previous bssid parameters are present in the connect request
15583 *
15584 * Return: success if reassociation is happening
15585 * Error code if reassociation is not permitted or not happening
15586 */
15587#ifdef CFG80211_CONNECT_PREV_BSSID
15588static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
15589 struct cfg80211_connect_params *req)
15590{
15591 int status = -EPERM;
15592 if (req->bssid_hint && req->channel_hint && req->prev_bssid) {
15593 hddLog(VOS_TRACE_LEVEL_INFO,
15594 FL("REASSOC Attempt on channel %d to "MAC_ADDRESS_STR),
15595 req->channel_hint->hw_value,
15596 MAC_ADDR_ARRAY(req->bssid_hint));
15597 status = hdd_reassoc(adapter, req->bssid_hint,
15598 req->channel_hint->hw_value,
15599 CONNECT_CMD_USERSPACE);
15600 }
15601 return status;
15602}
15603#else
15604static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
15605 struct cfg80211_connect_params *req)
15606{
15607 return -EPERM;
15608}
15609#endif
15610
Abhishek Singhe3beee22017-07-31 15:35:40 +053015611/**
15612 * wlan_hdd_check_ht20_ht40_ind() - check if Supplicant has indicated to
15613 * connect in HT20 mode
15614 * @hdd_ctx: hdd context
15615 * @adapter: Pointer to the HDD adapter
15616 * @req: Pointer to the structure cfg_connect_params receieved from user space
15617 *
15618 * This function will check if supplicant has indicated to to connect in HT20
15619 * mode. this is currently applicable only for 2.4Ghz mode only.
15620 * if feature is enabled and supplicant indicate HT20 set
15621 * force_24ghz_in_ht20 to true to force 2.4Ghz in HT20 else set it to false.
15622 *
15623 * Return: void
15624 */
15625#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
15626static void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
15627 hdd_adapter_t *adapter,
15628 struct cfg80211_connect_params *req)
15629{
15630 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
15631 tCsrRoamProfile *roam_profile;
15632
15633 roam_profile = &wext_state->roamProfile;
15634 roam_profile->force_24ghz_in_ht20 = false;
15635 if (hdd_ctx->cfg_ini->override_ht20_40_24g &&
15636 !(req->ht_capa.cap_info &
15637 IEEE80211_HT_CAP_SUP_WIDTH_20_40))
15638 roam_profile->force_24ghz_in_ht20 = true;
15639
15640 hddLog(LOG1, FL("req->ht_capa.cap_info %x override_ht20_40_24g %d"),
15641 req->ht_capa.cap_info, hdd_ctx->cfg_ini->override_ht20_40_24g);
15642}
15643#else
15644static inline void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
15645 hdd_adapter_t *adapter,
15646 struct cfg80211_connect_params *req)
15647{
15648 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
15649 tCsrRoamProfile *roam_profile;
15650
15651 roam_profile = &wext_state->roamProfile;
15652 roam_profile->force_24ghz_in_ht20 = false;
15653}
15654#endif
15655
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015656/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053015657 * FUNCTION: __wlan_hdd_cfg80211_connect
15658 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070015659 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015660static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015661 struct net_device *ndev,
15662 struct cfg80211_connect_params *req
15663 )
15664{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015665 int status;
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053015666 u16 channel;
Edhar, Mahesh Kumar496c7f72016-03-18 12:47:44 +053015667#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) || \
15668 defined(CFG80211_BSSID_HINT_BACKPORT)
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053015669 const u8 *bssid_hint = req->bssid_hint;
15670#else
15671 const u8 *bssid_hint = NULL;
15672#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015673 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070015674 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053015675 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015676
15677 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015678
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015679 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15680 TRACE_CODE_HDD_CFG80211_CONNECT,
15681 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015682 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015683 "%s: device_mode = %s (%d)", __func__,
15684 hdd_device_modetoString(pAdapter->device_mode),
15685 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015686
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015687 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080015688 if (!pHddCtx)
15689 {
15690 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15691 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053015692 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080015693 }
15694
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015695 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015696 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070015697 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015698 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015699 }
15700
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053015701 status = wlan_hdd_reassoc_bssid_hint(pAdapter, req);
15702 if (0 == status)
15703 return status;
15704
Agarwal Ashish51325b52014-06-16 16:50:49 +053015705
Jeff Johnson295189b2012-06-20 16:38:30 -070015706#ifdef WLAN_BTAMP_FEATURE
15707 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015708 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070015709 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015710 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015711 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080015712 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070015713 }
15714#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015715
15716 //If Device Mode is Station Concurrent Sessions Exit BMps
15717 //P2P Mode will be taken care in Open/close adapter
15718 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053015719 (vos_concurrent_open_sessions_running())) {
15720 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
15721 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015722 }
15723
15724 /*Try disconnecting if already in connected state*/
15725 status = wlan_hdd_try_disconnect(pAdapter);
15726 if ( 0 > status)
15727 {
15728 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
15729 " connection"));
15730 return -EALREADY;
15731 }
Agrawal Ashish559530c2015-12-01 18:04:20 +053015732 /* Check for max concurrent connections after doing disconnect if any*/
15733 if (vos_max_concurrent_connections_reached()) {
15734 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
15735 return -ECONNREFUSED;
15736 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015737
Jeff Johnson295189b2012-06-20 16:38:30 -070015738 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015739 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070015740
15741 if ( 0 > status)
15742 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015743 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070015744 __func__);
15745 return status;
15746 }
Sravan Kumar Kairam589c5722016-01-27 20:28:53 +053015747
15748 if (pHddCtx->spoofMacAddr.isEnabled)
15749 {
15750 hddLog(VOS_TRACE_LEVEL_INFO,
15751 "%s: MAC Spoofing enabled ", __func__);
15752 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
15753 * to fill TxBds for probe request during SSID scan which may happen
15754 * as part of connect command
15755 */
15756 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
15757 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
15758 if (status != VOS_STATUS_SUCCESS)
15759 return -ECONNREFUSED;
15760 }
15761
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053015762 if (req->channel)
15763 channel = req->channel->hw_value;
Mohit Khanna765234a2012-09-11 15:08:35 -070015764 else
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053015765 channel = 0;
Kapil Gupta312028a2016-10-25 14:15:20 +053015766
15767 /* Abort if any scan is going on */
15768 status = wlan_hdd_scan_abort(pAdapter);
15769 if (0 != status)
15770 hddLog(VOS_TRACE_LEVEL_ERROR, FL("scan abort failed"));
15771
Abhishek Singhe3beee22017-07-31 15:35:40 +053015772 wlan_hdd_check_ht20_ht40_ind(pHddCtx, pAdapter, req);
15773
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053015774 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
15775 req->ssid_len, req->bssid,
15776 bssid_hint, channel);
Jeff Johnson295189b2012-06-20 16:38:30 -070015777
Sushant Kaushikd7083982015-03-18 14:33:24 +053015778 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070015779 {
15780 //ReEnable BMPS if disabled
15781 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
15782 (NULL != pHddCtx))
15783 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053015784 if (pHddCtx->hdd_wlan_suspended)
15785 {
15786 hdd_set_pwrparams(pHddCtx);
15787 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015788 //ReEnable Bmps and Imps back
15789 hdd_enable_bmps_imps(pHddCtx);
15790 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053015791 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070015792 return status;
15793 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015794 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015795 EXIT();
15796 return status;
15797}
15798
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015799static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
15800 struct net_device *ndev,
15801 struct cfg80211_connect_params *req)
15802{
15803 int ret;
15804 vos_ssr_protect(__func__);
15805 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
15806 vos_ssr_unprotect(__func__);
15807
15808 return ret;
15809}
Jeff Johnson295189b2012-06-20 16:38:30 -070015810
15811/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015812 * FUNCTION: wlan_hdd_disconnect
15813 * This function is used to issue a disconnect request to SME
15814 */
15815int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
15816{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015817 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015818 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015819 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053015820 long ret;
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053015821 eConnectionState prev_conn_state;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015822
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015823 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015824
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015825 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015826 if (0 != status)
15827 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015828 return status;
15829 }
Abhishek Singh07e4a892015-11-23 11:29:57 +053015830 /* Indicate sme of disconnect so that in progress connection or preauth
15831 * can be aborted
15832 */
15833 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
Sushant Kaushikb4834d22015-07-15 15:29:05 +053015834 pAdapter->sessionId);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015835 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053015836
Agarwal Ashish47d18112014-08-04 19:55:07 +053015837 /* Need to apply spin lock before decreasing active sessions
15838 * as there can be chance for double decrement if context switch
15839 * Calls hdd_DisConnectHandler.
15840 */
15841
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053015842 prev_conn_state = pHddStaCtx->conn_info.connState;
15843
Agarwal Ashish47d18112014-08-04 19:55:07 +053015844 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053015845 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
15846 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053015847 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
15848 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053015849 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
15850 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053015851
Abhishek Singhf4669da2014-05-26 15:07:49 +053015852 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053015853 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
15854
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015855 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015856
Mihir Shete182a0b22014-08-18 16:08:48 +053015857 /*
15858 * stop tx queues before deleting STA/BSS context from the firmware.
15859 * tx has to be disabled because the firmware can get busy dropping
15860 * the tx frames after BSS/STA has been deleted and will not send
15861 * back a response resulting in WDI timeout
15862 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053015863 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053015864 netif_tx_disable(pAdapter->dev);
15865 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015866
Mihir Shete182a0b22014-08-18 16:08:48 +053015867 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015868 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
15869 pAdapter->sessionId, reason);
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053015870 if((eHAL_STATUS_CMD_NOT_QUEUED == status) &&
15871 prev_conn_state != eConnectionState_Connecting)
15872 {
15873 hddLog(LOG1,
15874 FL("status = %d, already disconnected"), status);
15875 result = 0;
15876 goto disconnected;
15877 }
15878 /*
15879 * Wait here instead of returning directly, this will block the next
15880 * connect command and allow processing of the scan for ssid and
15881 * the previous connect command in CSR. Else we might hit some
15882 * race conditions leading to SME and HDD out of sync.
15883 */
15884 else if(eHAL_STATUS_CMD_NOT_QUEUED == status)
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015885 {
15886 hddLog(LOG1,
15887 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053015888 }
15889 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015890 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015891 hddLog(LOGE,
15892 FL("csrRoamDisconnect failure, returned %d"),
15893 (int)status);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015894 result = -EINVAL;
15895 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015896 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015897 ret = wait_for_completion_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015898 &pAdapter->disconnect_comp_var,
15899 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015900 if (!ret && (eHAL_STATUS_CMD_NOT_QUEUED != status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015901 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015902 hddLog(LOGE,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053015903 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015904 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053015905 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015906disconnected:
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015907 hddLog(LOG1,
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053015908 FL("Set HDD connState to eConnectionState_NotConnected"));
15909 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Mahesh A Saptasagar936ffc32016-05-25 11:27:43 +053015910#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
15911 /* Sending disconnect event to userspace for kernel version < 3.11
15912 * is handled by __cfg80211_disconnect call to __cfg80211_disconnected
15913 */
15914 hddLog(LOG1, FL("Send disconnected event to userspace"));
15915
Mahesh A Saptasagarf5859b12016-06-01 17:17:50 +053015916 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, true,
Mahesh A Saptasagar936ffc32016-05-25 11:27:43 +053015917 WLAN_REASON_UNSPECIFIED);
15918#endif
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053015919
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015920 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015921 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015922}
15923
15924
15925/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015926 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070015927 * This function is used to issue a disconnect request to SME
15928 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015929static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015930 struct net_device *dev,
15931 u16 reason
15932 )
15933{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015934 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015935 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053015936 tCsrRoamProfile *pRoamProfile;
15937 hdd_station_ctx_t *pHddStaCtx;
15938 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015939#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015940 tANI_U8 staIdx;
15941#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015942
Jeff Johnson295189b2012-06-20 16:38:30 -070015943 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015944
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053015945 if (!pAdapter) {
15946 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
15947 return -EINVAL;
15948 }
15949
15950 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15951 if (!pHddStaCtx) {
15952 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
15953 return -EINVAL;
15954 }
15955
15956 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15957 status = wlan_hdd_validate_context(pHddCtx);
15958 if (0 != status)
15959 {
15960 return status;
15961 }
15962
15963 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
15964
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015965 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15966 TRACE_CODE_HDD_CFG80211_DISCONNECT,
15967 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015968 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
15969 __func__, hdd_device_modetoString(pAdapter->device_mode),
15970 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015971
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015972 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
15973 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070015974
Jeff Johnson295189b2012-06-20 16:38:30 -070015975 if (NULL != pRoamProfile)
15976 {
15977 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053015978 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
15979 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070015980 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015981 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070015982 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015983 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070015984 switch(reason)
15985 {
15986 case WLAN_REASON_MIC_FAILURE:
15987 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
15988 break;
15989
15990 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
15991 case WLAN_REASON_DISASSOC_AP_BUSY:
15992 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
15993 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
15994 break;
15995
15996 case WLAN_REASON_PREV_AUTH_NOT_VALID:
15997 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053015998 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070015999 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
16000 break;
16001
Jeff Johnson295189b2012-06-20 16:38:30 -070016002 default:
16003 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
16004 break;
16005 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053016006 pScanInfo = &pHddCtx->scan_info;
16007 if (pScanInfo->mScanPending)
16008 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053016009 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053016010 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053016011 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053016012 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053016013 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053016014 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016015#ifdef FEATURE_WLAN_TDLS
16016 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080016017 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016018 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080016019 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
16020 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016021 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016022 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080016023 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053016024 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016025 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080016026 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016027 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016028 status = sme_DeleteTdlsPeerSta(
16029 WLAN_HDD_GET_HAL_CTX(pAdapter),
16030 pAdapter->sessionId,
16031 mac);
16032 if (status != eHAL_STATUS_SUCCESS) {
16033 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
16034 return -EPERM;
16035 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016036 }
16037 }
16038#endif
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053016039
16040 hddLog(LOG1, FL("Disconnecting with reasoncode:%u connState %d"),
16041 reasonCode,
16042 pHddStaCtx->conn_info.connState);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016043 status = wlan_hdd_disconnect(pAdapter, reasonCode);
16044 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070016045 {
16046 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080016047 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016048 __func__, (int)status );
16049 return -EINVAL;
16050 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016051 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053016052 else
16053 {
16054 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
16055 "called while in %d state", __func__,
16056 pHddStaCtx->conn_info.connState);
16057 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016058 }
16059 else
16060 {
16061 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
16062 }
16063
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016064 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016065 return status;
16066}
16067
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016068static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
16069 struct net_device *dev,
16070 u16 reason
16071 )
16072{
16073 int ret;
16074 vos_ssr_protect(__func__);
16075 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
16076 vos_ssr_unprotect(__func__);
16077
16078 return ret;
16079}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016080
Jeff Johnson295189b2012-06-20 16:38:30 -070016081/*
16082 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016083 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070016084 * settings in IBSS mode.
16085 */
16086static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016087 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070016088 struct cfg80211_ibss_params *params
16089 )
16090{
16091 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016092 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016093 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
16094 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016095
Jeff Johnson295189b2012-06-20 16:38:30 -070016096 ENTER();
16097
16098 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070016099 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070016100
16101 if (params->ie_len && ( NULL != params->ie) )
16102 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016103 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
16104 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070016105 {
16106 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
16107 encryptionType = eCSR_ENCRYPT_TYPE_AES;
16108 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016109 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070016110 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070016111 tDot11fIEWPA dot11WPAIE;
16112 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016113 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070016114
Wilson Yang00256342013-10-10 23:13:38 -070016115 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016116 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
16117 params->ie_len, DOT11F_EID_WPA);
16118 if ( NULL != ie )
16119 {
16120 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
16121 // Unpack the WPA IE
16122 //Skip past the EID byte and length byte - and four byte WiFi OUI
16123 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
16124 &ie[2+4],
16125 ie[1] - 4,
16126 &dot11WPAIE);
16127 /*Extract the multicast cipher, the encType for unicast
16128 cipher for wpa-none is none*/
16129 encryptionType =
16130 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
16131 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016132 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016133
Jeff Johnson295189b2012-06-20 16:38:30 -070016134 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
16135
16136 if (0 > status)
16137 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016138 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070016139 __func__);
16140 return status;
16141 }
16142 }
16143
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016144 pWextState->roamProfile.AuthType.authType[0] =
16145 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070016146 eCSR_AUTH_TYPE_OPEN_SYSTEM;
16147
16148 if (params->privacy)
16149 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016150 /* Security enabled IBSS, At this time there is no information available
16151 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070016152 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016153 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070016154 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016155 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070016156 *enable privacy bit in beacons */
16157
16158 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
16159 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070016160 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
16161 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070016162 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
16163 pWextState->roamProfile.EncryptionType.numEntries = 1;
16164 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070016165 return status;
16166}
16167
16168/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016169 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016170 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070016171 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016172static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016173 struct net_device *dev,
16174 struct cfg80211_ibss_params *params
16175 )
16176{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016177 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070016178 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
16179 tCsrRoamProfile *pRoamProfile;
16180 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016181 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16182 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016183 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070016184
16185 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016186
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016187 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16188 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
16189 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016190 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016191 "%s: device_mode = %s (%d)", __func__,
16192 hdd_device_modetoString(pAdapter->device_mode),
16193 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070016194
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016195 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016196 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070016197 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016198 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016199 }
16200
16201 if (NULL == pWextState)
16202 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016203 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070016204 __func__);
16205 return -EIO;
16206 }
16207
Agarwal Ashish51325b52014-06-16 16:50:49 +053016208 if (vos_max_concurrent_connections_reached()) {
16209 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
16210 return -ECONNREFUSED;
16211 }
16212
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016213 /*Try disconnecting if already in connected state*/
16214 status = wlan_hdd_try_disconnect(pAdapter);
16215 if ( 0 > status)
16216 {
16217 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
16218 " IBSS connection"));
16219 return -EALREADY;
16220 }
16221
Jeff Johnson295189b2012-06-20 16:38:30 -070016222 pRoamProfile = &pWextState->roamProfile;
16223
16224 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
16225 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016226 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080016227 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016228 return -EINVAL;
16229 }
16230
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070016231 /* BSSID is provided by upper layers hence no need to AUTO generate */
16232 if (NULL != params->bssid) {
16233 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
16234 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
16235 hddLog (VOS_TRACE_LEVEL_ERROR,
16236 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
16237 return -EIO;
16238 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016239 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070016240 }
krunal sonie9002db2013-11-25 14:24:17 -080016241 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
16242 {
16243 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
16244 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
16245 {
16246 hddLog (VOS_TRACE_LEVEL_ERROR,
16247 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
16248 return -EIO;
16249 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016250
16251 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080016252 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016253 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080016254 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070016255
Jeff Johnson295189b2012-06-20 16:38:30 -070016256 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070016257 if (NULL !=
16258#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
16259 params->chandef.chan)
16260#else
16261 params->channel)
16262#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016263 {
16264 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016265 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
16266 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
16267 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
16268 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070016269
16270 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016271 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070016272 ieee80211_frequency_to_channel(
16273#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
16274 params->chandef.chan->center_freq);
16275#else
16276 params->channel->center_freq);
16277#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016278
16279 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
16280 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070016281 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016282 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
16283 __func__);
16284 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070016285 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016286
16287 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070016288 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016289 if (channelNum == validChan[indx])
16290 {
16291 break;
16292 }
16293 }
16294 if (indx >= numChans)
16295 {
16296 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016297 __func__, channelNum);
16298 return -EINVAL;
16299 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016300 /* Set the Operational Channel */
16301 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
16302 channelNum);
16303 pRoamProfile->ChannelInfo.numOfChannels = 1;
16304 pHddStaCtx->conn_info.operationChannel = channelNum;
16305 pRoamProfile->ChannelInfo.ChannelList =
16306 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070016307 }
16308
16309 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016310 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070016311 if (status < 0)
16312 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016313 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070016314 __func__);
16315 return status;
16316 }
16317
16318 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016319 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Abhishek Singh4d924682015-11-17 15:23:06 +053016320 params->ssid_len, (const u8 *)&bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016321 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070016322
16323 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070016324 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016325
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016326 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016327 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016328}
16329
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016330static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
16331 struct net_device *dev,
16332 struct cfg80211_ibss_params *params
16333 )
16334{
16335 int ret = 0;
16336
16337 vos_ssr_protect(__func__);
16338 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
16339 vos_ssr_unprotect(__func__);
16340
16341 return ret;
16342}
16343
Jeff Johnson295189b2012-06-20 16:38:30 -070016344/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016345 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016346 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070016347 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016348static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016349 struct net_device *dev
16350 )
16351{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016352 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016353 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
16354 tCsrRoamProfile *pRoamProfile;
16355 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016356 int status;
Abhishek Singh69de3302016-11-11 16:44:32 +053016357 eHalStatus hal_status;
Abhishek Singh7cd040e2016-01-07 10:51:04 +053016358#ifdef WLAN_FEATURE_RMC
16359 tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN] = {0};
16360#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016361
16362 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016363
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016364 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16365 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
16366 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016367 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016368 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016369 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016370 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016371 }
16372
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016373 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
16374 hdd_device_modetoString(pAdapter->device_mode),
16375 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070016376 if (NULL == pWextState)
16377 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016378 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070016379 __func__);
16380 return -EIO;
16381 }
16382
16383 pRoamProfile = &pWextState->roamProfile;
16384
16385 /* Issue disconnect only if interface type is set to IBSS */
16386 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
16387 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016388 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070016389 __func__);
16390 return -EINVAL;
16391 }
16392
Abhishek Singh7cd040e2016-01-07 10:51:04 +053016393#ifdef WLAN_FEATURE_RMC
16394 /* Clearing add IE of beacon */
16395 if (ccmCfgSetStr(pHddCtx->hHal,
16396 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0],
16397 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN,
16398 NULL, eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
16399 {
16400 hddLog (VOS_TRACE_LEVEL_ERROR,
16401 "%s: unable to clear PROBE_RSP_BCN_ADDNIE_DATA", __func__);
16402 return -EINVAL;
16403 }
16404 if (ccmCfgSetInt(pHddCtx->hHal,
16405 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0, NULL,
16406 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
16407 {
16408 hddLog (VOS_TRACE_LEVEL_ERROR,
16409 "%s: unable to clear WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
16410 __func__);
16411 return -EINVAL;
16412 }
16413
16414 // Reset WNI_CFG_PROBE_RSP Flags
16415 wlan_hdd_reset_prob_rspies(pAdapter);
16416
16417 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
16418 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 0,NULL,
16419 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
16420 {
16421 hddLog (VOS_TRACE_LEVEL_ERROR,
16422 "%s: unable to clear WNI_CFG_PROBE_RSP_ADDNIE_FLAG",
16423 __func__);
16424 return -EINVAL;
16425 }
16426#endif
16427
Jeff Johnson295189b2012-06-20 16:38:30 -070016428 /* Issue Disconnect request */
16429 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singh69de3302016-11-11 16:44:32 +053016430 hal_status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
16431 pAdapter->sessionId,
16432 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
16433 if (!HAL_STATUS_SUCCESS(hal_status)) {
16434 hddLog(LOGE,
16435 FL("sme_RoamDisconnect failed hal_status(%d)"),
16436 hal_status);
16437 return -EAGAIN;
16438 }
16439 status = wait_for_completion_timeout(
16440 &pAdapter->disconnect_comp_var,
16441 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
16442 if (!status) {
16443 hddLog(LOGE,
16444 FL("wait on disconnect_comp_var failed"));
16445 return -ETIMEDOUT;
16446 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016447
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016448 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016449 return 0;
16450}
16451
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016452static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
16453 struct net_device *dev
16454 )
16455{
16456 int ret = 0;
16457
16458 vos_ssr_protect(__func__);
16459 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
16460 vos_ssr_unprotect(__func__);
16461
16462 return ret;
16463}
16464
Jeff Johnson295189b2012-06-20 16:38:30 -070016465/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016466 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070016467 * This function is used to set the phy parameters
16468 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
16469 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016470static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016471 u32 changed)
16472{
16473 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
16474 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016475 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016476
16477 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016478
16479 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016480 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
16481 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016482
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016483 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016484 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016485 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016486 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016487 }
16488
Jeff Johnson295189b2012-06-20 16:38:30 -070016489 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
16490 {
16491 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
16492 WNI_CFG_RTS_THRESHOLD_STAMAX :
16493 wiphy->rts_threshold;
16494
16495 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016496 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070016497 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016498 hddLog(VOS_TRACE_LEVEL_ERROR,
16499 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016500 __func__, rts_threshold);
16501 return -EINVAL;
16502 }
16503
16504 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
16505 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016506 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016507 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016508 hddLog(VOS_TRACE_LEVEL_ERROR,
16509 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016510 __func__, rts_threshold);
16511 return -EIO;
16512 }
16513
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016514 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016515 rts_threshold);
16516 }
16517
16518 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
16519 {
16520 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
16521 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
16522 wiphy->frag_threshold;
16523
16524 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016525 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016526 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016527 hddLog(VOS_TRACE_LEVEL_ERROR,
16528 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016529 frag_threshold);
16530 return -EINVAL;
16531 }
16532
16533 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
16534 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016535 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016536 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016537 hddLog(VOS_TRACE_LEVEL_ERROR,
16538 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016539 __func__, frag_threshold);
16540 return -EIO;
16541 }
16542
16543 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
16544 frag_threshold);
16545 }
16546
16547 if ((changed & WIPHY_PARAM_RETRY_SHORT)
16548 || (changed & WIPHY_PARAM_RETRY_LONG))
16549 {
16550 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
16551 wiphy->retry_short :
16552 wiphy->retry_long;
16553
16554 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
16555 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
16556 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016557 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016558 __func__, retry_value);
16559 return -EINVAL;
16560 }
16561
16562 if (changed & WIPHY_PARAM_RETRY_SHORT)
16563 {
16564 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
16565 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016566 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016567 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016568 hddLog(VOS_TRACE_LEVEL_ERROR,
16569 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016570 __func__, retry_value);
16571 return -EIO;
16572 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016573 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016574 __func__, retry_value);
16575 }
16576 else if (changed & WIPHY_PARAM_RETRY_SHORT)
16577 {
16578 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
16579 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016580 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016581 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016582 hddLog(VOS_TRACE_LEVEL_ERROR,
16583 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016584 __func__, retry_value);
16585 return -EIO;
16586 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016587 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016588 __func__, retry_value);
16589 }
16590 }
16591
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016592 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016593 return 0;
16594}
16595
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016596static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
16597 u32 changed)
16598{
16599 int ret;
16600
16601 vos_ssr_protect(__func__);
16602 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
16603 vos_ssr_unprotect(__func__);
16604
16605 return ret;
16606}
16607
Jeff Johnson295189b2012-06-20 16:38:30 -070016608/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016609 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070016610 * This function is used to set the txpower
16611 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016612static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070016613#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16614 struct wireless_dev *wdev,
16615#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016616#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016617 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070016618#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016619 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070016620#endif
16621 int dbm)
16622{
16623 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016624 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070016625 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
16626 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016627 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016628
16629 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016630
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016631 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16632 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
16633 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016634 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016635 if (0 != status)
16636 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016637 return status;
16638 }
16639
16640 hHal = pHddCtx->hHal;
16641
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016642 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
16643 dbm, ccmCfgSetCallback,
16644 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016645 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016646 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016647 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
16648 return -EIO;
16649 }
16650
16651 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
16652 dbm);
16653
16654 switch(type)
16655 {
16656 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
16657 /* Fall through */
16658 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
16659 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
16660 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016661 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
16662 __func__);
16663 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070016664 }
16665 break;
16666 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016667 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070016668 __func__);
16669 return -EOPNOTSUPP;
16670 break;
16671 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016672 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
16673 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070016674 return -EIO;
16675 }
16676
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016677 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016678 return 0;
16679}
16680
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016681static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
16682#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16683 struct wireless_dev *wdev,
16684#endif
16685#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
16686 enum tx_power_setting type,
16687#else
16688 enum nl80211_tx_power_setting type,
16689#endif
16690 int dbm)
16691{
16692 int ret;
16693 vos_ssr_protect(__func__);
16694 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
16695#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16696 wdev,
16697#endif
16698#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
16699 type,
16700#else
16701 type,
16702#endif
16703 dbm);
16704 vos_ssr_unprotect(__func__);
16705
16706 return ret;
16707}
16708
Jeff Johnson295189b2012-06-20 16:38:30 -070016709/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016710 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070016711 * This function is used to read the txpower
16712 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016713static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070016714#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16715 struct wireless_dev *wdev,
16716#endif
16717 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070016718{
16719
16720 hdd_adapter_t *pAdapter;
16721 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016722 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016723
Jeff Johnsone7245742012-09-05 17:12:55 -070016724 ENTER();
16725
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016726 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016727 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016728 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016729 *dbm = 0;
16730 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016731 }
16732
Jeff Johnson295189b2012-06-20 16:38:30 -070016733 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
16734 if (NULL == pAdapter)
16735 {
16736 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
16737 return -ENOENT;
16738 }
16739
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016740 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16741 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
16742 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070016743 wlan_hdd_get_classAstats(pAdapter);
16744 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
16745
Jeff Johnsone7245742012-09-05 17:12:55 -070016746 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016747 return 0;
16748}
16749
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016750static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
16751#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16752 struct wireless_dev *wdev,
16753#endif
16754 int *dbm)
16755{
16756 int ret;
16757
16758 vos_ssr_protect(__func__);
16759 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
16760#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16761 wdev,
16762#endif
16763 dbm);
16764 vos_ssr_unprotect(__func__);
16765
16766 return ret;
16767}
16768
Dustin Brown8c1d4092017-07-28 18:08:01 +053016769/*
16770 * wlan_hdd_fill_summary_stats() - populate station_info summary stats
16771 * @stats: summary stats to use as a source
16772 * @info: kernel station_info struct to use as a destination
16773 *
16774 * Return: None
16775 */
16776static void wlan_hdd_fill_summary_stats(tCsrSummaryStatsInfo *stats,
16777 struct station_info *info)
16778{
16779 int i;
16780
16781 info->rx_packets = stats->rx_frm_cnt;
16782 info->tx_packets = 0;
16783 info->tx_retries = 0;
16784 info->tx_failed = 0;
16785
16786 for (i = 0; i < 4; ++i) {
16787 info->tx_packets += stats->tx_frm_cnt[i];
16788 info->tx_retries += stats->multiple_retry_cnt[i];
16789 info->tx_failed += stats->fail_cnt[i];
16790 }
16791
16792 info->filled |= STATION_INFO_TX_PACKETS |
16793 STATION_INFO_TX_RETRIES |
16794 STATION_INFO_TX_FAILED |
16795 STATION_INFO_RX_PACKETS;
16796}
16797
16798/**
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053016799 * wlan_hdd_sap_get_sta_rssi() - get RSSI of the SAP client
16800 * @adapter: sap adapter pointer
16801 * @staid: station id of the client
16802 * @rssi: rssi value to fill
16803 *
16804 * Return: None
16805 */
16806static void
16807wlan_hdd_sap_get_sta_rssi(hdd_adapter_t *adapter, uint8_t staid, s8 *rssi)
16808{
16809 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
16810
16811 WLANTL_GetSAPStaRSSi(pVosContext, staid, rssi);
16812}
16813
16814/**
Dustin Brown8c1d4092017-07-28 18:08:01 +053016815 * wlan_hdd_get_sap_stats() - get aggregate SAP stats
16816 * @adapter: sap adapter to get stats for
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053016817 * @mac: mac address of the station
Dustin Brown8c1d4092017-07-28 18:08:01 +053016818 * @info: kernel station_info struct to populate
16819 *
16820 * Fetch the vdev-level aggregate stats for the given SAP adapter. This is to
16821 * support "station dump" and "station get" for SAP vdevs, even though they
16822 * aren't technically stations.
16823 *
16824 * Return: errno
16825 */
16826static int
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053016827wlan_hdd_get_sap_stats(hdd_adapter_t *adapter,
16828#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16829 const u8* mac,
16830#else
16831 u8* mac,
16832#endif
16833 struct station_info *info)
Dustin Brown8c1d4092017-07-28 18:08:01 +053016834{
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053016835 v_MACADDR_t *peerMacAddr;
16836 uint8_t staid;
Dustin Brown8c1d4092017-07-28 18:08:01 +053016837 VOS_STATUS status;
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053016838 bool bc_mac_addr;
Dustin Brown8c1d4092017-07-28 18:08:01 +053016839
16840 status = wlan_hdd_get_station_stats(adapter);
16841 if (!VOS_IS_STATUS_SUCCESS(status)) {
16842 hddLog(VOS_TRACE_LEVEL_ERROR,
16843 "Failed to get SAP stats; status:%d", status);
16844 return 0;
16845 }
16846
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053016847 peerMacAddr = (v_MACADDR_t *)mac;
16848 bc_mac_addr = vos_is_macaddr_broadcast(peerMacAddr);
16849 staid = hdd_sta_id_find_from_mac_addr(adapter, peerMacAddr);
16850 hddLog(VOS_TRACE_LEVEL_INFO, "Get SAP stats for sta id:%d", staid);
16851
16852 if (staid < WLAN_MAX_STA_COUNT && !bc_mac_addr) {
16853 wlan_hdd_sap_get_sta_rssi(adapter, staid, &info->signal);
16854 info->filled |= STATION_INFO_SIGNAL;
16855 }
16856
Dustin Brown8c1d4092017-07-28 18:08:01 +053016857 wlan_hdd_fill_summary_stats(&adapter->hdd_stats.summary_stat, info);
16858
16859 return 0;
16860}
16861
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016862static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016863#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16864 const u8* mac,
16865#else
16866 u8* mac,
16867#endif
16868 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070016869{
16870 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
16871 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16872 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053016873 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070016874
16875 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
16876 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070016877
16878 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
16879 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
16880 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
16881 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
16882 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
16883 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
16884 tANI_U16 maxRate = 0;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053016885 int8_t snr = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070016886 tANI_U16 myRate;
16887 tANI_U16 currentRate = 0;
16888 tANI_U8 maxSpeedMCS = 0;
16889 tANI_U8 maxMCSIdx = 0;
16890 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053016891 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070016892 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016893 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016894
Leo Chang6f8870f2013-03-26 18:11:36 -070016895#ifdef WLAN_FEATURE_11AC
16896 tANI_U32 vht_mcs_map;
16897 eDataRate11ACMaxMcs vhtMaxMcs;
16898#endif /* WLAN_FEATURE_11AC */
16899
Jeff Johnsone7245742012-09-05 17:12:55 -070016900 ENTER();
16901
Dustin Brown8c1d4092017-07-28 18:08:01 +053016902 status = wlan_hdd_validate_context(pHddCtx);
16903 if (0 != status)
16904 {
16905 return status;
16906 }
16907
16908 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053016909 return wlan_hdd_get_sap_stats(pAdapter, mac, sinfo);
Dustin Brown8c1d4092017-07-28 18:08:01 +053016910
Jeff Johnson295189b2012-06-20 16:38:30 -070016911 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
16912 (0 == ssidlen))
16913 {
16914 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
16915 " Invalid ssidlen, %d", __func__, ssidlen);
16916 /*To keep GUI happy*/
16917 return 0;
16918 }
16919
Mukul Sharma811205f2014-07-09 21:07:30 +053016920 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
16921 {
16922 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16923 "%s: Roaming in progress, so unable to proceed this request", __func__);
Sachin Ahuja81ab1812016-08-19 21:35:58 +053016924 /* return a cached value */
16925 sinfo->signal = pAdapter->rssi;
Mukul Sharma811205f2014-07-09 21:07:30 +053016926 return 0;
16927 }
16928
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053016929 wlan_hdd_get_station_stats(pAdapter);
16930 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070016931
Kiet Lam3b17fc82013-09-27 05:24:08 +053016932 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053016933 wlan_hdd_get_snr(pAdapter, &snr);
16934 pHddStaCtx->conn_info.signal = sinfo->signal;
16935 pHddStaCtx->conn_info.noise = pHddStaCtx->conn_info.signal - snr;
Kiet Lam3b17fc82013-09-27 05:24:08 +053016936 sinfo->filled |= STATION_INFO_SIGNAL;
16937
c_hpothu09f19542014-05-30 21:53:31 +053016938 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053016939 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
16940 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053016941 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053016942 {
16943 rate_flags = pAdapter->maxRateFlags;
16944 }
c_hpothu44ff4e02014-05-08 00:13:57 +053016945
Jeff Johnson295189b2012-06-20 16:38:30 -070016946 //convert to the UI units of 100kbps
16947 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
16948
16949#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070016950 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 -070016951 sinfo->signal,
16952 pCfg->reportMaxLinkSpeed,
16953 myRate,
16954 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070016955 (int) pCfg->linkSpeedRssiMid,
16956 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070016957 (int) rate_flags,
16958 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070016959#endif //LINKSPEED_DEBUG_ENABLED
16960
16961 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
16962 {
16963 // we do not want to necessarily report the current speed
16964 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
16965 {
16966 // report the max possible speed
16967 rssidx = 0;
16968 }
16969 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
16970 {
16971 // report the max possible speed with RSSI scaling
16972 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
16973 {
16974 // report the max possible speed
16975 rssidx = 0;
16976 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070016977 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070016978 {
16979 // report middle speed
16980 rssidx = 1;
16981 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070016982 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
16983 {
16984 // report middle speed
16985 rssidx = 2;
16986 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016987 else
16988 {
16989 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070016990 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070016991 }
16992 }
16993 else
16994 {
16995 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
16996 hddLog(VOS_TRACE_LEVEL_ERROR,
16997 "%s: Invalid value for reportMaxLinkSpeed: %u",
16998 __func__, pCfg->reportMaxLinkSpeed);
16999 rssidx = 0;
17000 }
17001
17002 maxRate = 0;
17003
17004 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053017005 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
17006 OperationalRates, &ORLeng))
17007 {
17008 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
17009 /*To keep GUI happy*/
17010 return 0;
17011 }
17012
Jeff Johnson295189b2012-06-20 16:38:30 -070017013 for (i = 0; i < ORLeng; i++)
17014 {
Jeff Johnsone7245742012-09-05 17:12:55 -070017015 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070017016 {
17017 /* Validate Rate Set */
17018 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
17019 {
17020 currentRate = supported_data_rate[j].supported_rate[rssidx];
17021 break;
17022 }
17023 }
17024 /* Update MAX rate */
17025 maxRate = (currentRate > maxRate)?currentRate:maxRate;
17026 }
17027
17028 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053017029 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
17030 ExtendedRates, &ERLeng))
17031 {
17032 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
17033 /*To keep GUI happy*/
17034 return 0;
17035 }
17036
Jeff Johnson295189b2012-06-20 16:38:30 -070017037 for (i = 0; i < ERLeng; i++)
17038 {
Jeff Johnsone7245742012-09-05 17:12:55 -070017039 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070017040 {
17041 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
17042 {
17043 currentRate = supported_data_rate[j].supported_rate[rssidx];
17044 break;
17045 }
17046 }
17047 /* Update MAX rate */
17048 maxRate = (currentRate > maxRate)?currentRate:maxRate;
17049 }
c_hpothu79aab322014-07-14 21:11:01 +053017050
Kiet Lamb69f8dc2013-11-15 15:34:27 +053017051 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053017052 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053017053 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053017054 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070017055 {
c_hpothu79aab322014-07-14 21:11:01 +053017056 if (rate_flags & eHAL_TX_RATE_VHT80)
17057 mode = 2;
17058 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
17059 mode = 1;
17060 else
17061 mode = 0;
17062
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053017063 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
17064 MCSRates, &MCSLeng))
17065 {
17066 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
17067 /*To keep GUI happy*/
17068 return 0;
17069 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017070 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070017071#ifdef WLAN_FEATURE_11AC
17072 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017073 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070017074 {
Leo Chang6f8870f2013-03-26 18:11:36 -070017075 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017076 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070017077 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070017078 {
Leo Chang6f8870f2013-03-26 18:11:36 -070017079 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070017080 }
Leo Chang6f8870f2013-03-26 18:11:36 -070017081 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070017082 {
Leo Chang6f8870f2013-03-26 18:11:36 -070017083 maxMCSIdx = 7;
17084 }
17085 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
17086 {
17087 maxMCSIdx = 8;
17088 }
17089 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
17090 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017091 //VHT20 is supporting 0~8
17092 if (rate_flags & eHAL_TX_RATE_VHT20)
17093 maxMCSIdx = 8;
17094 else
17095 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070017096 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017097
c_hpothu79aab322014-07-14 21:11:01 +053017098 if (0 != rssidx)/*check for scaled */
17099 {
17100 //get middle rate MCS index if rssi=1/2
17101 for (i=0; i <= maxMCSIdx; i++)
17102 {
17103 if (sinfo->signal <= rssiMcsTbl[mode][i])
17104 {
17105 maxMCSIdx = i;
17106 break;
17107 }
17108 }
17109 }
17110
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017111 if (rate_flags & eHAL_TX_RATE_VHT80)
17112 {
17113 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
17114 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
17115 }
17116 else if (rate_flags & eHAL_TX_RATE_VHT40)
17117 {
17118 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
17119 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
17120 }
17121 else if (rate_flags & eHAL_TX_RATE_VHT20)
17122 {
17123 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
17124 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
17125 }
17126
Leo Chang6f8870f2013-03-26 18:11:36 -070017127 maxSpeedMCS = 1;
17128 if (currentRate > maxRate)
17129 {
17130 maxRate = currentRate;
17131 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017132
Leo Chang6f8870f2013-03-26 18:11:36 -070017133 }
17134 else
17135#endif /* WLAN_FEATURE_11AC */
17136 {
17137 if (rate_flags & eHAL_TX_RATE_HT40)
17138 {
17139 rateFlag |= 1;
17140 }
17141 if (rate_flags & eHAL_TX_RATE_SGI)
17142 {
17143 rateFlag |= 2;
17144 }
17145
Girish Gowli01abcee2014-07-31 20:18:55 +053017146 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053017147 if (rssidx == 1 || rssidx == 2)
17148 {
17149 //get middle rate MCS index if rssi=1/2
17150 for (i=0; i <= 7; i++)
17151 {
17152 if (sinfo->signal <= rssiMcsTbl[mode][i])
17153 {
17154 temp = i+1;
17155 break;
17156 }
17157 }
17158 }
c_hpothu79aab322014-07-14 21:11:01 +053017159
17160 for (i = 0; i < MCSLeng; i++)
17161 {
Leo Chang6f8870f2013-03-26 18:11:36 -070017162 for (j = 0; j < temp; j++)
17163 {
17164 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
17165 {
17166 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053017167 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070017168 break;
17169 }
17170 }
17171 if ((j < temp) && (currentRate > maxRate))
17172 {
17173 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070017174 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017175 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053017176 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070017177 }
17178 }
17179
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017180 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
17181 {
17182 maxRate = myRate;
17183 maxSpeedMCS = 1;
17184 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
17185 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017186 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053017187 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070017188 {
17189 maxRate = myRate;
17190 if (rate_flags & eHAL_TX_RATE_LEGACY)
17191 {
17192 maxSpeedMCS = 0;
17193 }
17194 else
17195 {
17196 maxSpeedMCS = 1;
17197 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
17198 }
17199 }
17200
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017201 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070017202 {
17203 sinfo->txrate.legacy = maxRate;
17204#ifdef LINKSPEED_DEBUG_ENABLED
17205 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
17206#endif //LINKSPEED_DEBUG_ENABLED
17207 }
17208 else
17209 {
17210 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070017211#ifdef WLAN_FEATURE_11AC
17212 sinfo->txrate.nss = 1;
17213 if (rate_flags & eHAL_TX_RATE_VHT80)
17214 {
17215 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017216 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070017217 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017218 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070017219 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017220 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
17221 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
17222 }
17223 else if (rate_flags & eHAL_TX_RATE_VHT20)
17224 {
17225 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
17226 }
17227#endif /* WLAN_FEATURE_11AC */
17228 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
17229 {
17230 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
17231 if (rate_flags & eHAL_TX_RATE_HT40)
17232 {
17233 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
17234 }
Leo Chang6f8870f2013-03-26 18:11:36 -070017235 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017236 if (rate_flags & eHAL_TX_RATE_SGI)
17237 {
17238 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
17239 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017240
Jeff Johnson295189b2012-06-20 16:38:30 -070017241#ifdef LINKSPEED_DEBUG_ENABLED
17242 pr_info("Reporting MCS rate %d flags %x\n",
17243 sinfo->txrate.mcs,
17244 sinfo->txrate.flags );
17245#endif //LINKSPEED_DEBUG_ENABLED
17246 }
17247 }
17248 else
17249 {
17250 // report current rate instead of max rate
17251
17252 if (rate_flags & eHAL_TX_RATE_LEGACY)
17253 {
17254 //provide to the UI in units of 100kbps
17255 sinfo->txrate.legacy = myRate;
17256#ifdef LINKSPEED_DEBUG_ENABLED
17257 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
17258#endif //LINKSPEED_DEBUG_ENABLED
17259 }
17260 else
17261 {
17262 //must be MCS
17263 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070017264#ifdef WLAN_FEATURE_11AC
17265 sinfo->txrate.nss = 1;
17266 if (rate_flags & eHAL_TX_RATE_VHT80)
17267 {
17268 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
17269 }
17270 else
17271#endif /* WLAN_FEATURE_11AC */
17272 {
17273 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
17274 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017275 if (rate_flags & eHAL_TX_RATE_SGI)
17276 {
17277 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
17278 }
17279 if (rate_flags & eHAL_TX_RATE_HT40)
17280 {
17281 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
17282 }
Leo Chang6f8870f2013-03-26 18:11:36 -070017283#ifdef WLAN_FEATURE_11AC
17284 else if (rate_flags & eHAL_TX_RATE_VHT80)
17285 {
17286 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
17287 }
17288#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070017289#ifdef LINKSPEED_DEBUG_ENABLED
17290 pr_info("Reporting actual MCS rate %d flags %x\n",
17291 sinfo->txrate.mcs,
17292 sinfo->txrate.flags );
17293#endif //LINKSPEED_DEBUG_ENABLED
17294 }
17295 }
17296 sinfo->filled |= STATION_INFO_TX_BITRATE;
17297
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070017298 sinfo->tx_packets =
17299 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
17300 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
17301 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
17302 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
17303
17304 sinfo->tx_retries =
17305 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
17306 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
17307 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
17308 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
17309
17310 sinfo->tx_failed =
17311 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
17312 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
17313 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
17314 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
17315
17316 sinfo->filled |=
17317 STATION_INFO_TX_PACKETS |
17318 STATION_INFO_TX_RETRIES |
17319 STATION_INFO_TX_FAILED;
17320
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053017321 sinfo->rx_packets = pAdapter->hdd_stats.summary_stat.rx_frm_cnt;
17322 sinfo->filled |= STATION_INFO_RX_PACKETS;
17323
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053017324 vos_mem_copy(&pHddStaCtx->conn_info.txrate,
17325 &sinfo->txrate, sizeof(sinfo->txrate));
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053017326 if (rate_flags & eHAL_TX_RATE_LEGACY)
17327 hddLog(LOG1, FL("Reporting RSSI:%d legacy rate %d pkt cnt tx %d rx %d"),
17328 sinfo->signal, sinfo->txrate.legacy, sinfo->tx_packets,
17329 sinfo->rx_packets);
17330 else
17331 hddLog(LOG1,
17332 FL("Reporting RSSI:%d MCS rate %d flags 0x%x pkt cnt tx %d rx %d"),
17333 sinfo->signal, sinfo->txrate.mcs, sinfo->txrate.flags,
17334 sinfo->tx_packets, sinfo->rx_packets);
17335
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017336 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17337 TRACE_CODE_HDD_CFG80211_GET_STA,
17338 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070017339 EXIT();
17340 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070017341}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017342#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
17343static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
17344 const u8* mac, struct station_info *sinfo)
17345#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017346static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
17347 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017348#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017349{
17350 int ret;
17351
17352 vos_ssr_protect(__func__);
17353 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
17354 vos_ssr_unprotect(__func__);
17355
17356 return ret;
17357}
17358
17359static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070017360 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070017361{
17362 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017363 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070017364 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017365 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017366
Jeff Johnsone7245742012-09-05 17:12:55 -070017367 ENTER();
17368
Jeff Johnson295189b2012-06-20 16:38:30 -070017369 if (NULL == pAdapter)
17370 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017371 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017372 return -ENODEV;
17373 }
17374
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017375 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17376 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
17377 pAdapter->sessionId, timeout));
17378
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017379 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017380 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017381 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017382 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017383 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017384 }
17385
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017386 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
17387 (TRUE == pHddCtx->hdd_wlan_suspended) &&
17388 (pHddCtx->cfg_ini->fhostArpOffload) &&
17389 (eConnectionState_Associated ==
17390 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
17391 {
Amar Singhald53568e2013-09-26 11:03:45 -070017392
17393 hddLog(VOS_TRACE_LEVEL_INFO,
17394 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053017395 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017396 if (!VOS_IS_STATUS_SUCCESS(vos_status))
17397 {
17398 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017399 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017400 __func__, vos_status);
17401 }
17402 }
17403
Jeff Johnson295189b2012-06-20 16:38:30 -070017404 /**The get power cmd from the supplicant gets updated by the nl only
17405 *on successful execution of the function call
17406 *we are oppositely mapped w.r.t mode in the driver
17407 **/
17408 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
17409
17410 if (VOS_STATUS_E_FAILURE == vos_status)
17411 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053017412 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17413 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017414 return -EINVAL;
17415 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017416 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017417 return 0;
17418}
17419
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017420static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
17421 struct net_device *dev, bool mode, int timeout)
17422{
17423 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070017424
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017425 vos_ssr_protect(__func__);
17426 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
17427 vos_ssr_unprotect(__func__);
17428
17429 return ret;
17430}
Sushant Kaushik084f6592015-09-10 13:11:56 +053017431
Jeff Johnson295189b2012-06-20 16:38:30 -070017432#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017433static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
17434 struct net_device *netdev,
17435 u8 key_index)
17436{
17437 ENTER();
17438 return 0;
17439}
17440
Jeff Johnson295189b2012-06-20 16:38:30 -070017441static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017442 struct net_device *netdev,
17443 u8 key_index)
17444{
17445 int ret;
17446 vos_ssr_protect(__func__);
17447 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
17448 vos_ssr_unprotect(__func__);
17449 return ret;
17450}
17451#endif //LINUX_VERSION_CODE
17452
17453#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
17454static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
17455 struct net_device *dev,
17456 struct ieee80211_txq_params *params)
17457{
17458 ENTER();
17459 return 0;
17460}
17461#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
17462static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
17463 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070017464{
Jeff Johnsone7245742012-09-05 17:12:55 -070017465 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070017466 return 0;
17467}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017468#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070017469
17470#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
17471static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017472 struct net_device *dev,
17473 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070017474{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017475 int ret;
17476
17477 vos_ssr_protect(__func__);
17478 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
17479 vos_ssr_unprotect(__func__);
17480 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070017481}
17482#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
17483static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
17484 struct ieee80211_txq_params *params)
17485{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017486 int ret;
17487
17488 vos_ssr_protect(__func__);
17489 ret = __wlan_hdd_set_txq_params(wiphy, params);
17490 vos_ssr_unprotect(__func__);
17491 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070017492}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017493#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017494
Naresh Jayaram69e3f282014-10-14 12:29:12 +053017495static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017496 struct net_device *dev,
17497 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070017498{
17499 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017500 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017501 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017502 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017503 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017504 v_CONTEXT_t pVosContext = NULL;
17505 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017506
Jeff Johnsone7245742012-09-05 17:12:55 -070017507 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017508
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017509 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070017510 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017511 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017512 return -EINVAL;
17513 }
17514
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017515 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17516 TRACE_CODE_HDD_CFG80211_DEL_STA,
17517 pAdapter->sessionId, pAdapter->device_mode));
17518
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017519 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17520 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017521 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017522 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017523 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017524 }
17525
Jeff Johnson295189b2012-06-20 16:38:30 -070017526 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070017527 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070017528 )
17529 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017530 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
17531 pSapCtx = VOS_GET_SAP_CB(pVosContext);
17532 if(pSapCtx == NULL){
17533 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17534 FL("psapCtx is NULL"));
17535 return -ENOENT;
17536 }
Agrawal Ashish306b75f2017-01-11 19:16:25 +053017537 if (pHddCtx->cfg_ini->enable_sap_auth_offload)
17538 {
17539 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
17540 "Change reason code to eSIR_MAC_DISASSOC_LEAVING_BSS_REASON in sap auth offload");
17541 pDelStaParams->reason_code = eSIR_MAC_DISASSOC_LEAVING_BSS_REASON;
17542 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017543 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070017544 {
17545 v_U16_t i;
17546 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
17547 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017548 if ((pSapCtx->aStaInfo[i].isUsed) &&
17549 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070017550 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017551 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017552 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017553 ETHER_ADDR_LEN);
17554
Jeff Johnson295189b2012-06-20 16:38:30 -070017555 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080017556 "%s: Delete STA with MAC::"
17557 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017558 __func__,
17559 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
17560 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070017561 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017562 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070017563 }
17564 }
17565 }
17566 else
17567 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017568
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017569 vos_status = hdd_softap_GetStaId(pAdapter,
17570 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017571 if (!VOS_IS_STATUS_SUCCESS(vos_status))
17572 {
17573 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080017574 "%s: Skip this DEL STA as this is not used::"
17575 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017576 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017577 return -ENOENT;
17578 }
17579
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017580 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017581 {
17582 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080017583 "%s: Skip this DEL STA as deauth is in progress::"
17584 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017585 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017586 return -ENOENT;
17587 }
17588
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017589 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017590
Jeff Johnson295189b2012-06-20 16:38:30 -070017591 hddLog(VOS_TRACE_LEVEL_INFO,
17592 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080017593 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070017594 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017595 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017596
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017597 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017598 if (!VOS_IS_STATUS_SUCCESS(vos_status))
17599 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017600 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017601 hddLog(VOS_TRACE_LEVEL_INFO,
17602 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080017603 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017604 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017605 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017606 return -ENOENT;
17607 }
17608
Jeff Johnson295189b2012-06-20 16:38:30 -070017609 }
17610 }
17611
17612 EXIT();
17613
17614 return 0;
17615}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053017616
17617#ifdef CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053017618int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Naresh Jayaram69e3f282014-10-14 12:29:12 +053017619 struct net_device *dev,
17620 struct station_del_parameters *param)
17621#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017622#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
Kapil Gupta137ef892016-12-13 19:38:00 +053017623int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017624 struct net_device *dev, const u8 *mac)
17625#else
Kapil Gupta137ef892016-12-13 19:38:00 +053017626int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017627 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053017628#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017629#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017630{
17631 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017632 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070017633
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017634 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017635
Naresh Jayaram69e3f282014-10-14 12:29:12 +053017636#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017637 if (NULL == param) {
17638 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017639 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017640 return -EINVAL;
17641 }
17642
17643 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
17644 param->subtype, &delStaParams);
17645
Naresh Jayaram69e3f282014-10-14 12:29:12 +053017646#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053017647 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017648 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053017649#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017650 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
17651
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017652 vos_ssr_unprotect(__func__);
17653
17654 return ret;
17655}
17656
17657static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017658 struct net_device *dev,
17659#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17660 const u8 *mac,
17661#else
17662 u8 *mac,
17663#endif
17664 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017665{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017666 hdd_adapter_t *pAdapter;
17667 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017668 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017669#ifdef FEATURE_WLAN_TDLS
17670 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017671
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017672 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017673
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017674 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17675 if (NULL == pAdapter)
17676 {
17677 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17678 "%s: Adapter is NULL",__func__);
17679 return -EINVAL;
17680 }
17681 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17682 status = wlan_hdd_validate_context(pHddCtx);
17683 if (0 != status)
17684 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017685 return status;
17686 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017687
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017688 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17689 TRACE_CODE_HDD_CFG80211_ADD_STA,
17690 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017691 mask = params->sta_flags_mask;
17692
17693 set = params->sta_flags_set;
17694
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017695 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017696 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
17697 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017698
17699 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
17700 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080017701 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017702 }
17703 }
17704#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017705 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017706 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017707}
17708
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017709#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
17710static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
17711 struct net_device *dev, const u8 *mac,
17712 struct station_parameters *params)
17713#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017714static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
17715 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017716#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017717{
17718 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017719
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017720 vos_ssr_protect(__func__);
17721 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
17722 vos_ssr_unprotect(__func__);
17723
17724 return ret;
17725}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017726#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070017727
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017728static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070017729 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017730{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017731 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17732 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017733 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017734 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017735 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017736 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070017737
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017738 ENTER();
17739
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017740 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017741 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017742 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017743 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017744 return -EINVAL;
17745 }
17746
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017747 if (!pmksa) {
17748 hddLog(LOGE, FL("pmksa is NULL"));
17749 return -EINVAL;
17750 }
17751
17752 if (!pmksa->bssid || !pmksa->pmkid) {
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070017753 hddLog(LOGE, FL("pmksa->bssid(%pK) or pmksa->pmkid(%pK) is NULL"),
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017754 pmksa->bssid, pmksa->pmkid);
17755 return -EINVAL;
17756 }
17757
17758 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
17759 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
17760
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017761 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17762 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017763 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017764 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017765 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017766 }
17767
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017768 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017769 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
17770
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017771 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
17772 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017773
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017774 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017775 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017776 &pmk_id, 1, FALSE);
17777
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017778 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17779 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
17780 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017781
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017782 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017783 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017784}
17785
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017786static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
17787 struct cfg80211_pmksa *pmksa)
17788{
17789 int ret;
17790
17791 vos_ssr_protect(__func__);
17792 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
17793 vos_ssr_unprotect(__func__);
17794
17795 return ret;
17796}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017797
Wilson Yang6507c4e2013-10-01 20:11:19 -070017798
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017799static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070017800 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017801{
Wilson Yang6507c4e2013-10-01 20:11:19 -070017802 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17803 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017804 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080017805 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017806
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017807 ENTER();
17808
Wilson Yang6507c4e2013-10-01 20:11:19 -070017809 /* Validate pAdapter */
17810 if (NULL == pAdapter)
17811 {
17812 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
17813 return -EINVAL;
17814 }
17815
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017816 if (!pmksa) {
17817 hddLog(LOGE, FL("pmksa is NULL"));
17818 return -EINVAL;
17819 }
17820
17821 if (!pmksa->bssid) {
17822 hddLog(LOGE, FL("pmksa->bssid is NULL"));
17823 return -EINVAL;
17824 }
17825
Kiet Lam98c46a12014-10-31 15:34:57 -070017826 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
17827 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
17828
Wilson Yang6507c4e2013-10-01 20:11:19 -070017829 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17830 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070017831 if (0 != status)
17832 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070017833 return status;
17834 }
17835
17836 /*Retrieve halHandle*/
17837 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
17838
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017839 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17840 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
17841 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017842 /* Delete the PMKID CSR cache */
17843 if (eHAL_STATUS_SUCCESS !=
17844 sme_RoamDelPMKIDfromCache(halHandle,
17845 pAdapter->sessionId, pmksa->bssid, FALSE)) {
17846 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
17847 MAC_ADDR_ARRAY(pmksa->bssid));
17848 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017849 }
17850
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017851 EXIT();
17852 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017853}
17854
Wilson Yang6507c4e2013-10-01 20:11:19 -070017855
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017856static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
17857 struct cfg80211_pmksa *pmksa)
17858{
17859 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017860
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017861 vos_ssr_protect(__func__);
17862 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
17863 vos_ssr_unprotect(__func__);
17864
17865 return ret;
17866
17867}
17868
17869static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017870{
Wilson Yang6507c4e2013-10-01 20:11:19 -070017871 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17872 tHalHandle halHandle;
17873 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080017874 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017875
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017876 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070017877
17878 /* Validate pAdapter */
17879 if (NULL == pAdapter)
17880 {
17881 hddLog(VOS_TRACE_LEVEL_ERROR,
17882 "%s: Invalid Adapter" ,__func__);
17883 return -EINVAL;
17884 }
17885
17886 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17887 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070017888 if (0 != status)
17889 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070017890 return status;
17891 }
17892
17893 /*Retrieve halHandle*/
17894 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
17895
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017896 /* Flush the PMKID cache in CSR */
17897 if (eHAL_STATUS_SUCCESS !=
17898 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
17899 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
17900 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017901 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017902 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080017903 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017904}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017905
17906static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
17907{
17908 int ret;
17909
17910 vos_ssr_protect(__func__);
17911 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
17912 vos_ssr_unprotect(__func__);
17913
17914 return ret;
17915}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017916#endif
17917
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017918#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017919static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
17920 struct net_device *dev,
17921 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017922{
17923 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17924 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017925 hdd_context_t *pHddCtx;
17926 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017927
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017928 ENTER();
17929
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017930 if (NULL == pAdapter)
17931 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017932 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017933 return -ENODEV;
17934 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017935 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17936 ret = wlan_hdd_validate_context(pHddCtx);
17937 if (0 != ret)
17938 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017939 return ret;
17940 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017941 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017942 if (NULL == pHddStaCtx)
17943 {
17944 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
17945 return -EINVAL;
17946 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017947
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017948 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17949 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
17950 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017951 // Added for debug on reception of Re-assoc Req.
17952 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
17953 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017954 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017955 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080017956 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017957 }
17958
17959#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080017960 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017961 ftie->ie_len);
17962#endif
17963
17964 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053017965 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
17966 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017967 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017968
17969 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017970 return 0;
17971}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017972
17973static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
17974 struct net_device *dev,
17975 struct cfg80211_update_ft_ies_params *ftie)
17976{
17977 int ret;
17978
17979 vos_ssr_protect(__func__);
17980 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
17981 vos_ssr_unprotect(__func__);
17982
17983 return ret;
17984}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017985#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017986
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017987#ifdef FEATURE_WLAN_SCAN_PNO
17988
17989void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
17990 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
17991{
17992 int ret;
17993 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
17994 hdd_context_t *pHddCtx;
17995
Nirav Shah80830bf2013-12-31 16:35:12 +053017996 ENTER();
17997
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017998 if (NULL == pAdapter)
17999 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053018000 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018001 "%s: HDD adapter is Null", __func__);
18002 return ;
18003 }
18004
18005 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18006 if (NULL == pHddCtx)
18007 {
18008 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18009 "%s: HDD context is Null!!!", __func__);
18010 return ;
18011 }
18012
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018013 spin_lock(&pHddCtx->schedScan_lock);
18014 if (TRUE == pHddCtx->isWiphySuspended)
18015 {
18016 pHddCtx->isSchedScanUpdatePending = TRUE;
18017 spin_unlock(&pHddCtx->schedScan_lock);
18018 hddLog(VOS_TRACE_LEVEL_INFO,
18019 "%s: Update cfg80211 scan database after it resume", __func__);
18020 return ;
18021 }
18022 spin_unlock(&pHddCtx->schedScan_lock);
18023
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018024 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
18025
18026 if (0 > ret)
18027 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagarfb49cdd2015-10-16 18:41:59 +053018028 else
18029 {
18030 /* Acquire wakelock to handle the case where APP's tries to suspend
18031 * immediatly after the driver gets connect request(i.e after pno)
18032 * from supplicant, this result in app's is suspending and not able
18033 * to process the connect request to AP */
18034 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
18035 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018036 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018037 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18038 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018039}
18040
18041/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018042 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053018043 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018044 */
18045static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
18046{
18047 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
18048 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018049 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018050 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18051 int status = 0;
Agrawal Ashishcff31692016-12-16 17:17:50 +053018052
18053 if (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
18054 {
18055 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18056 "%s: PNO is allowed only in STA interface", __func__);
18057 return eHAL_STATUS_FAILURE;
18058 }
18059
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018060 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
18061
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053018062 /* The current firmware design does not allow PNO during any
Agrawal Ashishcff31692016-12-16 17:17:50 +053018063 * active sessions. PNO is allowed only in case when sap session
18064 * is present and sapo auth offload feature enabled in firmare.
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053018065 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018066 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
18067 {
18068 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018069 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018070
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018071 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
18072 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
18073 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
18074 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
Agrawal Ashishcff31692016-12-16 17:17:50 +053018075 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode &&
18076 !pHddCtx->cfg_ini->enable_sap_auth_offload)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053018077 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018078 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018079 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018080 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018081 }
18082 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
18083 pAdapterNode = pNext;
18084 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018085 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018086}
18087
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018088void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
18089{
18090 hdd_adapter_t *pAdapter = callbackContext;
18091 hdd_context_t *pHddCtx;
18092
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018093 ENTER();
18094
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018095 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
18096 {
18097 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18098 FL("Invalid adapter or adapter has invalid magic"));
18099 return;
18100 }
18101
18102 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18103 if (0 != wlan_hdd_validate_context(pHddCtx))
18104 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018105 return;
18106 }
18107
c_hpothub53c45d2014-08-18 16:53:14 +053018108 if (VOS_STATUS_SUCCESS != status)
18109 {
18110 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018111 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053018112 pHddCtx->isPnoEnable = FALSE;
18113 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018114
18115 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
18116 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018117 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018118}
18119
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018120#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) || \
18121 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
18122/**
18123 * hdd_config_sched_scan_plan() - configures the sched scan plans
18124 * from the framework.
18125 * @pno_req: pointer to PNO scan request
18126 * @request: pointer to scan request from framework
18127 *
18128 * Return: None
18129 */
18130static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
18131 struct cfg80211_sched_scan_request *request,
18132 hdd_context_t *hdd_ctx)
18133{
18134 v_U32_t i = 0;
18135
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018136 pno_req->scanTimers.ucScanTimersCount = request->n_scan_plans;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018137 for (i = 0; i < request->n_scan_plans; i++)
18138 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018139 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
18140 request->scan_plans[i].iterations;
18141 pno_req->scanTimers.aTimerValues[i].uTimerValue =
18142 request->scan_plans[i].interval;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018143 }
18144}
18145#else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018146static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018147 struct cfg80211_sched_scan_request *request,
18148 hdd_context_t *hdd_ctx)
18149{
18150 v_U32_t i, temp_int;
18151 /* Driver gets only one time interval which is hardcoded in
18152 * supplicant for 10000ms. Taking power consumption into account 6
18153 * timers will be used, Timervalue is increased exponentially
18154 * i.e 10,20,40, 80,160,320 secs. And number of scan cycle for each
18155 * timer is configurable through INI param gPNOScanTimerRepeatValue.
18156 * If it is set to 0 only one timer will be used and PNO scan cycle
18157 * will be repeated after each interval specified by supplicant
18158 * till PNO is disabled.
18159 */
18160 if (0 == hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue)
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018161 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018162 HDD_PNO_SCAN_TIMERS_SET_ONE;
18163 else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018164 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018165 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
18166
18167 temp_int = (request->interval)/1000;
18168 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18169 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
18170 temp_int, hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue);
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018171 for ( i = 0; i < pno_req->scanTimers.ucScanTimersCount; i++)
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018172 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018173 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018174 hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue;
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018175 pno_req->scanTimers.aTimerValues[i].uTimerValue = temp_int;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018176 temp_int *= 2;
18177 }
18178 //Repeat last timer until pno disabled.
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018179 pno_req->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018180}
18181#endif
18182
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018183/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018184 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
18185 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018186 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018187static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018188 struct net_device *dev, struct cfg80211_sched_scan_request *request)
18189{
18190 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018191 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018192 hdd_context_t *pHddCtx;
18193 tHalHandle hHal;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018194 v_U32_t i, indx, num_ch, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053018195 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
18196 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018197 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
18198 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018199 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053018200 hdd_config_t *pConfig = NULL;
18201 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018202
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018203 ENTER();
18204
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018205 if (NULL == pAdapter)
18206 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018207 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018208 "%s: HDD adapter is Null", __func__);
18209 return -ENODEV;
18210 }
18211
18212 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018213 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018214
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018215 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018216 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018217 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018218 }
18219
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053018220 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018221 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
18222 if (NULL == hHal)
18223 {
18224 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18225 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018226 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018227 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018228 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18229 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
18230 pAdapter->sessionId, pAdapter->device_mode));
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053018231 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053018232 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053018233 {
18234 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18235 "%s: aborting the existing scan is unsuccessfull", __func__);
18236 return -EBUSY;
18237 }
18238
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018239 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018240 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053018241 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018242 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018243 return -EBUSY;
18244 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018245
c_hpothu37f21312014-04-09 21:49:54 +053018246 if (TRUE == pHddCtx->isPnoEnable)
18247 {
18248 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
18249 FL("already PNO is enabled"));
18250 return -EBUSY;
18251 }
c_hpothu225aa7c2014-10-22 17:45:13 +053018252
18253 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
18254 {
18255 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18256 "%s: abort ROC failed ", __func__);
18257 return -EBUSY;
18258 }
18259
c_hpothu37f21312014-04-09 21:49:54 +053018260 pHddCtx->isPnoEnable = TRUE;
18261
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018262 pnoRequest.enable = 1; /*Enable PNO */
18263 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018264
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018265 if (( !pnoRequest.ucNetworksCount ) ||
18266 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018267 {
18268 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053018269 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018270 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053018271 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018272 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018273 goto error;
18274 }
18275
18276 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
18277 {
18278 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053018279 "%s: Incorrect number of channels %d",
18280 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018281 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018282 goto error;
18283 }
18284
18285 /* Framework provides one set of channels(all)
18286 * common for all saved profile */
18287 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
18288 channels_allowed, &num_channels_allowed))
18289 {
18290 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18291 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018292 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018293 goto error;
18294 }
18295 /* Checking each channel against allowed channel list */
18296 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053018297 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018298 {
Nirav Shah80830bf2013-12-31 16:35:12 +053018299 char chList [(request->n_channels*5)+1];
18300 int len;
18301 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018302 {
Nirav Shah80830bf2013-12-31 16:35:12 +053018303 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018304 {
Nirav Shah80830bf2013-12-31 16:35:12 +053018305 if (request->channels[i]->hw_value == channels_allowed[indx])
18306 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053018307 if ((!pConfig->enableDFSPnoChnlScan) &&
18308 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
18309 {
18310 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18311 "%s : Dropping DFS channel : %d",
18312 __func__,channels_allowed[indx]);
18313 num_ignore_dfs_ch++;
18314 break;
18315 }
18316
Nirav Shah80830bf2013-12-31 16:35:12 +053018317 valid_ch[num_ch++] = request->channels[i]->hw_value;
18318 len += snprintf(chList+len, 5, "%d ",
18319 request->channels[i]->hw_value);
18320 break ;
18321 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018322 }
18323 }
Nirav Shah80830bf2013-12-31 16:35:12 +053018324 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018325
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053018326 /*If all channels are DFS and dropped, then ignore the PNO request*/
18327 if (num_ignore_dfs_ch == request->n_channels)
18328 {
18329 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18330 "%s : All requested channels are DFS channels", __func__);
18331 ret = -EINVAL;
18332 goto error;
18333 }
18334 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018335
18336 pnoRequest.aNetworks =
18337 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
18338 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018339 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018340 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
18341 FL("failed to allocate memory aNetworks %u"),
18342 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
18343 goto error;
18344 }
18345 vos_mem_zero(pnoRequest.aNetworks,
18346 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
18347
18348 /* Filling per profile params */
18349 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
18350 {
18351 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018352 request->match_sets[i].ssid.ssid_len;
18353
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018354 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
18355 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018356 {
18357 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053018358 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018359 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018360 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018361 goto error;
18362 }
18363
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018364 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018365 request->match_sets[i].ssid.ssid,
18366 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053018367 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18368 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018369 i, pnoRequest.aNetworks[i].ssId.ssId);
18370 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
18371 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
18372 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018373
18374 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018375 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
18376 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018377
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018378 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018379 }
18380
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018381 for (i = 0; i < request->n_ssids; i++)
18382 {
18383 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018384 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018385 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018386 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018387 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018388 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018389 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018390 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018391 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018392 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018393 break;
18394 }
18395 j++;
18396 }
18397 }
18398 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18399 "Number of hidden networks being Configured = %d",
18400 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053018401 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080018402 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018403
18404 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
18405 if (pnoRequest.p24GProbeTemplate == NULL)
18406 {
18407 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
18408 FL("failed to allocate memory p24GProbeTemplate %u"),
18409 SIR_PNO_MAX_PB_REQ_SIZE);
18410 goto error;
18411 }
18412
18413 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
18414 if (pnoRequest.p5GProbeTemplate == NULL)
18415 {
18416 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
18417 FL("failed to allocate memory p5GProbeTemplate %u"),
18418 SIR_PNO_MAX_PB_REQ_SIZE);
18419 goto error;
18420 }
18421
18422 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
18423 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
18424
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053018425 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
18426 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053018427 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018428 pnoRequest.us24GProbeTemplateLen = request->ie_len;
18429 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
18430 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053018431
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018432 pnoRequest.us5GProbeTemplateLen = request->ie_len;
18433 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
18434 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053018435 }
18436
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018437 hdd_config_sched_scan_plan(&pnoRequest, request, pHddCtx);
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053018438
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018439 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018440
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018441 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018442 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
18443 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018444 pAdapter->pno_req_status = 0;
18445
Nirav Shah80830bf2013-12-31 16:35:12 +053018446 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18447 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018448 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
18449 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053018450
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018451 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018452 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018453 hdd_cfg80211_sched_scan_done_callback, pAdapter);
18454 if (eHAL_STATUS_SUCCESS != status)
18455 {
18456 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053018457 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018458 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018459 goto error;
18460 }
18461
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018462 ret = wait_for_completion_timeout(
18463 &pAdapter->pno_comp_var,
18464 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
18465 if (0 >= ret)
18466 {
18467 // Did not receive the response for PNO enable in time.
18468 // Assuming the PNO enable was success.
18469 // Returning error from here, because we timeout, results
18470 // in side effect of Wifi (Wifi Setting) not to work.
18471 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18472 FL("Timed out waiting for PNO to be Enabled"));
18473 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018474 }
18475
18476 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053018477 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018478
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018479error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018480 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18481 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053018482 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018483 if (pnoRequest.aNetworks)
18484 vos_mem_free(pnoRequest.aNetworks);
18485 if (pnoRequest.p24GProbeTemplate)
18486 vos_mem_free(pnoRequest.p24GProbeTemplate);
18487 if (pnoRequest.p5GProbeTemplate)
18488 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018489
18490 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018491 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018492}
18493
18494/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018495 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
18496 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018497 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018498static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
18499 struct net_device *dev, struct cfg80211_sched_scan_request *request)
18500{
18501 int ret;
18502
18503 vos_ssr_protect(__func__);
18504 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
18505 vos_ssr_unprotect(__func__);
18506
18507 return ret;
18508}
18509
18510/*
18511 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
18512 * Function to disable PNO
18513 */
18514static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018515 struct net_device *dev)
18516{
18517 eHalStatus status = eHAL_STATUS_FAILURE;
18518 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18519 hdd_context_t *pHddCtx;
18520 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018521 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018522 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018523
18524 ENTER();
18525
18526 if (NULL == pAdapter)
18527 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018528 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018529 "%s: HDD adapter is Null", __func__);
18530 return -ENODEV;
18531 }
18532
18533 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018534
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018535 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018536 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018537 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018538 "%s: HDD context is Null", __func__);
18539 return -ENODEV;
18540 }
18541
18542 /* The return 0 is intentional when isLogpInProgress and
18543 * isLoadUnloadInProgress. We did observe a crash due to a return of
18544 * failure in sched_scan_stop , especially for a case where the unload
18545 * of the happens at the same time. The function __cfg80211_stop_sched_scan
18546 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
18547 * success. If it returns a failure , then its next invocation due to the
18548 * clean up of the second interface will have the dev pointer corresponding
18549 * to the first one leading to a crash.
18550 */
18551 if (pHddCtx->isLogpInProgress)
18552 {
18553 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18554 "%s: LOGP in Progress. Ignore!!!", __func__);
Mahesh A Saptasagar0c11d822015-10-08 19:54:08 +053018555 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018556 return ret;
18557 }
18558
Mihir Shete18156292014-03-11 15:38:30 +053018559 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018560 {
18561 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18562 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
18563 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018564 }
18565
18566 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
18567 if (NULL == hHal)
18568 {
18569 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18570 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018571 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018572 }
18573
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018574 pnoRequest.enable = 0; /* Disable PNO */
18575 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018576
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018577 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18578 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
18579 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053018580
18581 INIT_COMPLETION(pAdapter->pno_comp_var);
18582 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
18583 pnoRequest.callbackContext = pAdapter;
18584 pAdapter->pno_req_status = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018585 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018586 pAdapter->sessionId,
18587 NULL, pAdapter);
18588 if (eHAL_STATUS_SUCCESS != status)
18589 {
18590 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18591 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018592 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018593 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018594 }
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053018595 ret = wait_for_completion_timeout(
18596 &pAdapter->pno_comp_var,
18597 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
18598 if (0 >= ret)
18599 {
18600 // Did not receive the response for PNO disable in time.
18601 // Assuming the PNO disable was success.
18602 // Returning error from here, because we timeout, results
18603 // in side effect of Wifi (Wifi Setting) not to work.
Anurag Chouhan96b41cb2016-09-28 18:54:47 +053018604 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053018605 FL("Timed out waiting for PNO to be disabled"));
18606 ret = 0;
18607 }
18608
18609 ret = pAdapter->pno_req_status;
18610 pHddCtx->isPnoEnable = (ret == 0) ? FALSE : TRUE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018611
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018612error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018613 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018614 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018615
18616 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018617 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018618}
18619
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018620/*
18621 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
18622 * NL interface to disable PNO
18623 */
18624static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
18625 struct net_device *dev)
18626{
18627 int ret;
18628
18629 vos_ssr_protect(__func__);
18630 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
18631 vos_ssr_unprotect(__func__);
18632
18633 return ret;
18634}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018635#endif /*FEATURE_WLAN_SCAN_PNO*/
18636
18637
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018638#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018639#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018640static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18641 struct net_device *dev,
18642 u8 *peer, u8 action_code,
18643 u8 dialog_token,
18644 u16 status_code, u32 peer_capability,
18645 const u8 *buf, size_t len)
18646#else /* TDLS_MGMT_VERSION2 */
18647#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
18648static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18649 struct net_device *dev,
18650 const u8 *peer, u8 action_code,
18651 u8 dialog_token, u16 status_code,
18652 u32 peer_capability, bool initiator,
18653 const u8 *buf, size_t len)
18654#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
18655static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18656 struct net_device *dev,
18657 const u8 *peer, u8 action_code,
18658 u8 dialog_token, u16 status_code,
18659 u32 peer_capability, const u8 *buf,
18660 size_t len)
18661#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
18662static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18663 struct net_device *dev,
18664 u8 *peer, u8 action_code,
18665 u8 dialog_token,
18666 u16 status_code, u32 peer_capability,
18667 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018668#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018669static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18670 struct net_device *dev,
18671 u8 *peer, u8 action_code,
18672 u8 dialog_token,
18673 u16 status_code, const u8 *buf,
18674 size_t len)
18675#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018676#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018677{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018678 hdd_adapter_t *pAdapter;
18679 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018680 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070018681 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080018682 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070018683 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018684 int ret;
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053018685 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018686#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018687 u32 peer_capability = 0;
18688#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053018689 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018690 hdd_station_ctx_t *pHddStaCtx = NULL;
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053018691 tdlsCtx_t *pHddTdlsCtx;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018692
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018693 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18694 if (NULL == pAdapter)
18695 {
18696 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18697 "%s: Adapter is NULL",__func__);
18698 return -EINVAL;
18699 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018700 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18701 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
18702 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018703
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018704 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018705 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018706 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018707 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018708 "Invalid arguments");
18709 return -EINVAL;
18710 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018711
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080018712 if (pHddCtx->isLogpInProgress)
18713 {
18714 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18715 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053018716 wlan_hdd_tdls_set_link_status(pAdapter,
18717 peer,
18718 eTDLS_LINK_IDLE,
18719 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080018720 return -EBUSY;
18721 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018722
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018723 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
18724 {
18725 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18726 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
18727 return -EAGAIN;
18728 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018729
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053018730 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
18731 if (!pHddTdlsCtx) {
18732 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18733 "%s: pHddTdlsCtx not valid.", __func__);
18734 }
18735
Hoonki Lee27511902013-03-14 18:19:06 -070018736 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018737 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018738 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070018739 "%s: TDLS mode is disabled OR not enabled in FW."
18740 MAC_ADDRESS_STR " action %d declined.",
18741 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018742 return -ENOTSUPP;
18743 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018744
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018745 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18746
18747 if( NULL == pHddStaCtx )
18748 {
18749 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18750 "%s: HDD station context NULL ",__func__);
18751 return -EINVAL;
18752 }
18753
18754 /* STA should be connected and authenticated
18755 * before sending any TDLS frames
18756 */
18757 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
18758 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
18759 {
18760 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18761 "STA is not connected or unauthenticated. "
18762 "connState %u, uIsAuthenticated %u",
18763 pHddStaCtx->conn_info.connState,
18764 pHddStaCtx->conn_info.uIsAuthenticated);
18765 return -EAGAIN;
18766 }
18767
Hoonki Lee27511902013-03-14 18:19:06 -070018768 /* other than teardown frame, other mgmt frames are not sent if disabled */
18769 if (SIR_MAC_TDLS_TEARDOWN != action_code)
18770 {
18771 /* if tdls_mode is disabled to respond to peer's request */
18772 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
18773 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018774 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070018775 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070018776 " TDLS mode is disabled. action %d declined.",
18777 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070018778
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018779 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070018780 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053018781
18782 if (vos_max_concurrent_connections_reached())
18783 {
18784 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
18785 return -EINVAL;
18786 }
Hoonki Lee27511902013-03-14 18:19:06 -070018787 }
18788
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018789 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
18790 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053018791 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018792 {
18793 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018794 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070018795 " TDLS setup is ongoing. action %d declined.",
18796 __func__, MAC_ADDR_ARRAY(peer), action_code);
18797 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018798 }
18799 }
18800
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018801 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
18802 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080018803 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053018804 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
18805 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080018806 {
18807 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
18808 we return error code at 'add_station()'. Hence we have this
18809 check again in addtion to add_station().
18810 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018811 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080018812 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018813 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18814 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053018815 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
18816 __func__, MAC_ADDR_ARRAY(peer), action_code,
18817 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053018818 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080018819 }
18820 else
18821 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018822 /* maximum reached. tweak to send error code to peer and return
18823 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080018824 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018825 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18826 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053018827 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
18828 __func__, MAC_ADDR_ARRAY(peer), status_code,
18829 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070018830 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018831 /* fall through to send setup resp with failure status
18832 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080018833 }
18834 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018835 else
18836 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018837 mutex_lock(&pHddCtx->tdls_lock);
18838 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018839 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018840 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018841 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018842 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070018843 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
18844 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018845 return -EPERM;
18846 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018847 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018848 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018849 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018850
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018851 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053018852 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018853 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
18854 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018855
Hoonki Leea34dd892013-02-05 22:56:02 -080018856 /*Except teardown responder will not be used so just make 0*/
18857 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018858 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080018859 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070018860
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018861 mutex_lock(&pHddCtx->tdls_lock);
18862 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070018863
18864 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
18865 responder = pTdlsPeer->is_responder;
18866 else
Hoonki Leea34dd892013-02-05 22:56:02 -080018867 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070018868 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053018869 "%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 -070018870 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
18871 dialog_token, status_code, len);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018872 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070018873 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080018874 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018875 mutex_unlock(&pHddCtx->tdls_lock);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018876 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018877
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053018878 /* Discard TDLS setup if peer is removed by user app */
18879 if ((pHddCtx->cfg_ini->fTDLSExternalControl) &&
18880 ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
18881 (SIR_MAC_TDLS_SETUP_CNF == action_code) ||
18882 (SIR_MAC_TDLS_DIS_REQ == action_code))) {
18883
18884 mutex_lock(&pHddCtx->tdls_lock);
18885 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18886 if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) {
18887 mutex_unlock(&pHddCtx->tdls_lock);
18888 hddLog(LOGE, FL("TDLS External Control enabled, but peer "
18889 MAC_ADDRESS_STR " is not forced, so reject the action code %d"),
18890 MAC_ADDR_ARRAY(peer), action_code);
18891 return -EINVAL;
18892 }
18893 mutex_unlock(&pHddCtx->tdls_lock);
18894 }
18895
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053018896 /* For explicit trigger of DIS_REQ come out of BMPS for
18897 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070018898 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Deepthi Gowrif78f1f72016-03-21 13:13:28 +053018899 (SIR_MAC_TDLS_SETUP_CNF== action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053018900 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
18901 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070018902 {
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053018903 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter))) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018904 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053018905 "%s: Sending frame action_code %u.Disable BMPS", __func__,
18906 action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018907 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
18908 if (status != VOS_STATUS_SUCCESS) {
18909 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053018910 } else {
18911 pHddTdlsCtx->is_tdls_disabled_bmps = true;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018912 }
Hoonki Lee14621352013-04-16 17:51:19 -070018913 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018914 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018915 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018916 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
18917 }
18918 }
Hoonki Lee14621352013-04-16 17:51:19 -070018919 }
18920
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018921 /* make sure doesn't call send_mgmt() while it is pending */
18922 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
18923 {
18924 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080018925 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018926 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018927 ret = -EBUSY;
18928 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018929 }
18930
18931 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018932 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
18933
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018934 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
18935 pAdapter->sessionId, peer, action_code, dialog_token,
18936 status_code, peer_capability, (tANI_U8 *)buf, len,
18937 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018938
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018939 if (VOS_STATUS_SUCCESS != status)
18940 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018941 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18942 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018943 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018944 ret = -EINVAL;
18945 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018946 }
18947
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018948 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18949 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
18950 WAIT_TIME_TDLS_MGMT);
18951
Hoonki Leed37cbb32013-04-20 00:31:14 -070018952 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
18953 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
18954
18955 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018956 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070018957 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070018958 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070018959 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018960 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080018961
18962 if (pHddCtx->isLogpInProgress)
18963 {
18964 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18965 "%s: LOGP in Progress. Ignore!!!", __func__);
18966 return -EAGAIN;
18967 }
Abhishek Singh837adf22015-10-01 17:37:37 +053018968 if (rc <= 0)
18969 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
18970 WLAN_LOG_INDICATOR_HOST_DRIVER,
18971 WLAN_LOG_REASON_HDD_TIME_OUT,
18972 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080018973
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018974 ret = -EINVAL;
18975 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018976 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018977 else
18978 {
18979 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18980 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
18981 __func__, rc, pAdapter->mgmtTxCompletionStatus);
18982 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018983
Gopichand Nakkala05922802013-03-14 12:23:19 -070018984 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070018985 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018986 ret = max_sta_failed;
18987 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070018988 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018989
Hoonki Leea34dd892013-02-05 22:56:02 -080018990 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
18991 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018992 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018993 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
18994 }
Hoonki Leea34dd892013-02-05 22:56:02 -080018995 }
18996 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
18997 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018998 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018999 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
19000 }
Hoonki Leea34dd892013-02-05 22:56:02 -080019001 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019002
19003 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019004
19005tx_failed:
19006 /* add_station will be called before sending TDLS_SETUP_REQ and
19007 * TDLS_SETUP_RSP and as part of add_station driver will enable
19008 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
19009 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
19010 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
19011 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
19012 */
19013
19014 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
19015 (SIR_MAC_TDLS_SETUP_RSP == action_code))
19016 wlan_hdd_tdls_check_bmps(pAdapter);
19017 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019018}
19019
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019020#if TDLS_MGMT_VERSION2
19021static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
19022 u8 *peer, u8 action_code, u8 dialog_token,
19023 u16 status_code, u32 peer_capability,
19024 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019025#else /* TDLS_MGMT_VERSION2 */
19026#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
19027static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19028 struct net_device *dev,
19029 const u8 *peer, u8 action_code,
19030 u8 dialog_token, u16 status_code,
19031 u32 peer_capability, bool initiator,
19032 const u8 *buf, size_t len)
19033#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
19034static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19035 struct net_device *dev,
19036 const u8 *peer, u8 action_code,
19037 u8 dialog_token, u16 status_code,
19038 u32 peer_capability, const u8 *buf,
19039 size_t len)
19040#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
19041static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19042 struct net_device *dev,
19043 u8 *peer, u8 action_code,
19044 u8 dialog_token,
19045 u16 status_code, u32 peer_capability,
19046 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019047#else
19048static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
19049 u8 *peer, u8 action_code, u8 dialog_token,
19050 u16 status_code, const u8 *buf, size_t len)
19051#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019052#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019053{
19054 int ret;
19055
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019056 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019057#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019058 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
19059 dialog_token, status_code,
19060 peer_capability, buf, len);
19061#else /* TDLS_MGMT_VERSION2 */
19062#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
19063 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
19064 dialog_token, status_code,
19065 peer_capability, initiator,
19066 buf, len);
19067#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
19068 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
19069 dialog_token, status_code,
19070 peer_capability, buf, len);
19071#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
19072 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
19073 dialog_token, status_code,
19074 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019075#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019076 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
19077 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019078#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019079#endif
19080 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019081
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019082 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019083}
Atul Mittal115287b2014-07-08 13:26:33 +053019084
19085int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019086#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19087 const u8 *peer,
19088#else
Atul Mittal115287b2014-07-08 13:26:33 +053019089 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019090#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019091 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053019092 cfg80211_exttdls_callback callback)
19093{
19094
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019095 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053019096 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053019097 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053019098 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19099 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
19100 __func__, MAC_ADDR_ARRAY(peer));
19101
19102 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
19103 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
19104
19105 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019106 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
19107 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
19108 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053019109 return -ENOTSUPP;
19110 }
19111
19112 /* To cater the requirement of establishing the TDLS link
19113 * irrespective of the data traffic , get an entry of TDLS peer.
19114 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053019115 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019116 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
19117 if (pTdlsPeer == NULL) {
19118 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19119 "%s: peer " MAC_ADDRESS_STR " not existing",
19120 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053019121 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019122 return -EINVAL;
19123 }
19124
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053019125 /* check FW TDLS Off Channel capability */
19126 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053019127 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053019128 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019129 {
19130 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
19131 pTdlsPeer->peerParams.global_operating_class =
19132 tdls_peer_params->global_operating_class;
19133 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
19134 pTdlsPeer->peerParams.min_bandwidth_kbps =
19135 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053019136 /* check configured channel is valid, non dfs and
19137 * not current operating channel */
19138 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
19139 tdls_peer_params->channel)) &&
19140 (pHddStaCtx) &&
19141 (tdls_peer_params->channel !=
19142 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019143 {
19144 pTdlsPeer->isOffChannelConfigured = TRUE;
19145 }
19146 else
19147 {
19148 pTdlsPeer->isOffChannelConfigured = FALSE;
19149 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19150 "%s: Configured Tdls Off Channel is not valid", __func__);
19151
19152 }
19153 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053019154 "%s: tdls_off_channel %d isOffChannelConfigured %d "
19155 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019156 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053019157 pTdlsPeer->isOffChannelConfigured,
19158 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019159 }
19160 else
19161 {
19162 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053019163 "%s: TDLS off channel FW capability %d, "
19164 "host capab %d or Invalid TDLS Peer Params", __func__,
19165 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
19166 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019167 }
19168
Atul Mittal115287b2014-07-08 13:26:33 +053019169 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
19170
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019171 mutex_unlock(&pHddCtx->tdls_lock);
19172
Atul Mittal115287b2014-07-08 13:26:33 +053019173 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19174 " %s TDLS Add Force Peer Failed",
19175 __func__);
19176 return -EINVAL;
19177 }
19178 /*EXT TDLS*/
19179
19180 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019181 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019182 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19183 " %s TDLS set callback Failed",
19184 __func__);
19185 return -EINVAL;
19186 }
19187
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019188 mutex_unlock(&pHddCtx->tdls_lock);
19189
Atul Mittal115287b2014-07-08 13:26:33 +053019190 return(0);
19191
19192}
19193
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019194int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
19195#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19196 const u8 *peer
19197#else
19198 u8 *peer
19199#endif
19200)
Atul Mittal115287b2014-07-08 13:26:33 +053019201{
19202
19203 hddTdlsPeer_t *pTdlsPeer;
19204 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053019205
Atul Mittal115287b2014-07-08 13:26:33 +053019206 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19207 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
19208 __func__, MAC_ADDR_ARRAY(peer));
19209
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053019210 if (0 != wlan_hdd_validate_context(pHddCtx)) {
19211 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
19212 return -EINVAL;
19213 }
19214
Atul Mittal115287b2014-07-08 13:26:33 +053019215 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
19216 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
19217
19218 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019219 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
19220 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
19221 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053019222 return -ENOTSUPP;
19223 }
19224
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019225 mutex_lock(&pHddCtx->tdls_lock);
19226 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Atul Mittal115287b2014-07-08 13:26:33 +053019227
19228 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019229 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019230 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019231 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053019232 __func__, MAC_ADDR_ARRAY(peer));
19233 return -EINVAL;
19234 }
19235 else {
19236 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
19237 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053019238 hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_EXT_CTRL,
19239 pTdlsPeer->peerMac);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019240 /* if channel switch is configured, reset
19241 the channel for this peer */
19242 if (TRUE == pTdlsPeer->isOffChannelConfigured)
19243 {
19244 pTdlsPeer->peerParams.channel = 0;
19245 pTdlsPeer->isOffChannelConfigured = FALSE;
19246 }
Atul Mittal115287b2014-07-08 13:26:33 +053019247 }
19248
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019249 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019250 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019251 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053019252 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019253 }
Atul Mittal115287b2014-07-08 13:26:33 +053019254
19255 /*EXT TDLS*/
19256
19257 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019258 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019259 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19260 " %s TDLS set callback Failed",
19261 __func__);
19262 return -EINVAL;
19263 }
Atul Mittal115287b2014-07-08 13:26:33 +053019264
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019265 mutex_unlock(&pHddCtx->tdls_lock);
19266
19267 return(0);
Atul Mittal115287b2014-07-08 13:26:33 +053019268}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019269static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019270#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19271 const u8 *peer,
19272#else
19273 u8 *peer,
19274#endif
19275 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019276{
19277 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19278 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019279 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019280 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019281
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019282 ENTER();
19283
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053019284 if (!pAdapter) {
19285 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
19286 return -EINVAL;
19287 }
19288
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019289 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19290 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
19291 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019292 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019293 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019294 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070019295 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019296 return -EINVAL;
19297 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080019298
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019299 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019300 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080019301 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019302 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080019303 }
19304
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019305
19306 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080019307 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019308 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080019309 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019310 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
19311 "Cannot process TDLS commands",
19312 pHddCtx->cfg_ini->fEnableTDLSSupport,
19313 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019314 return -ENOTSUPP;
19315 }
19316
19317 switch (oper) {
19318 case NL80211_TDLS_ENABLE_LINK:
19319 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019320 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019321 long ret;
Hanumantha Reddy Pothulada389492016-02-11 17:29:27 +053019322 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams = { {0}, 0,
19323 0, 0, 0, 0, 0, 0, {0}, 0, {0} };
Agarwal Ashish16020c42014-12-29 22:01:11 +053019324 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019325 tANI_U16 numCurrTdlsPeers = 0;
19326 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053019327 tANI_U8 suppChannelLen = 0;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019328 tSirMacAddr peerMac;
19329 int channel;
19330 tTDLSLinkStatus peer_status = eTDLS_LINK_IDLE;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019331
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019332 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19333 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
19334 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019335
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019336 mutex_lock(&pHddCtx->tdls_lock);
19337 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053019338 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053019339 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019340 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053019341 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
19342 " (oper %d) not exsting. ignored",
19343 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
19344 return -EINVAL;
19345 }
19346
19347 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19348 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
19349 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
19350 "NL80211_TDLS_ENABLE_LINK");
19351
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070019352 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
19353 {
19354 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
19355 MAC_ADDRESS_STR " failed",
19356 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019357 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070019358 return -EINVAL;
19359 }
19360
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053019361 /* before starting tdls connection, set tdls
19362 * off channel established status to default value */
19363 pTdlsPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019364
19365 mutex_unlock(&pHddCtx->tdls_lock);
19366
Deepthi Gowri2d85bbf2016-07-25 15:43:31 +053019367 wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019368 /* TDLS Off Channel, Disable tdls channel switch,
19369 when there are more than one tdls link */
19370 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053019371 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019372 {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019373 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019374 /* get connected peer and send disable tdls off chan */
19375 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019376 if ((connPeer) &&
19377 (connPeer->isOffChannelSupported == TRUE) &&
19378 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019379 {
19380 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19381 "%s: More then one peer connected, Disable "
19382 "TDLS channel switch", __func__);
19383
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053019384 connPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019385 vos_mem_copy(peerMac, connPeer->peerMac, sizeof (tSirMacAddr));
19386 channel = connPeer->peerParams.channel;
19387
19388 mutex_unlock(&pHddCtx->tdls_lock);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019389
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019390 ret = sme_SendTdlsChanSwitchReq(
19391 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019392 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019393 peerMac,
19394 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019395 TDLS_OFF_CHANNEL_BW_OFFSET,
19396 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019397 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019398 hddLog(VOS_TRACE_LEVEL_ERROR,
19399 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019400 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019401 }
19402 else
19403 {
19404 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19405 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019406 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019407 "isOffChannelConfigured %d",
19408 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019409 (connPeer ? (connPeer->isOffChannelSupported)
19410 : -1),
19411 (connPeer ? (connPeer->isOffChannelConfigured)
19412 : -1));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019413 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019414 }
19415 }
19416
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019417 mutex_lock(&pHddCtx->tdls_lock);
19418 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
19419 if ( NULL == pTdlsPeer ) {
19420 mutex_unlock(&pHddCtx->tdls_lock);
19421 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19422 "%s: " MAC_ADDRESS_STR
19423 " (oper %d) peer got freed in other context. ignored",
19424 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
19425 return -EINVAL;
19426 }
19427 peer_status = pTdlsPeer->link_status;
19428 mutex_unlock(&pHddCtx->tdls_lock);
19429
19430 if (eTDLS_LINK_CONNECTED != peer_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019431 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019432 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053019433
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019434 if (0 != wlan_hdd_tdls_get_link_establish_params(
19435 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019436 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019437 return -EINVAL;
19438 }
19439 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053019440
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019441 ret = sme_SendTdlsLinkEstablishParams(
19442 WLAN_HDD_GET_HAL_CTX(pAdapter),
19443 pAdapter->sessionId, peer,
19444 &tdlsLinkEstablishParams);
19445 if (ret != VOS_STATUS_SUCCESS) {
19446 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
19447 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019448 /* Send TDLS peer UAPSD capabilities to the firmware and
19449 * register with the TL on after the response for this operation
19450 * is received .
19451 */
19452 ret = wait_for_completion_interruptible_timeout(
19453 &pAdapter->tdls_link_establish_req_comp,
19454 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
Masti, Narayanraddie1892a52015-12-15 15:01:01 +053019455
19456 mutex_lock(&pHddCtx->tdls_lock);
19457 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
19458 if ( NULL == pTdlsPeer ) {
19459 mutex_unlock(&pHddCtx->tdls_lock);
19460 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19461 "%s %d: " MAC_ADDRESS_STR
19462 " (oper %d) peer got freed in other context. ignored",
19463 __func__, __LINE__, MAC_ADDR_ARRAY(peer),
19464 (int)oper);
19465 return -EINVAL;
19466 }
19467 peer_status = pTdlsPeer->link_status;
19468 mutex_unlock(&pHddCtx->tdls_lock);
19469
19470 if (ret <= 0 || (peer_status == eTDLS_LINK_TEARING))
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019471 {
19472 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019473 FL("Link Establish Request Failed Status %ld"),
19474 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019475 return -EINVAL;
19476 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053019477 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019478
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019479 mutex_lock(&pHddCtx->tdls_lock);
19480 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
19481 if ( NULL == pTdlsPeer ) {
19482 mutex_unlock(&pHddCtx->tdls_lock);
19483 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19484 "%s: " MAC_ADDRESS_STR
19485 " (oper %d) peer got freed in other context. ignored",
19486 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
19487 return -EINVAL;
19488 }
19489
Atul Mittal115287b2014-07-08 13:26:33 +053019490 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
19491 eTDLS_LINK_CONNECTED,
19492 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053019493 staDesc.ucSTAId = pTdlsPeer->staId;
19494 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053019495
19496 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19497 "%s: tdlsLinkEstablishParams of peer "
19498 MAC_ADDRESS_STR "uapsdQueues: %d"
19499 "qos: %d maxSp: %d isBufSta: %d isOffChannelSupported: %d"
19500 "isResponder: %d peerstaId: %d",
19501 __func__,
19502 MAC_ADDR_ARRAY(tdlsLinkEstablishParams.peerMac),
19503 tdlsLinkEstablishParams.uapsdQueues,
19504 tdlsLinkEstablishParams.qos,
19505 tdlsLinkEstablishParams.maxSp,
19506 tdlsLinkEstablishParams.isBufSta,
19507 tdlsLinkEstablishParams.isOffChannelSupported,
19508 tdlsLinkEstablishParams.isResponder,
19509 pTdlsPeer->staId);
19510
19511 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19512 "%s: StaDesc ucSTAId: %d ucQosEnabled: %d",
19513 __func__,
19514 staDesc.ucSTAId,
19515 staDesc.ucQosEnabled);
19516
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019517 ret = WLANTL_UpdateTdlsSTAClient(
19518 pHddCtx->pvosContext,
19519 &staDesc);
19520 if (ret != VOS_STATUS_SUCCESS) {
19521 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
19522 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053019523
Gopichand Nakkala471708b2013-06-04 20:03:01 +053019524 /* Mark TDLS client Authenticated .*/
19525 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
19526 pTdlsPeer->staId,
19527 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070019528 if (VOS_STATUS_SUCCESS == status)
19529 {
Hoonki Lee14621352013-04-16 17:51:19 -070019530 if (pTdlsPeer->is_responder == 0)
19531 {
19532 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053019533 tdlsConnInfo_t *tdlsInfo;
19534
19535 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
19536
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053019537 if (!vos_timer_is_initialized(
19538 &pTdlsPeer->initiatorWaitTimeoutTimer))
19539 {
19540 /* Initialize initiator wait callback */
19541 vos_timer_init(
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053019542 &pTdlsPeer->initiatorWaitTimeoutTimer,
19543 VOS_TIMER_TYPE_SW,
19544 wlan_hdd_tdls_initiator_wait_cb,
19545 tdlsInfo);
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053019546 }
Hoonki Lee14621352013-04-16 17:51:19 -070019547 wlan_hdd_tdls_timer_restart(pAdapter,
19548 &pTdlsPeer->initiatorWaitTimeoutTimer,
19549 WAIT_TIME_TDLS_INITIATOR);
19550 /* suspend initiator TX until it receives direct packet from the
19551 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019552 ret = WLANTL_SuspendDataTx(
19553 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
19554 &staId, NULL);
19555 if (ret != VOS_STATUS_SUCCESS) {
19556 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
19557 }
Hoonki Lee14621352013-04-16 17:51:19 -070019558 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019559
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053019560 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019561 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053019562 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019563 suppChannelLen =
19564 tdlsLinkEstablishParams.supportedChannelsLen;
19565
19566 if ((suppChannelLen > 0) &&
19567 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
19568 {
19569 tANI_U8 suppPeerChannel = 0;
19570 int i = 0;
19571 for (i = 0U; i < suppChannelLen; i++)
19572 {
19573 suppPeerChannel =
19574 tdlsLinkEstablishParams.supportedChannels[i];
19575
19576 pTdlsPeer->isOffChannelSupported = FALSE;
19577 if (suppPeerChannel ==
19578 pTdlsPeer->peerParams.channel)
19579 {
19580 pTdlsPeer->isOffChannelSupported = TRUE;
19581 break;
19582 }
19583 }
19584 }
19585 else
19586 {
19587 pTdlsPeer->isOffChannelSupported = FALSE;
19588 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053019589 }
19590 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19591 "%s: TDLS channel switch request for channel "
19592 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019593 "%d isOffChannelSupported %d", __func__,
19594 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053019595 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019596 suppChannelLen,
19597 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053019598
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019599 /* TDLS Off Channel, Enable tdls channel switch,
19600 when their is only one tdls link and it supports */
19601 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
19602 if ((numCurrTdlsPeers == 1) &&
19603 (TRUE == pTdlsPeer->isOffChannelSupported) &&
19604 (TRUE == pTdlsPeer->isOffChannelConfigured))
19605 {
19606 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19607 "%s: Send TDLS channel switch request for channel %d",
19608 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053019609
19610 pTdlsPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019611 vos_mem_copy(peerMac, pTdlsPeer->peerMac, sizeof (tSirMacAddr));
19612 channel = pTdlsPeer->peerParams.channel;
19613
19614 mutex_unlock(&pHddCtx->tdls_lock);
19615
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019616 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
19617 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019618 peerMac,
19619 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019620 TDLS_OFF_CHANNEL_BW_OFFSET,
19621 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019622 if (ret != VOS_STATUS_SUCCESS) {
19623 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
19624 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019625 }
19626 else
19627 {
19628 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19629 "%s: TDLS channel switch request not sent"
19630 " numCurrTdlsPeers %d "
19631 "isOffChannelSupported %d "
19632 "isOffChannelConfigured %d",
19633 __func__, numCurrTdlsPeers,
19634 pTdlsPeer->isOffChannelSupported,
19635 pTdlsPeer->isOffChannelConfigured);
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019636 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019637 }
19638
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070019639 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019640 else
19641 mutex_unlock(&pHddCtx->tdls_lock);
19642
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019643 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053019644
19645 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053019646 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
19647 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053019648 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053019649 int ac;
19650 uint8 ucAc[4] = { WLANTL_AC_VO,
19651 WLANTL_AC_VI,
19652 WLANTL_AC_BK,
19653 WLANTL_AC_BE };
19654 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
19655 for(ac=0; ac < 4; ac++)
19656 {
19657 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
19658 pTdlsPeer->staId, ucAc[ac],
19659 tlTid[ac], tlTid[ac], 0, 0,
19660 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019661 if (status != VOS_STATUS_SUCCESS) {
19662 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
19663 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053019664 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053019665 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019666 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019667
Bhargav Shah66896792015-10-01 18:17:37 +053019668 /* stop TCP delack timer if TDLS is enable */
19669 set_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
19670 hdd_manage_delack_timer(pHddCtx);
Abhishek Singh67fa6bc2016-01-05 15:57:19 +053019671 hdd_wlan_tdls_enable_link_event(peer,
19672 pTdlsPeer->isOffChannelSupported,
19673 pTdlsPeer->isOffChannelConfigured,
19674 pTdlsPeer->isOffChannelEstablished);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019675 }
19676 break;
19677 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080019678 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019679 tANI_U16 numCurrTdlsPeers = 0;
19680 hddTdlsPeer_t *connPeer = NULL;
19681
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019682 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19683 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
19684 __func__, MAC_ADDR_ARRAY(peer));
19685
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019686 mutex_lock(&pHddCtx->tdls_lock);
19687 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Sunil Dutt41de4e22013-11-14 18:09:02 +053019688
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019689
Sunil Dutt41de4e22013-11-14 18:09:02 +053019690 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019691 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053019692 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
19693 " (oper %d) not exsting. ignored",
19694 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
19695 return -EINVAL;
19696 }
19697
19698 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19699 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
19700 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
19701 "NL80211_TDLS_DISABLE_LINK");
19702
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019703 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080019704 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019705 long status;
19706
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053019707 /* set tdls off channel status to false for this peer */
19708 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053019709 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
19710 eTDLS_LINK_TEARING,
19711 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
19712 eTDLS_LINK_UNSPECIFIED:
19713 eTDLS_LINK_DROPPED_BY_REMOTE);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019714 mutex_unlock(&pHddCtx->tdls_lock);
19715
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019716 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
19717
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019718 status = sme_DeleteTdlsPeerSta(
19719 WLAN_HDD_GET_HAL_CTX(pAdapter),
19720 pAdapter->sessionId, peer );
19721 if (status != VOS_STATUS_SUCCESS) {
19722 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
19723 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019724
19725 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
19726 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019727
19728 mutex_lock(&pHddCtx->tdls_lock);
19729 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
19730 if ( NULL == pTdlsPeer ) {
19731 mutex_unlock(&pHddCtx->tdls_lock);
19732 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
19733 " peer was freed in other context",
19734 __func__, MAC_ADDR_ARRAY(peer));
19735 return -EINVAL;
19736 }
19737
Atul Mittal271a7652014-09-12 13:18:22 +053019738 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053019739 eTDLS_LINK_IDLE,
19740 eTDLS_LINK_UNSPECIFIED);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019741 mutex_unlock(&pHddCtx->tdls_lock);
19742
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019743 if (status <= 0)
19744 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019745 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19746 "%s: Del station failed status %ld",
19747 __func__, status);
19748 return -EPERM;
19749 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019750
19751 /* TDLS Off Channel, Enable tdls channel switch,
19752 when their is only one tdls link and it supports */
19753 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
19754 if (numCurrTdlsPeers == 1)
19755 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019756 tSirMacAddr peerMac;
19757 int channel;
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053019758
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019759 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019760 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053019761
19762 if (connPeer == NULL) {
19763 mutex_unlock(&pHddCtx->tdls_lock);
19764 hddLog(VOS_TRACE_LEVEL_ERROR,
19765 "%s connPeer is NULL", __func__);
19766 return -EINVAL;
19767 }
19768
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019769 vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr));
19770 channel = connPeer->peerParams.channel;
19771
19772 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19773 "%s: TDLS channel switch "
19774 "isOffChannelSupported %d "
19775 "isOffChannelConfigured %d "
19776 "isOffChannelEstablished %d",
19777 __func__,
19778 (connPeer ? connPeer->isOffChannelSupported : -1),
19779 (connPeer ? connPeer->isOffChannelConfigured : -1),
19780 (connPeer ? connPeer->isOffChannelEstablished : -1));
19781
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019782 if ((connPeer) &&
19783 (connPeer->isOffChannelSupported == TRUE) &&
19784 (connPeer->isOffChannelConfigured == TRUE))
19785 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053019786 connPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019787 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019788 status = sme_SendTdlsChanSwitchReq(
19789 WLAN_HDD_GET_HAL_CTX(pAdapter),
19790 pAdapter->sessionId,
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019791 peerMac,
19792 channel,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019793 TDLS_OFF_CHANNEL_BW_OFFSET,
19794 TDLS_CHANNEL_SWITCH_ENABLE);
19795 if (status != VOS_STATUS_SUCCESS) {
19796 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
19797 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019798 }
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019799 else
19800 mutex_unlock(&pHddCtx->tdls_lock);
19801 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019802 else
19803 {
19804 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19805 "%s: TDLS channel switch request not sent "
19806 "numCurrTdlsPeers %d ",
19807 __func__, numCurrTdlsPeers);
19808 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080019809 }
19810 else
19811 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019812 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019813 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19814 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080019815 }
Bhargav Shah66896792015-10-01 18:17:37 +053019816 if (numCurrTdlsPeers == 0) {
19817 /* start TCP delack timer if TDLS is disable */
19818 clear_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
19819 hdd_manage_delack_timer(pHddCtx);
19820 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080019821 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019822 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019823 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053019824 {
Atul Mittal115287b2014-07-08 13:26:33 +053019825 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053019826
Atul Mittal115287b2014-07-08 13:26:33 +053019827 if (0 != status)
19828 {
19829 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019830 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053019831 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053019832 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053019833 break;
19834 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019835 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053019836 {
Atul Mittal115287b2014-07-08 13:26:33 +053019837 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
19838 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019839 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053019840 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053019841
Atul Mittal115287b2014-07-08 13:26:33 +053019842 if (0 != status)
19843 {
19844 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019845 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053019846 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053019847 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053019848 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053019849 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019850 case NL80211_TDLS_DISCOVERY_REQ:
19851 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019852 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019853 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019854 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019855 return -ENOTSUPP;
19856 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019857 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19858 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019859 return -ENOTSUPP;
19860 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019861
19862 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019863 return 0;
19864}
Chilam NG571c65a2013-01-19 12:27:36 +053019865
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019866static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019867#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19868 const u8 *peer,
19869#else
19870 u8 *peer,
19871#endif
19872 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019873{
19874 int ret;
19875
19876 vos_ssr_protect(__func__);
19877 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
19878 vos_ssr_unprotect(__func__);
19879
19880 return ret;
19881}
19882
Chilam NG571c65a2013-01-19 12:27:36 +053019883int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
19884 struct net_device *dev, u8 *peer)
19885{
Arif Hussaina7c8e412013-11-20 11:06:42 -080019886 hddLog(VOS_TRACE_LEVEL_INFO,
19887 "tdls send discover req: "MAC_ADDRESS_STR,
19888 MAC_ADDR_ARRAY(peer));
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019889#if TDLS_MGMT_VERSION2
19890 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19891 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
19892#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019893#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
19894 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19895 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
19896#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
19897 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19898 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
19899#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
19900 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19901 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
19902#else
Chilam NG571c65a2013-01-19 12:27:36 +053019903 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19904 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019905#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019906#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053019907}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019908#endif
19909
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019910#ifdef WLAN_FEATURE_GTK_OFFLOAD
19911/*
19912 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
19913 * Callback rountine called upon receiving response for
19914 * get offload info
19915 */
19916void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
19917 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
19918{
19919
19920 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019921 tANI_U8 tempReplayCounter[8];
19922 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019923
19924 ENTER();
19925
19926 if (NULL == pAdapter)
19927 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053019928 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019929 "%s: HDD adapter is Null", __func__);
19930 return ;
19931 }
19932
19933 if (NULL == pGtkOffloadGetInfoRsp)
19934 {
19935 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19936 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
19937 return ;
19938 }
19939
19940 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
19941 {
19942 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19943 "%s: wlan Failed to get replay counter value",
19944 __func__);
19945 return ;
19946 }
19947
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019948 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
19949 /* Update replay counter */
19950 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
19951 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
19952
19953 {
19954 /* changing from little to big endian since supplicant
19955 * works on big endian format
19956 */
19957 int i;
19958 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
19959
19960 for (i = 0; i < 8; i++)
19961 {
19962 tempReplayCounter[7-i] = (tANI_U8)p[i];
19963 }
19964 }
19965
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019966 /* Update replay counter to NL */
19967 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019968 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019969}
19970
19971/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019972 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019973 * This function is used to offload GTK rekeying job to the firmware.
19974 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019975int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019976 struct cfg80211_gtk_rekey_data *data)
19977{
19978 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19979 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
19980 hdd_station_ctx_t *pHddStaCtx;
19981 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019982 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019983 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019984 eHalStatus status = eHAL_STATUS_FAILURE;
19985
19986 ENTER();
19987
19988 if (NULL == pAdapter)
19989 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019990 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019991 "%s: HDD adapter is Null", __func__);
19992 return -ENODEV;
19993 }
19994
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019995 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19996 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
19997 pAdapter->sessionId, pAdapter->device_mode));
19998
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019999 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020000 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020001 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020002 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020003 }
20004
20005 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
20006 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
20007 if (NULL == hHal)
20008 {
20009 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20010 "%s: HAL context is Null!!!", __func__);
20011 return -EAGAIN;
20012 }
20013
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020014 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
20015 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
20016 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
20017 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020018 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020019 {
20020 /* changing from big to little endian since driver
20021 * works on little endian format
20022 */
20023 tANI_U8 *p =
20024 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
20025 int i;
20026
20027 for (i = 0; i < 8; i++)
20028 {
20029 p[7-i] = data->replay_ctr[i];
20030 }
20031 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020032
20033 if (TRUE == pHddCtx->hdd_wlan_suspended)
20034 {
20035 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020036 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
20037 sizeof (tSirGtkOffloadParams));
20038 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020039 pAdapter->sessionId);
20040
20041 if (eHAL_STATUS_SUCCESS != status)
20042 {
20043 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20044 "%s: sme_SetGTKOffload failed, returned %d",
20045 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053020046
20047 /* Need to clear any trace of key value in the memory.
20048 * Thus zero out the memory even though it is local
20049 * variable.
20050 */
20051 vos_mem_zero(&hddGtkOffloadReqParams,
20052 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020053 return status;
20054 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020055 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20056 "%s: sme_SetGTKOffload successfull", __func__);
20057 }
20058 else
20059 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020060 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20061 "%s: wlan not suspended GTKOffload request is stored",
20062 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020063 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020064
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053020065 /* Need to clear any trace of key value in the memory.
20066 * Thus zero out the memory even though it is local
20067 * variable.
20068 */
20069 vos_mem_zero(&hddGtkOffloadReqParams,
20070 sizeof(hddGtkOffloadReqParams));
20071
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020072 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020073 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020074}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020075
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020076int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
20077 struct cfg80211_gtk_rekey_data *data)
20078{
20079 int ret;
20080
20081 vos_ssr_protect(__func__);
20082 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
20083 vos_ssr_unprotect(__func__);
20084
20085 return ret;
20086}
20087#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020088/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020089 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020090 * This function is used to set access control policy
20091 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020092static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
20093 struct net_device *dev,
20094 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020095{
20096 int i;
20097 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20098 hdd_hostapd_state_t *pHostapdState;
20099 tsap_Config_t *pConfig;
20100 v_CONTEXT_t pVosContext = NULL;
20101 hdd_context_t *pHddCtx;
20102 int status;
20103
20104 ENTER();
20105
20106 if (NULL == pAdapter)
20107 {
20108 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20109 "%s: HDD adapter is Null", __func__);
20110 return -ENODEV;
20111 }
20112
20113 if (NULL == params)
20114 {
20115 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20116 "%s: params is Null", __func__);
20117 return -EINVAL;
20118 }
20119
20120 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
20121 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020122 if (0 != status)
20123 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020124 return status;
20125 }
20126
20127 pVosContext = pHddCtx->pvosContext;
20128 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
20129
20130 if (NULL == pHostapdState)
20131 {
20132 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20133 "%s: pHostapdState is Null", __func__);
20134 return -EINVAL;
20135 }
20136
20137 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
20138 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053020139 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20140 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
20141 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020142
20143 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
20144 {
20145 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
20146
20147 /* default value */
20148 pConfig->num_accept_mac = 0;
20149 pConfig->num_deny_mac = 0;
20150
20151 /**
20152 * access control policy
20153 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
20154 * listed in hostapd.deny file.
20155 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
20156 * listed in hostapd.accept file.
20157 */
20158 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
20159 {
20160 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
20161 }
20162 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
20163 {
20164 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
20165 }
20166 else
20167 {
20168 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20169 "%s:Acl Policy : %d is not supported",
20170 __func__, params->acl_policy);
20171 return -ENOTSUPP;
20172 }
20173
20174 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
20175 {
20176 pConfig->num_accept_mac = params->n_acl_entries;
20177 for (i = 0; i < params->n_acl_entries; i++)
20178 {
20179 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20180 "** Add ACL MAC entry %i in WhiletList :"
20181 MAC_ADDRESS_STR, i,
20182 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
20183
20184 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
20185 sizeof(qcmacaddr));
20186 }
20187 }
20188 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
20189 {
20190 pConfig->num_deny_mac = params->n_acl_entries;
20191 for (i = 0; i < params->n_acl_entries; i++)
20192 {
20193 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20194 "** Add ACL MAC entry %i in BlackList :"
20195 MAC_ADDRESS_STR, i,
20196 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
20197
20198 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
20199 sizeof(qcmacaddr));
20200 }
20201 }
20202
20203 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
20204 {
20205 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20206 "%s: SAP Set Mac Acl fail", __func__);
20207 return -EINVAL;
20208 }
20209 }
20210 else
20211 {
20212 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053020213 "%s: Invalid device_mode = %s (%d)",
20214 __func__, hdd_device_modetoString(pAdapter->device_mode),
20215 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020216 return -EINVAL;
20217 }
20218
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020219 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020220 return 0;
20221}
20222
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020223static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
20224 struct net_device *dev,
20225 const struct cfg80211_acl_data *params)
20226{
20227 int ret;
20228 vos_ssr_protect(__func__);
20229 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
20230 vos_ssr_unprotect(__func__);
20231
20232 return ret;
20233}
20234
Leo Chang9056f462013-08-01 19:21:11 -070020235#ifdef WLAN_NL80211_TESTMODE
20236#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070020237void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070020238(
20239 void *pAdapter,
20240 void *indCont
20241)
20242{
Leo Changd9df8aa2013-09-26 13:32:26 -070020243 tSirLPHBInd *lphbInd;
20244 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053020245 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070020246
20247 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070020248 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070020249
c_hpothu73f35e62014-04-18 13:40:08 +053020250 if (pAdapter == NULL)
20251 {
20252 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20253 "%s: pAdapter is NULL\n",__func__);
20254 return;
20255 }
20256
Leo Chang9056f462013-08-01 19:21:11 -070020257 if (NULL == indCont)
20258 {
20259 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070020260 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070020261 return;
20262 }
20263
c_hpothu73f35e62014-04-18 13:40:08 +053020264 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070020265 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070020266 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053020267 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070020268 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070020269 GFP_ATOMIC);
20270 if (!skb)
20271 {
20272 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20273 "LPHB timeout, NL buffer alloc fail");
20274 return;
20275 }
20276
Leo Changac3ba772013-10-07 09:47:04 -070020277 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070020278 {
20279 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20280 "WLAN_HDD_TM_ATTR_CMD put fail");
20281 goto nla_put_failure;
20282 }
Leo Changac3ba772013-10-07 09:47:04 -070020283 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070020284 {
20285 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20286 "WLAN_HDD_TM_ATTR_TYPE put fail");
20287 goto nla_put_failure;
20288 }
Leo Changac3ba772013-10-07 09:47:04 -070020289 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070020290 sizeof(tSirLPHBInd), lphbInd))
20291 {
20292 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20293 "WLAN_HDD_TM_ATTR_DATA put fail");
20294 goto nla_put_failure;
20295 }
Leo Chang9056f462013-08-01 19:21:11 -070020296 cfg80211_testmode_event(skb, GFP_ATOMIC);
20297 return;
20298
20299nla_put_failure:
20300 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20301 "NLA Put fail");
20302 kfree_skb(skb);
20303
20304 return;
20305}
20306#endif /* FEATURE_WLAN_LPHB */
20307
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020308static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070020309{
20310 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
20311 int err = 0;
20312#ifdef FEATURE_WLAN_LPHB
20313 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070020314 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020315
20316 ENTER();
20317
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053020318 err = wlan_hdd_validate_context(pHddCtx);
20319 if (0 != err)
20320 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053020321 return err;
20322 }
Leo Chang9056f462013-08-01 19:21:11 -070020323#endif /* FEATURE_WLAN_LPHB */
20324
20325 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
20326 if (err)
20327 {
20328 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20329 "%s Testmode INV ATTR", __func__);
20330 return err;
20331 }
20332
20333 if (!tb[WLAN_HDD_TM_ATTR_CMD])
20334 {
20335 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20336 "%s Testmode INV CMD", __func__);
20337 return -EINVAL;
20338 }
20339
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053020340 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20341 TRACE_CODE_HDD_CFG80211_TESTMODE,
20342 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070020343 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
20344 {
20345#ifdef FEATURE_WLAN_LPHB
20346 /* Low Power Heartbeat configuration request */
20347 case WLAN_HDD_TM_CMD_WLAN_HB:
20348 {
20349 int buf_len;
20350 void *buf;
20351 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080020352 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070020353
20354 if (!tb[WLAN_HDD_TM_ATTR_DATA])
20355 {
20356 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20357 "%s Testmode INV DATA", __func__);
20358 return -EINVAL;
20359 }
20360
20361 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
20362 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080020363
Manjeet Singh3c577442017-02-10 19:03:38 +053020364 if (buf_len > sizeof(*hb_params)) {
20365 hddLog(LOGE, FL("buf_len=%d exceeded hb_params size limit"),
20366 buf_len);
20367 return -ERANGE;
20368 }
20369
Amar Singhal05852702014-02-04 14:40:00 -080020370 hb_params_temp =(tSirLPHBReq *)buf;
20371 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
20372 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
20373 return -EINVAL;
20374
Leo Chang9056f462013-08-01 19:21:11 -070020375 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
20376 if (NULL == hb_params)
20377 {
20378 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20379 "%s Request Buffer Alloc Fail", __func__);
20380 return -EINVAL;
20381 }
20382
Ashish Kumar Dhanotiya3a8c0a72017-07-13 18:58:59 +053020383 vos_mem_zero(hb_params, sizeof(tSirLPHBReq));
Leo Chang9056f462013-08-01 19:21:11 -070020384 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070020385 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
20386 hb_params,
20387 wlan_hdd_cfg80211_lphb_ind_handler);
20388 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070020389 {
Leo Changd9df8aa2013-09-26 13:32:26 -070020390 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20391 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070020392 vos_mem_free(hb_params);
20393 }
Leo Chang9056f462013-08-01 19:21:11 -070020394 return 0;
20395 }
20396#endif /* FEATURE_WLAN_LPHB */
20397 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020398 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20399 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070020400 return -EOPNOTSUPP;
20401 }
20402
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020403 EXIT();
20404 return err;
Leo Chang9056f462013-08-01 19:21:11 -070020405}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020406
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053020407static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
20408#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
20409 struct wireless_dev *wdev,
20410#endif
20411 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020412{
20413 int ret;
20414
20415 vos_ssr_protect(__func__);
20416 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
20417 vos_ssr_unprotect(__func__);
20418
20419 return ret;
20420}
Leo Chang9056f462013-08-01 19:21:11 -070020421#endif /* CONFIG_NL80211_TESTMODE */
20422
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053020423extern void hdd_set_wlan_suspend_mode(bool suspend);
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020424static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020425 struct net_device *dev,
20426 int idx, struct survey_info *survey)
20427{
20428 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20429 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053020430 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020431 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053020432 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020433 v_S7_t snr,rssi;
20434 int status, i, j, filled = 0;
20435
20436 ENTER();
20437
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020438 if (NULL == pAdapter)
20439 {
20440 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20441 "%s: HDD adapter is Null", __func__);
20442 return -ENODEV;
20443 }
20444
20445 if (NULL == wiphy)
20446 {
20447 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20448 "%s: wiphy is Null", __func__);
20449 return -ENODEV;
20450 }
20451
20452 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
20453 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020454 if (0 != status)
20455 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020456 return status;
20457 }
20458
Mihir Sheted9072e02013-08-21 17:02:29 +053020459 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
20460
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020461 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053020462 0 != pAdapter->survey_idx ||
20463 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020464 {
20465 /* The survey dump ops when implemented completely is expected to
20466 * return a survey of all channels and the ops is called by the
20467 * kernel with incremental values of the argument 'idx' till it
20468 * returns -ENONET. But we can only support the survey for the
20469 * operating channel for now. survey_idx is used to track
20470 * that the ops is called only once and then return -ENONET for
20471 * the next iteration
20472 */
20473 pAdapter->survey_idx = 0;
20474 return -ENONET;
20475 }
20476
Mukul Sharma9d5233b2015-06-11 20:28:20 +053020477 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
20478 {
20479 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20480 "%s: Roaming in progress, hence return ", __func__);
20481 return -ENONET;
20482 }
20483
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020484 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
20485
20486 wlan_hdd_get_snr(pAdapter, &snr);
20487 wlan_hdd_get_rssi(pAdapter, &rssi);
20488
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053020489 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20490 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
20491 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020492 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
20493 hdd_wlan_get_freq(channel, &freq);
20494
20495
20496 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
20497 {
20498 if (NULL == wiphy->bands[i])
20499 {
20500 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
20501 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
20502 continue;
20503 }
20504
20505 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
20506 {
20507 struct ieee80211_supported_band *band = wiphy->bands[i];
20508
20509 if (band->channels[j].center_freq == (v_U16_t)freq)
20510 {
20511 survey->channel = &band->channels[j];
20512 /* The Rx BDs contain SNR values in dB for the received frames
20513 * while the supplicant expects noise. So we calculate and
20514 * return the value of noise (dBm)
20515 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
20516 */
20517 survey->noise = rssi - snr;
20518 survey->filled = SURVEY_INFO_NOISE_DBM;
20519 filled = 1;
20520 }
20521 }
20522 }
20523
20524 if (filled)
20525 pAdapter->survey_idx = 1;
20526 else
20527 {
20528 pAdapter->survey_idx = 0;
20529 return -ENONET;
20530 }
20531
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020532 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020533 return 0;
20534}
20535
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020536static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
20537 struct net_device *dev,
20538 int idx, struct survey_info *survey)
20539{
20540 int ret;
20541
20542 vos_ssr_protect(__func__);
20543 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
20544 vos_ssr_unprotect(__func__);
20545
20546 return ret;
20547}
20548
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020549/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053020550 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020551 * this is called when cfg80211 driver resume
20552 * driver updates latest sched_scan scan result(if any) to cfg80211 database
20553 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053020554int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020555{
20556 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
20557 hdd_adapter_t *pAdapter;
20558 hdd_adapter_list_node_t *pAdapterNode, *pNext;
20559 VOS_STATUS status = VOS_STATUS_SUCCESS;
20560
20561 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020562
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053020563 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020564 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020565 return 0;
20566 }
20567
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053020568 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
20569 NO_SESSION, pHddCtx->isWiphySuspended));
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053020570
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053020571 if (pHddCtx->is_ap_mode_wow_supported)
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053020572 {
20573 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20574 "%s: Resume SoftAP", __func__);
20575 hdd_set_wlan_suspend_mode(false);
20576 }
20577
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020578 spin_lock(&pHddCtx->schedScan_lock);
20579 pHddCtx->isWiphySuspended = FALSE;
20580 if (TRUE != pHddCtx->isSchedScanUpdatePending)
20581 {
20582 spin_unlock(&pHddCtx->schedScan_lock);
20583 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20584 "%s: Return resume is not due to PNO indication", __func__);
20585 return 0;
20586 }
20587 // Reset flag to avoid updatating cfg80211 data old results again
20588 pHddCtx->isSchedScanUpdatePending = FALSE;
20589 spin_unlock(&pHddCtx->schedScan_lock);
20590
20591 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
20592
20593 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
20594 {
20595 pAdapter = pAdapterNode->pAdapter;
20596 if ( (NULL != pAdapter) &&
20597 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
20598 {
20599 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053020600 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020601 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
20602 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053020603 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020604 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053020605 {
20606 /* Acquire wakelock to handle the case where APP's tries to
20607 * suspend immediately after updating the scan results. Whis
20608 * results in app's is in suspended state and not able to
20609 * process the connect request to AP
20610 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053020611 hdd_prevent_suspend_timeout(2000,
20612 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020613 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053020614 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020615
20616 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20617 "%s : cfg80211 scan result database updated", __func__);
20618
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020619 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020620 return 0;
20621
20622 }
20623 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
20624 pAdapterNode = pNext;
20625 }
20626
20627 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20628 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020629 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020630 return 0;
20631}
20632
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053020633int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
20634{
20635 int ret;
20636
20637 vos_ssr_protect(__func__);
20638 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
20639 vos_ssr_unprotect(__func__);
20640
20641 return ret;
20642}
20643
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020644/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053020645 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020646 * this is called when cfg80211 driver suspends
20647 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053020648int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020649 struct cfg80211_wowlan *wow)
20650{
20651 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053020652 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020653
20654 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020655
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053020656 ret = wlan_hdd_validate_context(pHddCtx);
20657 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020658 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053020659 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020660 }
20661
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053020662 if (pHddCtx->is_ap_mode_wow_supported) {
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053020663 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20664 "%s: Suspend SoftAP", __func__);
20665 hdd_set_wlan_suspend_mode(true);
20666 }
20667
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053020668
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053020669 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20670 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
20671 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020672 pHddCtx->isWiphySuspended = TRUE;
20673
20674 EXIT();
20675
20676 return 0;
20677}
20678
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053020679int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
20680 struct cfg80211_wowlan *wow)
20681{
20682 int ret;
20683
20684 vos_ssr_protect(__func__);
20685 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
20686 vos_ssr_unprotect(__func__);
20687
20688 return ret;
20689}
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053020690
20691#ifdef FEATURE_OEM_DATA_SUPPORT
20692static void wlan_hdd_cfg80211_oem_data_rsp_ind_new(void *ctx,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053020693 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053020694{
20695 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
20696
20697 ENTER();
20698
20699 if (wlan_hdd_validate_context(pHddCtx)) {
20700 return;
20701 }
20702 if (!pMsg)
20703 {
20704 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
20705 return;
20706 }
20707
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053020708 send_oem_data_rsp_msg(evLen, pMsg);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053020709
20710 EXIT();
20711 return;
20712
20713}
20714
20715void wlan_hdd_cfg80211_oemdata_callback(void *ctx, const tANI_U16 evType,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053020716 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053020717{
20718 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
20719
20720 ENTER();
20721
20722 if (wlan_hdd_validate_context(pHddCtx)) {
20723 return;
20724 }
20725
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053020726 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d) evLen %d"), evType, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053020727
20728 switch(evType) {
20729 case SIR_HAL_START_OEM_DATA_RSP_IND_NEW:
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053020730 wlan_hdd_cfg80211_oem_data_rsp_ind_new(ctx, pMsg, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053020731 break;
20732 default:
20733 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
20734 break;
20735 }
20736 EXIT();
20737}
20738#endif
20739
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053020740#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
20741 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053020742/**
20743 * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api
20744 * @wiphy: Pointer to wiphy
20745 * @wdev: Pointer to wireless device structure
20746 *
20747 * This function is used to abort an ongoing scan
20748 *
20749 * Return: None
20750 */
20751static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
20752 struct wireless_dev *wdev)
20753{
20754 struct net_device *dev = wdev->netdev;
20755 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
20756 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
20757 int ret;
20758
20759 ENTER();
20760
20761 if (NULL == adapter) {
20762 hddLog(VOS_TRACE_LEVEL_FATAL, FL("HDD adapter is NULL"));
20763 return;
20764 }
20765
20766 ret = wlan_hdd_validate_context(hdd_ctx);
20767 if (0 != ret)
20768 return;
20769
20770 wlan_hdd_scan_abort(adapter);
20771
20772 return;
20773}
20774
20775/**
20776 * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api
20777 * @wiphy: Pointer to wiphy
20778 * @wdev: Pointer to wireless device structure
20779 *
20780 * Return: None
20781 */
20782void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
20783 struct wireless_dev *wdev)
20784{
20785 vos_ssr_protect(__func__);
20786 __wlan_hdd_cfg80211_abort_scan(wiphy, wdev);
20787 vos_ssr_unprotect(__func__);
20788
20789 return;
20790}
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053020791#endif
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053020792
Jeff Johnson295189b2012-06-20 16:38:30 -070020793/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053020794static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070020795{
20796 .add_virtual_intf = wlan_hdd_add_virtual_intf,
20797 .del_virtual_intf = wlan_hdd_del_virtual_intf,
20798 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
20799 .change_station = wlan_hdd_change_station,
20800#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
20801 .add_beacon = wlan_hdd_cfg80211_add_beacon,
20802 .del_beacon = wlan_hdd_cfg80211_del_beacon,
20803 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070020804#else
20805 .start_ap = wlan_hdd_cfg80211_start_ap,
20806 .change_beacon = wlan_hdd_cfg80211_change_beacon,
20807 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070020808#endif
20809 .change_bss = wlan_hdd_cfg80211_change_bss,
20810 .add_key = wlan_hdd_cfg80211_add_key,
20811 .get_key = wlan_hdd_cfg80211_get_key,
20812 .del_key = wlan_hdd_cfg80211_del_key,
20813 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080020814#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070020815 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080020816#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070020817 .scan = wlan_hdd_cfg80211_scan,
20818 .connect = wlan_hdd_cfg80211_connect,
20819 .disconnect = wlan_hdd_cfg80211_disconnect,
20820 .join_ibss = wlan_hdd_cfg80211_join_ibss,
20821 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
20822 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
20823 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
20824 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070020825 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
20826 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053020827 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070020828#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
20829 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
20830 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
20831 .set_txq_params = wlan_hdd_set_txq_params,
20832#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070020833 .get_station = wlan_hdd_cfg80211_get_station,
20834 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
20835 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070020836 .add_station = wlan_hdd_cfg80211_add_station,
20837#ifdef FEATURE_WLAN_LFR
20838 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
20839 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
20840 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
20841#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070020842#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
20843 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
20844#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020845#ifdef FEATURE_WLAN_TDLS
20846 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
20847 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
20848#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020849#ifdef WLAN_FEATURE_GTK_OFFLOAD
20850 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
20851#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020852#ifdef FEATURE_WLAN_SCAN_PNO
20853 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
20854 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
20855#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020856 .resume = wlan_hdd_cfg80211_resume_wlan,
20857 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020858 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070020859#ifdef WLAN_NL80211_TESTMODE
20860 .testmode_cmd = wlan_hdd_cfg80211_testmode,
20861#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020862 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053020863#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
20864 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053020865 .abort_scan = wlan_hdd_cfg80211_abort_scan,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053020866#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070020867};
20868