blob: d6e3b7df8189d621423129dd66def0097e40b433 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Hanumanth Reddy Pothula14bc86d2018-01-02 20:02:02 +05302 * Copyright (c) 2012-2018 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
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +0530424/* interface limits for sta + monitor SCC */
425static const struct ieee80211_iface_limit
426wlan_hdd_iface_sta_mon_limit[] = {
427 {
428 .max = 1,
429 .types = BIT(NL80211_IFTYPE_STATION),
430 },
431 {
432 .max = 1, /* Monitor interface */
433 .types = BIT(NL80211_IFTYPE_MONITOR),
434 },
435};
436
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800437/* By default, only single channel concurrency is allowed */
438static struct ieee80211_iface_combination
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +0530439wlan_hdd_iface_combination[] = {
440 {
441 .limits = wlan_hdd_iface_limit,
442 .num_different_channels = 1,
443 /*
444 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
445 * and p2p0 interfaces during driver init
446 * Some vendors create separate interface for P2P operations.
447 * wlan0: STA interface
448 * p2p0: P2P Device interface, action frames goes
449 * through this interface.
450 * p2p-xx: P2P interface, After GO negotiation this interface is
451 * created for p2p operations(GO/CLIENT interface).
452 */
453 .max_interfaces = WLAN_MAX_INTERFACES,
454 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
455 .beacon_int_infra_match = false,
456 },
457 {
458 .limits = wlan_hdd_iface_sta_mon_limit,
459 .num_different_channels = 1,
460 .max_interfaces = WLAN_STA_AND_MON_INTERFACES,
461 .n_limits = ARRAY_SIZE(wlan_hdd_iface_sta_mon_limit),
462 .beacon_int_infra_match = false,
463 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800464};
465#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800466
Jeff Johnson295189b2012-06-20 16:38:30 -0700467static struct cfg80211_ops wlan_hdd_cfg80211_ops;
468
469/* Data rate 100KBPS based on IE Index */
470struct index_data_rate_type
471{
472 v_U8_t beacon_rate_index;
473 v_U16_t supported_rate[4];
474};
475
476/* 11B, 11G Rate table include Basic rate and Extended rate
477 The IDX field is the rate index
478 The HI field is the rate when RSSI is strong or being ignored
479 (in this case we report actual rate)
480 The MID field is the rate when RSSI is moderate
481 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
482 The LO field is the rate when RSSI is low
483 (in this case we don't report rates, actual current rate used)
484 */
485static const struct
486{
487 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700488 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700489} supported_data_rate[] =
490{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700491/* IDX HI HM LM LO (RSSI-based index */
492 {2, { 10, 10, 10, 0}},
493 {4, { 20, 20, 10, 0}},
494 {11, { 55, 20, 10, 0}},
495 {12, { 60, 55, 20, 0}},
496 {18, { 90, 55, 20, 0}},
497 {22, {110, 55, 20, 0}},
498 {24, {120, 90, 60, 0}},
499 {36, {180, 120, 60, 0}},
500 {44, {220, 180, 60, 0}},
501 {48, {240, 180, 90, 0}},
502 {66, {330, 180, 90, 0}},
503 {72, {360, 240, 90, 0}},
504 {96, {480, 240, 120, 0}},
505 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700506};
507
508/* MCS Based rate table */
509static struct index_data_rate_type supported_mcs_rate[] =
510{
511/* MCS L20 L40 S20 S40 */
512 {0, {65, 135, 72, 150}},
513 {1, {130, 270, 144, 300}},
514 {2, {195, 405, 217, 450}},
515 {3, {260, 540, 289, 600}},
516 {4, {390, 810, 433, 900}},
517 {5, {520, 1080, 578, 1200}},
518 {6, {585, 1215, 650, 1350}},
519 {7, {650, 1350, 722, 1500}}
520};
521
Leo Chang6f8870f2013-03-26 18:11:36 -0700522#ifdef WLAN_FEATURE_11AC
523
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530524#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700525
526struct index_vht_data_rate_type
527{
528 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530529 v_U16_t supported_VHT80_rate[2];
530 v_U16_t supported_VHT40_rate[2];
531 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700532};
533
534typedef enum
535{
536 DATA_RATE_11AC_MAX_MCS_7,
537 DATA_RATE_11AC_MAX_MCS_8,
538 DATA_RATE_11AC_MAX_MCS_9,
539 DATA_RATE_11AC_MAX_MCS_NA
540} eDataRate11ACMaxMcs;
541
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530542/* SSID broadcast type */
543typedef enum eSSIDBcastType
544{
545 eBCAST_UNKNOWN = 0,
546 eBCAST_NORMAL = 1,
547 eBCAST_HIDDEN = 2,
548} tSSIDBcastType;
549
Leo Chang6f8870f2013-03-26 18:11:36 -0700550/* MCS Based VHT rate table */
551static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
552{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530553/* MCS L80 S80 L40 S40 L20 S40*/
554 {0, {293, 325}, {135, 150}, {65, 72}},
555 {1, {585, 650}, {270, 300}, {130, 144}},
556 {2, {878, 975}, {405, 450}, {195, 217}},
557 {3, {1170, 1300}, {540, 600}, {260, 289}},
558 {4, {1755, 1950}, {810, 900}, {390, 433}},
559 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
560 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
561 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
562 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
563 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700564};
565#endif /* WLAN_FEATURE_11AC */
566
c_hpothu79aab322014-07-14 21:11:01 +0530567/*array index points to MCS and array value points respective rssi*/
568static int rssiMcsTbl[][10] =
569{
570/*MCS 0 1 2 3 4 5 6 7 8 9*/
571 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
572 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
573 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
574};
575
Jeff Johnson295189b2012-06-20 16:38:30 -0700576extern struct net_device_ops net_ops_struct;
Dasari Srinivas7875a302014-09-26 17:50:57 +0530577#ifdef FEATURE_WLAN_SCAN_PNO
578static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
579#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700580
Leo Chang9056f462013-08-01 19:21:11 -0700581#ifdef WLAN_NL80211_TESTMODE
582enum wlan_hdd_tm_attr
583{
584 WLAN_HDD_TM_ATTR_INVALID = 0,
585 WLAN_HDD_TM_ATTR_CMD = 1,
586 WLAN_HDD_TM_ATTR_DATA = 2,
587 WLAN_HDD_TM_ATTR_TYPE = 3,
588 /* keep last */
589 WLAN_HDD_TM_ATTR_AFTER_LAST,
590 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
591};
592
593enum wlan_hdd_tm_cmd
594{
595 WLAN_HDD_TM_CMD_WLAN_HB = 1,
596};
597
598#define WLAN_HDD_TM_DATA_MAX_LEN 5000
599
600static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
601{
602 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
603 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
604 .len = WLAN_HDD_TM_DATA_MAX_LEN },
605};
606#endif /* WLAN_NL80211_TESTMODE */
607
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800608#ifdef FEATURE_WLAN_CH_AVOID
609/*
610 * FUNCTION: wlan_hdd_send_avoid_freq_event
611 * This is called when wlan driver needs to send vendor specific
612 * avoid frequency range event to userspace
613 */
614int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
615 tHddAvoidFreqList *pAvoidFreqList)
616{
617 struct sk_buff *vendor_event;
618
619 ENTER();
620
621 if (!pHddCtx)
622 {
623 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
624 "%s: HDD context is null", __func__);
625 return -1;
626 }
627
628 if (!pAvoidFreqList)
629 {
630 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
631 "%s: pAvoidFreqList is null", __func__);
632 return -1;
633 }
634
635 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530636#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
637 NULL,
638#endif
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800639 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530640 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800641 GFP_KERNEL);
642 if (!vendor_event)
643 {
644 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
645 "%s: cfg80211_vendor_event_alloc failed", __func__);
646 return -1;
647 }
648
649 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
650 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
651
652 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
653
654 EXIT();
655 return 0;
656}
657#endif /* FEATURE_WLAN_CH_AVOID */
658
Srinivas Dasari030bad32015-02-18 23:23:54 +0530659/*
660 * FUNCTION: __wlan_hdd_cfg80211_nan_request
661 * This is called when wlan driver needs to send vendor specific
662 * nan request event.
663 */
664static int __wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
665 struct wireless_dev *wdev,
666 const void *data, int data_len)
667{
668 tNanRequestReq nan_req;
669 VOS_STATUS status;
670 int ret_val = -1;
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530671 struct net_device *dev = wdev->netdev;
672 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
673 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530674 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
675
676 if (0 == data_len)
677 {
678 hddLog(VOS_TRACE_LEVEL_ERROR,
679 FL("NAN - Invalid Request, length = 0"));
680 return ret_val;
681 }
682
683 if (NULL == data)
684 {
685 hddLog(VOS_TRACE_LEVEL_ERROR,
686 FL("NAN - Invalid Request, data is NULL"));
687 return ret_val;
688 }
689
690 status = wlan_hdd_validate_context(pHddCtx);
691 if (0 != status)
692 {
693 hddLog(VOS_TRACE_LEVEL_ERROR,
694 FL("HDD context is not valid"));
695 return -EINVAL;
696 }
697
698 hddLog(LOG1, FL("Received NAN command"));
699 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
700 (tANI_U8 *)data, data_len);
701
702 /* check the NAN Capability */
703 if (TRUE != sme_IsFeatureSupportedByFW(NAN))
704 {
705 hddLog(VOS_TRACE_LEVEL_ERROR,
706 FL("NAN is not supported by Firmware"));
707 return -EINVAL;
708 }
709
710 nan_req.request_data_len = data_len;
711 nan_req.request_data = data;
712
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530713 status = sme_NanRequest(hHal, &nan_req, pAdapter->sessionId);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530714 if (VOS_STATUS_SUCCESS == status)
715 {
716 ret_val = 0;
717 }
718 return ret_val;
719}
720
721/*
722 * FUNCTION: wlan_hdd_cfg80211_nan_request
723 * Wrapper to protect the nan vendor command from ssr
724 */
725static int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
726 struct wireless_dev *wdev,
727 const void *data, int data_len)
728{
729 int ret;
730
731 vos_ssr_protect(__func__);
732 ret = __wlan_hdd_cfg80211_nan_request(wiphy, wdev, data, data_len);
733 vos_ssr_unprotect(__func__);
734
735 return ret;
736}
737
738/*
739 * FUNCTION: wlan_hdd_cfg80211_nan_callback
740 * This is a callback function and it gets called
741 * when we need to report nan response event to
742 * upper layers.
743 */
744static void wlan_hdd_cfg80211_nan_callback(void* ctx, tSirNanEvent* msg)
745{
746 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
747 struct sk_buff *vendor_event;
748 int status;
749 tSirNanEvent *data;
750
751 ENTER();
752 if (NULL == msg)
753 {
754 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
755 FL(" msg received here is null"));
756 return;
757 }
758 data = msg;
759
760 status = wlan_hdd_validate_context(pHddCtx);
761
762 if (0 != status)
763 {
764 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
765 FL("HDD context is not valid"));
766 return;
767 }
768
769 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530770#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
771 NULL,
772#endif
Srinivas Dasari030bad32015-02-18 23:23:54 +0530773 data->event_data_len +
774 NLMSG_HDRLEN,
775 QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX,
776 GFP_KERNEL);
777
778 if (!vendor_event)
779 {
780 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
781 FL("cfg80211_vendor_event_alloc failed"));
782 return;
783 }
784 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN,
785 data->event_data_len, data->event_data))
786 {
787 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
788 FL("QCA_WLAN_VENDOR_ATTR_NAN put fail"));
789 kfree_skb(vendor_event);
790 return;
791 }
792 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
793 EXIT();
794}
795
796/*
797 * FUNCTION: wlan_hdd_cfg80211_nan_init
798 * This function is called to register the callback to sme layer
799 */
800inline void wlan_hdd_cfg80211_nan_init(hdd_context_t *pHddCtx)
801{
802 sme_NanRegisterCallback(pHddCtx->hHal, wlan_hdd_cfg80211_nan_callback);
803}
804
Anurag Chouhanfcd20172017-07-19 17:25:19 +0530805/*
806 * define short names for the global vendor params
807 * used by __wlan_hdd_cfg80211_get_station_cmd()
808 */
809#define STATION_INVALID \
810 QCA_WLAN_VENDOR_ATTR_GET_STATION_INVALID
811#define STATION_INFO \
812 QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO
813#define STATION_ASSOC_FAIL_REASON \
814 QCA_WLAN_VENDOR_ATTR_GET_STATION_ASSOC_FAIL_REASON
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +0530815#define STATION_REMOTE \
816 QCA_WLAN_VENDOR_ATTR_GET_STATION_REMOTE
Anurag Chouhanfcd20172017-07-19 17:25:19 +0530817#define STATION_MAX \
818 QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX
819
820static const struct nla_policy
821hdd_get_station_policy[STATION_MAX + 1] = {
822 [STATION_INFO] = {.type = NLA_FLAG},
823 [STATION_ASSOC_FAIL_REASON] = {.type = NLA_FLAG},
824};
825
826/**
827 * hdd_get_station_assoc_fail() - Handle get station assoc fail
828 * @hdd_ctx: HDD context within host driver
829 * @wdev: wireless device
830 *
831 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION_ASSOC_FAIL.
832 * Validate cmd attributes and send the station info to upper layers.
833 *
834 * Return: Success(0) or reason code for failure
835 */
836static int hdd_get_station_assoc_fail(hdd_context_t *hdd_ctx,
837 hdd_adapter_t *adapter)
838{
839 struct sk_buff *skb = NULL;
840 uint32_t nl_buf_len;
841 hdd_station_ctx_t *hdd_sta_ctx;
842
843 nl_buf_len = NLMSG_HDRLEN;
844 nl_buf_len += sizeof(uint32_t);
845 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
846
847 if (!skb) {
848 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"cfg80211_vendor_cmd_alloc_reply_skb failed");
849 return -ENOMEM;
850 }
851
852 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
853
854 if (nla_put_u32(skb, INFO_ASSOC_FAIL_REASON,
855 hdd_sta_ctx->conn_info.assoc_status_code)) {
856 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
857 goto fail;
858 }
859 return cfg80211_vendor_cmd_reply(skb);
860fail:
861 if (skb)
862 kfree_skb(skb);
863 return -EINVAL;
864}
865
866/**
867 * hdd_map_auth_type() - transform auth type specific to
868 * vendor command
869 * @auth_type: csr auth type
870 *
871 * Return: Success(0) or reason code for failure
872 */
873static int hdd_convert_auth_type(uint32_t auth_type)
874{
875 uint32_t ret_val;
876
877 switch (auth_type) {
878 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
879 ret_val = QCA_WLAN_AUTH_TYPE_OPEN;
880 break;
881 case eCSR_AUTH_TYPE_SHARED_KEY:
882 ret_val = QCA_WLAN_AUTH_TYPE_SHARED;
883 break;
884 case eCSR_AUTH_TYPE_WPA:
885 ret_val = QCA_WLAN_AUTH_TYPE_WPA;
886 break;
887 case eCSR_AUTH_TYPE_WPA_PSK:
888 ret_val = QCA_WLAN_AUTH_TYPE_WPA_PSK;
889 break;
890 case eCSR_AUTH_TYPE_AUTOSWITCH:
891 ret_val = QCA_WLAN_AUTH_TYPE_AUTOSWITCH;
892 break;
893 case eCSR_AUTH_TYPE_WPA_NONE:
894 ret_val = QCA_WLAN_AUTH_TYPE_WPA_NONE;
895 break;
896 case eCSR_AUTH_TYPE_RSN:
897 ret_val = QCA_WLAN_AUTH_TYPE_RSN;
898 break;
899 case eCSR_AUTH_TYPE_RSN_PSK:
900 ret_val = QCA_WLAN_AUTH_TYPE_RSN_PSK;
901 break;
902 case eCSR_AUTH_TYPE_FT_RSN:
903 ret_val = QCA_WLAN_AUTH_TYPE_FT;
904 break;
905 case eCSR_AUTH_TYPE_FT_RSN_PSK:
906 ret_val = QCA_WLAN_AUTH_TYPE_FT_PSK;
907 break;
908 case eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE:
909 ret_val = QCA_WLAN_AUTH_TYPE_WAI;
910 break;
911 case eCSR_AUTH_TYPE_WAPI_WAI_PSK:
912 ret_val = QCA_WLAN_AUTH_TYPE_WAI_PSK;
913 break;
914#ifdef FEATURE_WLAN_ESE
915 case eCSR_AUTH_TYPE_CCKM_WPA:
916 ret_val = QCA_WLAN_AUTH_TYPE_CCKM_WPA;
917 break;
918 case eCSR_AUTH_TYPE_CCKM_RSN:
919 ret_val = QCA_WLAN_AUTH_TYPE_CCKM_RSN;
920 break;
921#endif
922 case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
923 ret_val = QCA_WLAN_AUTH_TYPE_SHA256_PSK;
924 break;
925 case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
926 ret_val = QCA_WLAN_AUTH_TYPE_SHA256;
927 break;
928 case eCSR_NUM_OF_SUPPORT_AUTH_TYPE:
929 case eCSR_AUTH_TYPE_FAILED:
930 case eCSR_AUTH_TYPE_NONE:
931 default:
932 ret_val = QCA_WLAN_AUTH_TYPE_INVALID;
933 break;
934 }
935 return ret_val;
936}
937
938/**
939 * hdd_map_dot_11_mode() - transform dot11mode type specific to
940 * vendor command
941 * @dot11mode: dot11mode
942 *
943 * Return: Success(0) or reason code for failure
944 */
945static int hdd_convert_dot11mode(uint32_t dot11mode)
946{
947 uint32_t ret_val;
948
949 switch (dot11mode) {
950 case eCSR_CFG_DOT11_MODE_11A:
951 ret_val = QCA_WLAN_802_11_MODE_11A;
952 break;
953 case eCSR_CFG_DOT11_MODE_11B:
954 ret_val = QCA_WLAN_802_11_MODE_11B;
955 break;
956 case eCSR_CFG_DOT11_MODE_11G:
957 ret_val = QCA_WLAN_802_11_MODE_11G;
958 break;
959 case eCSR_CFG_DOT11_MODE_11N:
960 ret_val = QCA_WLAN_802_11_MODE_11N;
961 break;
962 case eCSR_CFG_DOT11_MODE_11AC:
963 ret_val = QCA_WLAN_802_11_MODE_11AC;
964 break;
965 case eCSR_CFG_DOT11_MODE_AUTO:
966 case eCSR_CFG_DOT11_MODE_ABG:
967 default:
968 ret_val = QCA_WLAN_802_11_MODE_INVALID;
969 }
970 return ret_val;
971}
972
973/**
974 * hdd_add_tx_bitrate() - add tx bitrate attribute
975 * @skb: pointer to sk buff
976 * @hdd_sta_ctx: pointer to hdd station context
977 * @idx: attribute index
978 *
979 * Return: Success(0) or reason code for failure
980 */
981static int32_t hdd_add_tx_bitrate(struct sk_buff *skb,
982 hdd_station_ctx_t *hdd_sta_ctx,
983 int idx)
984{
985 struct nlattr *nla_attr;
986 uint32_t bitrate, bitrate_compat;
987
988 nla_attr = nla_nest_start(skb, idx);
989 if (!nla_attr)
990 goto fail;
991 /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
992 bitrate = cfg80211_calculate_bitrate(&hdd_sta_ctx->conn_info.txrate);
993
994 /* report 16-bit bitrate only if we can */
995 bitrate_compat = bitrate < (1UL << 16) ? bitrate : 0;
996 if (bitrate > 0 &&
997 nla_put_u32(skb, NL80211_RATE_INFO_BITRATE32, bitrate)) {
998 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
999 goto fail;
1000 }
1001 if (bitrate_compat > 0 &&
1002 nla_put_u16(skb, NL80211_RATE_INFO_BITRATE, bitrate_compat)) {
1003 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1004 goto fail;
1005 }
1006 if (nla_put_u8(skb, NL80211_RATE_INFO_VHT_NSS,
1007 hdd_sta_ctx->conn_info.txrate.nss)) {
1008 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1009 goto fail;
1010 }
1011 nla_nest_end(skb, nla_attr);
1012 return 0;
1013fail:
1014 return -EINVAL;
1015}
1016
1017/**
1018 * hdd_add_sta_info() - add station info attribute
1019 * @skb: pointer to sk buff
1020 * @hdd_sta_ctx: pointer to hdd station context
1021 * @idx: attribute index
1022 *
1023 * Return: Success(0) or reason code for failure
1024 */
1025static int32_t hdd_add_sta_info(struct sk_buff *skb,
1026 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1027{
1028 struct nlattr *nla_attr;
1029
1030 nla_attr = nla_nest_start(skb, idx);
1031 if (!nla_attr)
1032 goto fail;
1033 if (nla_put_u8(skb, NL80211_STA_INFO_SIGNAL,
1034 (hdd_sta_ctx->conn_info.signal + 100))) {
1035 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1036 goto fail;
1037 }
1038 if (hdd_add_tx_bitrate(skb, hdd_sta_ctx, NL80211_STA_INFO_TX_BITRATE))
1039 goto fail;
1040 nla_nest_end(skb, nla_attr);
1041 return 0;
1042fail:
1043 return -EINVAL;
1044}
1045
1046/**
1047 * hdd_add_survey_info() - add survey info attribute
1048 * @skb: pointer to sk buff
1049 * @hdd_sta_ctx: pointer to hdd station context
1050 * @idx: attribute index
1051 *
1052 * Return: Success(0) or reason code for failure
1053 */
1054static int32_t hdd_add_survey_info(struct sk_buff *skb,
1055 hdd_station_ctx_t *hdd_sta_ctx,
1056 int idx)
1057{
1058 struct nlattr *nla_attr;
1059
1060 nla_attr = nla_nest_start(skb, idx);
1061 if (!nla_attr)
1062 goto fail;
1063 if (nla_put_u32(skb, NL80211_SURVEY_INFO_FREQUENCY,
1064 hdd_sta_ctx->conn_info.freq) ||
1065 nla_put_u8(skb, NL80211_SURVEY_INFO_NOISE,
1066 (hdd_sta_ctx->conn_info.noise + 100))) {
1067 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1068 goto fail;
1069 }
1070 nla_nest_end(skb, nla_attr);
1071 return 0;
1072fail:
1073 return -EINVAL;
1074}
1075
1076/**
1077 * hdd_add_link_standard_info() - add link info attribute
1078 * @skb: pointer to sk buff
1079 * @hdd_sta_ctx: pointer to hdd station context
1080 * @idx: attribute index
1081 *
1082 * Return: Success(0) or reason code for failure
1083 */
1084static int32_t
1085hdd_add_link_standard_info(struct sk_buff *skb,
1086 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1087{
1088 struct nlattr *nla_attr;
1089
1090 nla_attr = nla_nest_start(skb, idx);
1091 if (!nla_attr)
1092 goto fail;
1093 if (nla_put(skb,
1094 NL80211_ATTR_SSID,
1095 hdd_sta_ctx->conn_info.SSID.SSID.length,
1096 hdd_sta_ctx->conn_info.SSID.SSID.ssId)) {
1097 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1098 goto fail;
1099 }
1100 if (hdd_add_survey_info(skb, hdd_sta_ctx, NL80211_ATTR_SURVEY_INFO))
1101 goto fail;
1102 if (hdd_add_sta_info(skb, hdd_sta_ctx, NL80211_ATTR_STA_INFO))
1103 goto fail;
1104 nla_nest_end(skb, nla_attr);
1105 return 0;
1106fail:
1107 return -EINVAL;
1108}
1109
1110/**
1111 * hdd_add_ap_standard_info() - add ap info attribute
1112 * @skb: pointer to sk buff
1113 * @hdd_sta_ctx: pointer to hdd station context
1114 * @idx: attribute index
1115 *
1116 * Return: Success(0) or reason code for failure
1117 */
1118static int32_t
1119hdd_add_ap_standard_info(struct sk_buff *skb,
1120 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1121{
1122 struct nlattr *nla_attr;
1123
1124 nla_attr = nla_nest_start(skb, idx);
1125 if (!nla_attr)
1126 goto fail;
1127 if (hdd_sta_ctx->conn_info.conn_flag.vht_present)
1128 if (nla_put(skb, NL80211_ATTR_VHT_CAPABILITY,
1129 sizeof(hdd_sta_ctx->conn_info.vht_caps),
1130 &hdd_sta_ctx->conn_info.vht_caps)) {
1131 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1132 goto fail;
1133 }
1134 if (hdd_sta_ctx->conn_info.conn_flag.ht_present)
1135 if (nla_put(skb, NL80211_ATTR_HT_CAPABILITY,
1136 sizeof(hdd_sta_ctx->conn_info.ht_caps),
1137 &hdd_sta_ctx->conn_info.ht_caps)) {
1138 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1139 goto fail;
1140 }
1141 nla_nest_end(skb, nla_attr);
1142 return 0;
1143fail:
1144 return -EINVAL;
1145}
1146
1147/**
1148 * hdd_get_station_info() - send BSS information to supplicant
1149 * @hdd_ctx: pointer to hdd context
1150 * @adapter: pointer to adapter
1151 *
1152 * Return: 0 if success else error status
1153 */
1154static int hdd_get_station_info(hdd_context_t *hdd_ctx,
1155 hdd_adapter_t *adapter)
1156{
1157 struct sk_buff *skb = NULL;
1158 uint8_t *tmp_hs20 = NULL;
1159 uint32_t nl_buf_len;
1160 hdd_station_ctx_t *hdd_sta_ctx;
1161
1162 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
1163
1164 nl_buf_len = NLMSG_HDRLEN;
1165 nl_buf_len += sizeof(hdd_sta_ctx->conn_info.SSID.SSID.length) +
1166 sizeof(hdd_sta_ctx->conn_info.freq) +
1167 sizeof(hdd_sta_ctx->conn_info.noise) +
1168 sizeof(hdd_sta_ctx->conn_info.signal) +
1169 (sizeof(uint32_t) * 2) +
1170 sizeof(hdd_sta_ctx->conn_info.txrate.nss) +
1171 sizeof(hdd_sta_ctx->conn_info.roam_count) +
1172 sizeof(hdd_sta_ctx->conn_info.authType) +
1173 sizeof(hdd_sta_ctx->conn_info.dot11Mode);
1174 if (hdd_sta_ctx->conn_info.conn_flag.vht_present)
1175 nl_buf_len += sizeof(hdd_sta_ctx->conn_info.vht_caps);
1176 if (hdd_sta_ctx->conn_info.conn_flag.ht_present)
1177 nl_buf_len += sizeof(hdd_sta_ctx->conn_info.ht_caps);
1178 if (hdd_sta_ctx->conn_info.conn_flag.hs20_present) {
1179 tmp_hs20 = (uint8_t *)&(hdd_sta_ctx->conn_info.hs20vendor_ie);
1180 nl_buf_len += (sizeof(hdd_sta_ctx->conn_info.hs20vendor_ie) -
1181 1);
1182 }
1183 if (hdd_sta_ctx->conn_info.conn_flag.ht_op_present)
1184 nl_buf_len += sizeof(hdd_sta_ctx->conn_info.ht_operation);
1185 if (hdd_sta_ctx->conn_info.conn_flag.vht_op_present)
1186 nl_buf_len += sizeof(hdd_sta_ctx->conn_info.vht_operation);
1187
1188
1189 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
1190 if (!skb) {
1191 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"%s: %d cfg80211_vendor_cmd_alloc_reply_skb failed",
1192 __func__, __LINE__);
1193 return -ENOMEM;
1194 }
1195
1196 if (hdd_add_link_standard_info(skb, hdd_sta_ctx,
1197 LINK_INFO_STANDARD_NL80211_ATTR)) {
1198 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1199 goto fail;
1200 }
1201 if (hdd_add_ap_standard_info(skb, hdd_sta_ctx,
1202 AP_INFO_STANDARD_NL80211_ATTR)) {
1203 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1204 goto fail;
1205 }
1206 if (nla_put_u32(skb, INFO_ROAM_COUNT,
1207 hdd_sta_ctx->conn_info.roam_count) ||
1208 nla_put_u32(skb, INFO_AKM,
1209 hdd_convert_auth_type(
1210 hdd_sta_ctx->conn_info.authType)) ||
1211 nla_put_u32(skb, WLAN802_11_MODE,
1212 hdd_convert_dot11mode(
1213 hdd_sta_ctx->conn_info.dot11Mode))) {
1214 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1215 goto fail;
1216 }
1217 if (hdd_sta_ctx->conn_info.conn_flag.ht_op_present)
1218 if (nla_put(skb, HT_OPERATION,
1219 (sizeof(hdd_sta_ctx->conn_info.ht_operation)),
1220 &hdd_sta_ctx->conn_info.ht_operation)) {
1221 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1222 goto fail;
1223 }
1224 if (hdd_sta_ctx->conn_info.conn_flag.vht_op_present)
1225 if (nla_put(skb, VHT_OPERATION,
1226 (sizeof(hdd_sta_ctx->conn_info.vht_operation)),
1227 &hdd_sta_ctx->conn_info.vht_operation)) {
1228 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1229 goto fail;
1230 }
1231 if (hdd_sta_ctx->conn_info.conn_flag.hs20_present)
1232 if (nla_put(skb, AP_INFO_HS20_INDICATION,
1233 (sizeof(hdd_sta_ctx->conn_info.hs20vendor_ie) - 1),
1234 tmp_hs20 + 1)) {
1235 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1236 goto fail;
1237 }
1238
1239 return cfg80211_vendor_cmd_reply(skb);
1240fail:
1241 if (skb)
1242 kfree_skb(skb);
1243 return -EINVAL;
1244}
1245
1246/**
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301247 * hdd_add_survey_info_sap_get_len - get data length used in
1248 * hdd_add_survey_info_sap()
1249 *
1250 * This function calculates the data length used in hdd_add_survey_info_sap()
1251 *
1252 * Return: total data length used in hdd_add_survey_info_sap()
1253 */
1254static uint32_t hdd_add_survey_info_sap_get_len(void)
1255{
1256 return ((NLA_HDRLEN) + (sizeof(uint32_t) + NLA_HDRLEN));
1257}
1258
1259/**
1260 * hdd_add_survey_info - add survey info attribute
1261 * @skb: pointer to response skb buffer
1262 * @stainfo: station information
1263 * @idx: attribute type index for nla_next_start()
1264 *
1265 * This function adds survey info attribute to response skb buffer
1266 *
1267 * Return : 0 on success and errno on failure
1268 */
1269static int32_t hdd_add_survey_info_sap(struct sk_buff *skb,
1270 struct hdd_cache_sta_info *stainfo,
1271 int idx)
1272{
1273 struct nlattr *nla_attr;
1274
1275 nla_attr = nla_nest_start(skb, idx);
1276 if (!nla_attr)
1277 goto fail;
1278 if (nla_put_u32(skb, NL80211_SURVEY_INFO_FREQUENCY,
1279 stainfo->freq)) {
1280 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1281 FL("put fail"));
1282 goto fail;
1283 }
1284 nla_nest_end(skb, nla_attr);
1285 return 0;
1286fail:
1287 return -EINVAL;
1288}
1289
1290/**
1291 * hdd_add_tx_bitrate_sap_get_len - get data length used in
1292 * hdd_add_tx_bitrate_sap()
1293 *
1294 * This function calculates the data length used in hdd_add_tx_bitrate_sap()
1295 *
1296 * Return: total data length used in hdd_add_tx_bitrate_sap()
1297 */
1298static uint32_t hdd_add_tx_bitrate_sap_get_len(void)
1299{
1300 return ((NLA_HDRLEN) + (sizeof(uint8_t) + NLA_HDRLEN));
1301}
1302
1303/**
1304 * hdd_add_tx_bitrate_sap - add vht nss info attribute
1305 * @skb: pointer to response skb buffer
1306 * @stainfo: station information
1307 * @idx: attribute type index for nla_next_start()
1308 *
1309 * This function adds vht nss attribute to response skb buffer
1310 *
1311 * Return : 0 on success and errno on failure
1312 */
1313static int hdd_add_tx_bitrate_sap(struct sk_buff *skb,
1314 struct hdd_cache_sta_info *stainfo,
1315 int idx)
1316{
1317 struct nlattr *nla_attr;
1318
1319 nla_attr = nla_nest_start(skb, idx);
1320 if (!nla_attr)
1321 goto fail;
1322
1323 if (nla_put_u8(skb, NL80211_RATE_INFO_VHT_NSS,
1324 stainfo->nss)) {
1325 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1326 FL("put fail"));
1327 goto fail;
1328 }
1329 nla_nest_end(skb, nla_attr);
1330 return 0;
1331fail:
1332 return -EINVAL;
1333}
1334
1335/**
1336 * hdd_add_sta_info_sap_get_len - get data length used in
1337 * hdd_add_sta_info_sap()
1338 *
1339 * This function calculates the data length used in hdd_add_sta_info_sap()
1340 *
1341 * Return: total data length used in hdd_add_sta_info_sap()
1342 */
1343static uint32_t hdd_add_sta_info_sap_get_len(void)
1344{
1345 return ((NLA_HDRLEN) + (sizeof(uint8_t) + NLA_HDRLEN) +
1346 hdd_add_tx_bitrate_sap_get_len());
1347}
1348
1349/**
1350 * hdd_add_sta_info_sap - add sta signal info attribute
1351 * @skb: pointer to response skb buffer
1352 * @rssi: peer rssi value
1353 * @stainfo: station information
1354 * @idx: attribute type index for nla_next_start()
1355 *
1356 * This function adds sta signal attribute to response skb buffer
1357 *
1358 * Return : 0 on success and errno on failure
1359 */
1360static int32_t hdd_add_sta_info_sap(struct sk_buff *skb, int8_t rssi,
1361 struct hdd_cache_sta_info *stainfo, int idx)
1362{
1363 struct nlattr *nla_attr;
1364
1365 nla_attr = nla_nest_start(skb, idx);
1366 if (!nla_attr)
1367 goto fail;
1368
Hanumanth Reddy Pothula14bc86d2018-01-02 20:02:02 +05301369 /* upperlayer expects positive rssi value */
1370 if (nla_put_u8(skb, NL80211_STA_INFO_SIGNAL, (rssi + 96))) {
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301371 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1372 FL("put fail"));
1373 goto fail;
1374 }
1375 if (hdd_add_tx_bitrate_sap(skb, stainfo, NL80211_STA_INFO_TX_BITRATE)) {
1376 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1377 FL("put fail"));
1378 goto fail;
1379 }
1380
1381 nla_nest_end(skb, nla_attr);
1382 return 0;
1383fail:
1384 return -EINVAL;
1385}
1386
1387/**
1388 * hdd_add_link_standard_info_sap_get_len - get data length used in
1389 * hdd_add_link_standard_info_sap()
1390 *
1391 * This function calculates the data length used in
1392 * hdd_add_link_standard_info_sap()
1393 *
1394 * Return: total data length used in hdd_add_link_standard_info_sap()
1395 */
1396static uint32_t hdd_add_link_standard_info_sap_get_len(void)
1397{
1398 return ((NLA_HDRLEN) +
1399 hdd_add_survey_info_sap_get_len() +
1400 hdd_add_sta_info_sap_get_len() +
1401 (sizeof(uint32_t) + NLA_HDRLEN));
1402}
1403
1404/**
1405 * hdd_add_link_standard_info_sap - add add link info attribut
1406 * @skb: pointer to response skb buffer
1407 * @stainfo: station information
1408 * @idx: attribute type index for nla_next_start()
1409 *
1410 * This function adds link info attribut to response skb buffer
1411 *
1412 * Return : 0 on success and errno on failure
1413 */
1414static int hdd_add_link_standard_info_sap(struct sk_buff *skb, int8_t rssi,
1415 struct hdd_cache_sta_info *stainfo,
1416 int idx)
1417{
1418 struct nlattr *nla_attr;
1419
1420 nla_attr = nla_nest_start(skb, idx);
1421 if (!nla_attr)
1422 goto fail;
1423 if (hdd_add_survey_info_sap(skb, stainfo, NL80211_ATTR_SURVEY_INFO))
1424 goto fail;
1425 if (hdd_add_sta_info_sap(skb, rssi, stainfo, NL80211_ATTR_STA_INFO))
1426 goto fail;
1427
1428 if (nla_put_u32(skb, NL80211_ATTR_REASON_CODE, stainfo->reason_code)) {
1429 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1430 FL("put fail"));
1431 goto fail;
1432 }
1433
1434 nla_nest_end(skb, nla_attr);
1435 return 0;
1436fail:
1437 return -EINVAL;
1438}
1439
1440/**
1441 * hdd_add_ap_standard_info_sap_get_len - get data length used in
1442 * hdd_add_ap_standard_info_sap()
1443 * @stainfo: station information
1444 *
1445 * This function calculates the data length used in
1446 * hdd_add_ap_standard_info_sap()
1447 *
1448 * Return: total data length used in hdd_add_ap_standard_info_sap()
1449 */
1450static uint32_t hdd_add_ap_standard_info_sap_get_len(
1451 struct hdd_cache_sta_info *stainfo)
1452{
1453 uint32_t len;
1454
1455 len = NLA_HDRLEN;
1456 if (stainfo->vht_present)
1457 len += (sizeof(stainfo->vht_caps) + NLA_HDRLEN);
1458 if (stainfo->ht_present)
1459 len += (sizeof(stainfo->ht_caps) + NLA_HDRLEN);
1460
1461 return len;
1462}
1463
1464/**
1465 * hdd_add_ap_standard_info_sap - add HT and VHT info attributes
1466 * @skb: pointer to response skb buffer
1467 * @stainfo: station information
1468 * @idx: attribute type index for nla_next_start()
1469 *
1470 * This function adds HT and VHT info attributes to response skb buffer
1471 *
1472 * Return : 0 on success and errno on failure
1473 */
1474static int hdd_add_ap_standard_info_sap(struct sk_buff *skb,
1475 struct hdd_cache_sta_info *stainfo,
1476 int idx)
1477{
1478 struct nlattr *nla_attr;
1479
1480 nla_attr = nla_nest_start(skb, idx);
1481 if (!nla_attr)
1482 goto fail;
1483
1484 if (stainfo->vht_present) {
1485 if (nla_put(skb, NL80211_ATTR_VHT_CAPABILITY,
1486 sizeof(stainfo->vht_caps),
1487 &stainfo->vht_caps)) {
1488 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1489 FL("put fail"));
1490 goto fail;
1491 }
1492 }
1493 if (stainfo->ht_present) {
1494 if (nla_put(skb, NL80211_ATTR_HT_CAPABILITY,
1495 sizeof(stainfo->ht_caps),
1496 &stainfo->ht_caps)) {
1497 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1498 FL("put fail"));
1499 goto fail;
1500 }
1501 }
1502 nla_nest_end(skb, nla_attr);
1503 return 0;
1504fail:
1505 return -EINVAL;
1506}
1507
1508/**
1509 * hdd_decode_ch_width - decode channel band width based
1510 * @ch_width: encoded enum value holding channel band width
1511 *
1512 * This function decodes channel band width from the given encoded enum value.
1513 *
1514 * Returns: decoded channel band width.
1515 */
1516static uint8_t hdd_decode_ch_width(tSirMacHTChannelWidth ch_width)
1517{
1518 switch (ch_width) {
1519 case 0:
1520 return 20;
1521 case 1:
1522 return 40;
1523 case 2:
1524 return 80;
1525 default:
1526 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1527 "invalid enum: %d", ch_width);
1528 return 20;
1529 }
1530}
1531
1532/**
1533 * hdd_get_cached_station_remote() - get cached(deleted) peer's info
1534 * @hdd_ctx: hdd context
1535 * @adapter: hostapd interface
1536 * @mac_addr: mac address of requested peer
1537 *
1538 * This function collect and indicate the cached(deleted) peer's info
1539 *
1540 * Return: 0 on success, otherwise error value
1541 */
1542static int hdd_get_cached_station_remote(hdd_context_t *hdd_ctx,
1543 hdd_adapter_t *adapter,
1544 v_MACADDR_t mac_addr)
1545{
1546 struct hdd_cache_sta_info *stainfo;
1547 struct sk_buff *skb = NULL;
1548 uint32_t nl_buf_len;
1549 uint8_t cw;
1550 ptSapContext sap_ctx;
1551 v_CONTEXT_t vos_ctx = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
1552
1553 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
1554 if(sap_ctx == NULL){
1555 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1556 FL("psapCtx is NULL"));
1557 return -ENOENT;
1558 }
1559
1560 stainfo = hdd_get_cache_stainfo(sap_ctx->cache_sta_info,
1561 mac_addr.bytes);
1562 if (!stainfo) {
1563 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1564 "peer " MAC_ADDRESS_STR " not found",
1565 MAC_ADDR_ARRAY(mac_addr.bytes));
1566 return -EINVAL;
1567 }
1568 if (sap_ctx->aStaInfo[stainfo->ucSTAId].isUsed == TRUE) {
1569 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1570 "peer " MAC_ADDRESS_STR " is in connected state",
1571 MAC_ADDR_ARRAY(mac_addr.bytes));
1572 return -EINVAL;
1573 }
1574
1575
1576 nl_buf_len = NLMSG_HDRLEN + hdd_add_link_standard_info_sap_get_len() +
1577 hdd_add_ap_standard_info_sap_get_len(stainfo) +
1578 (sizeof(stainfo->dot11_mode) + NLA_HDRLEN) +
1579 (sizeof(cw) + NLA_HDRLEN) +
1580 (sizeof(stainfo->rx_rate) + NLA_HDRLEN);
1581
1582 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
1583 if (!skb) {
1584 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "cfg80211_vendor_cmd_alloc_reply_skb failed");
1585 return -ENOMEM;
1586 }
1587
1588 if (hdd_add_link_standard_info_sap(skb, stainfo->rssi, stainfo,
1589 LINK_INFO_STANDARD_NL80211_ATTR)) {
1590 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "link standard put fail");
1591 goto fail;
1592 }
1593
1594 if (hdd_add_ap_standard_info_sap(skb, stainfo,
1595 AP_INFO_STANDARD_NL80211_ATTR)) {
1596 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "ap standard put fail");
1597 goto fail;
1598 }
1599
1600 /* upper layer expects decoded channel BW */
1601 cw = hdd_decode_ch_width(stainfo->ch_width);
1602 if (nla_put_u32(skb, REMOTE_SUPPORTED_MODE, stainfo->dot11_mode) ||
1603 nla_put_u8(skb, REMOTE_CH_WIDTH, cw)) {
1604 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "remote ch put fail");
1605 goto fail;
1606 }
Hanumanth Reddy Pothula504fe152018-01-02 20:41:03 +05301607 if (nla_put_u32(skb, REMOTE_LAST_RX_RATE, (stainfo->rx_rate * 100))) {
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301608 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "rx rate put fail");
1609 goto fail;
1610 }
1611
1612 vos_mem_zero(stainfo, sizeof(*stainfo));
1613
1614 return cfg80211_vendor_cmd_reply(skb);
1615fail:
1616 if (skb)
1617 kfree_skb(skb);
1618
1619 return -EINVAL;
1620}
1621
1622/**
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301623 * __hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
1624 * @wiphy: corestack handler
1625 * @wdev: wireless device
1626 * @data: data
1627 * @data_len: data length
1628 *
1629 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
1630 * Validate cmd attributes and send the station info to upper layers.
1631 *
1632 * Return: Success(0) or reason code for failure
1633 */
1634static int32_t
1635__hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
1636 struct wireless_dev *wdev,
1637 const void *data,
1638 int data_len)
1639{
1640 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
1641 struct net_device *dev = wdev->netdev;
1642 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
1643 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX + 1];
1644 int32_t status;
1645
1646 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"Enter");
1647 if (VOS_FTM_MODE == hdd_get_conparam()) {
1648 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"Command not allowed in FTM mode");
1649 status = -EPERM;
1650 goto out;
1651 }
1652
1653 status = wlan_hdd_validate_context(hdd_ctx);
1654 if (0 != status)
1655 goto out;
1656
1657
1658 status = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX,
1659 data, data_len, NULL);
1660 if (status) {
1661 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"Invalid ATTR");
1662 goto out;
1663 }
1664
1665 /* Parse and fetch Command Type*/
1666 if (tb[STATION_INFO]) {
1667 status = hdd_get_station_info(hdd_ctx, adapter);
1668 } else if (tb[STATION_ASSOC_FAIL_REASON]) {
1669 status = hdd_get_station_assoc_fail(hdd_ctx, adapter);
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301670 } else if (tb[STATION_REMOTE]) {
1671 v_MACADDR_t mac_addr;
1672
1673 if (adapter->device_mode != WLAN_HDD_SOFTAP &&
1674 adapter->device_mode != WLAN_HDD_P2P_GO) {
1675 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"invalid device_mode:%d",
1676 adapter->device_mode);
1677 status = -EINVAL;
1678 goto out;
1679 }
1680
1681 nla_memcpy(mac_addr.bytes, tb[STATION_REMOTE],
1682 VOS_MAC_ADDRESS_LEN);
1683
1684 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "STATION_REMOTE "MAC_ADDRESS_STR"",
1685 MAC_ADDR_ARRAY(mac_addr.bytes));
1686
1687 status = hdd_get_cached_station_remote(hdd_ctx, adapter,
1688 mac_addr);
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301689 } else {
1690 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"get station info cmd type failed");
1691 status = -EINVAL;
1692 goto out;
1693 }
1694 EXIT();
1695out:
1696 return status;
1697}
1698
1699/**
1700 * wlan_hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
1701 * @wiphy: corestack handler
1702 * @wdev: wireless device
1703 * @data: data
1704 * @data_len: data length
1705 *
1706 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
1707 * Validate cmd attributes and send the station info to upper layers.
1708 *
1709 * Return: Success(0) or reason code for failure
1710 */
1711static int32_t
1712hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
1713 struct wireless_dev *wdev,
1714 const void *data,
1715 int data_len)
1716{
1717 int ret;
1718
1719 vos_ssr_protect(__func__);
1720 ret = __hdd_cfg80211_get_station_cmd(wiphy, wdev, data, data_len);
1721 vos_ssr_unprotect(__func__);
1722
1723 return ret;
1724}
1725
1726/*
1727 * undef short names defined for get station command
1728 * used by __wlan_hdd_cfg80211_get_station_cmd()
1729 */
1730#undef STATION_INVALID
1731#undef STATION_INFO
1732#undef STATION_ASSOC_FAIL_REASON
1733#undef STATION_MAX
Srinivas Dasari030bad32015-02-18 23:23:54 +05301734
Sunil Duttc69bccb2014-05-26 21:30:20 +05301735#ifdef WLAN_FEATURE_LINK_LAYER_STATS
1736
1737static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
1738 struct sk_buff *vendor_event)
1739{
1740 if (nla_put_u8(vendor_event,
1741 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
1742 stats->rate.preamble) ||
1743 nla_put_u8(vendor_event,
1744 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
1745 stats->rate.nss) ||
1746 nla_put_u8(vendor_event,
1747 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
1748 stats->rate.bw) ||
1749 nla_put_u8(vendor_event,
1750 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
1751 stats->rate.rateMcsIdx) ||
1752 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
1753 stats->rate.bitrate ) ||
1754 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
1755 stats->txMpdu ) ||
1756 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
1757 stats->rxMpdu ) ||
1758 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
1759 stats->mpduLost ) ||
1760 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
1761 stats->retries) ||
1762 nla_put_u32(vendor_event,
1763 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
1764 stats->retriesShort ) ||
1765 nla_put_u32(vendor_event,
1766 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
1767 stats->retriesLong))
1768 {
1769 hddLog(VOS_TRACE_LEVEL_ERROR,
1770 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1771 return FALSE;
1772 }
1773 return TRUE;
1774}
1775
1776static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
1777 struct sk_buff *vendor_event)
1778{
1779 u32 i = 0;
1780 struct nlattr *rateInfo;
1781 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
1782 stats->type) ||
1783 nla_put(vendor_event,
1784 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
1785 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
1786 nla_put_u32(vendor_event,
1787 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
1788 stats->capabilities) ||
1789 nla_put_u32(vendor_event,
1790 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
1791 stats->numRate))
1792 {
1793 hddLog(VOS_TRACE_LEVEL_ERROR,
1794 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1795 goto error;
1796 }
1797
1798 rateInfo = nla_nest_start(vendor_event,
1799 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301800 if(!rateInfo)
1801 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301802 for (i = 0; i < stats->numRate; i++)
1803 {
1804 struct nlattr *rates;
1805 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
1806 stats->rateStats +
1807 (i * sizeof(tSirWifiRateStat)));
1808 rates = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301809 if(!rates)
1810 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301811
1812 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
1813 {
1814 hddLog(VOS_TRACE_LEVEL_ERROR,
1815 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1816 return FALSE;
1817 }
1818 nla_nest_end(vendor_event, rates);
1819 }
1820 nla_nest_end(vendor_event, rateInfo);
1821
1822 return TRUE;
1823error:
1824 return FALSE;
1825}
1826
1827static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
1828 struct sk_buff *vendor_event)
1829{
1830 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
1831 stats->ac ) ||
1832 nla_put_u32(vendor_event,
1833 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
1834 stats->txMpdu ) ||
1835 nla_put_u32(vendor_event,
1836 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
1837 stats->rxMpdu ) ||
1838 nla_put_u32(vendor_event,
1839 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
1840 stats->txMcast ) ||
1841 nla_put_u32(vendor_event,
1842 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
1843 stats->rxMcast ) ||
1844 nla_put_u32(vendor_event,
1845 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
1846 stats->rxAmpdu ) ||
1847 nla_put_u32(vendor_event,
1848 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
1849 stats->txAmpdu ) ||
1850 nla_put_u32(vendor_event,
1851 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
1852 stats->mpduLost )||
1853 nla_put_u32(vendor_event,
1854 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
1855 stats->retries ) ||
1856 nla_put_u32(vendor_event,
1857 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
1858 stats->retriesShort ) ||
1859 nla_put_u32(vendor_event,
1860 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
1861 stats->retriesLong ) ||
1862 nla_put_u32(vendor_event,
1863 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
1864 stats->contentionTimeMin ) ||
1865 nla_put_u32(vendor_event,
1866 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
1867 stats->contentionTimeMax ) ||
1868 nla_put_u32(vendor_event,
1869 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
1870 stats->contentionTimeAvg ) ||
1871 nla_put_u32(vendor_event,
1872 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
1873 stats->contentionNumSamples ))
1874 {
1875 hddLog(VOS_TRACE_LEVEL_ERROR,
1876 FL("QCA_WLAN_VENDOR_ATTR put fail") );
1877 return FALSE;
1878 }
1879 return TRUE;
1880}
1881
1882static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
1883 struct sk_buff *vendor_event)
1884{
Dino Myclec8f3f332014-07-21 16:48:27 +05301885 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301886 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
1887 nla_put(vendor_event,
1888 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
1889 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
1890 nla_put_u32(vendor_event,
1891 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
1892 stats->state ) ||
1893 nla_put_u32(vendor_event,
1894 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
1895 stats->roaming ) ||
1896 nla_put_u32(vendor_event,
1897 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
1898 stats->capabilities ) ||
1899 nla_put(vendor_event,
1900 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
1901 strlen(stats->ssid), stats->ssid) ||
1902 nla_put(vendor_event,
1903 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
1904 WNI_CFG_BSSID_LEN, stats->bssid) ||
1905 nla_put(vendor_event,
1906 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
1907 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
1908 nla_put(vendor_event,
1909 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
1910 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
1911 )
1912 {
1913 hddLog(VOS_TRACE_LEVEL_ERROR,
1914 FL("QCA_WLAN_VENDOR_ATTR put fail") );
1915 return FALSE;
1916 }
1917 return TRUE;
1918}
1919
Dino Mycle3b9536d2014-07-09 22:05:24 +05301920static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
1921 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301922 struct sk_buff *vendor_event)
1923{
1924 int i = 0;
1925 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301926 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1927 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05301928 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301929
Sunil Duttc69bccb2014-05-26 21:30:20 +05301930 if (FALSE == put_wifi_interface_info(
1931 &pWifiIfaceStat->info,
1932 vendor_event))
1933 {
1934 hddLog(VOS_TRACE_LEVEL_ERROR,
1935 FL("QCA_WLAN_VENDOR_ATTR put fail") );
1936 return FALSE;
1937
1938 }
Dino Mycle3b9536d2014-07-09 22:05:24 +05301939 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
1940 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
1941 if (NULL == pWifiIfaceStatTL)
1942 {
1943 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
1944 return FALSE;
1945 }
1946
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05301947 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
1948 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
1949 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
1950 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
1951
1952 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
1953 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
1954 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
1955 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301956
1957 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
1958 {
1959 if (VOS_STATUS_SUCCESS ==
1960 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1961 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
1962 {
1963 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
1964 * obtained from TL structure
1965 */
1966
1967 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
1968 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301969 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
1970
Srinivas Dasari98947432014-11-07 19:41:24 +05301971 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
1972 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
1973 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
1974 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
1975 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
1976 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
1977 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
1978 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301979
Srinivas Dasari98947432014-11-07 19:41:24 +05301980 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
1981 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
1982 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
1983 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
1984 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
1985 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
1986 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
1987 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301988
Srinivas Dasari98947432014-11-07 19:41:24 +05301989 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
1990 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
1991 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
1992 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
1993 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
1994 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
1995 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
1996 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301997 }
1998 else
1999 {
2000 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
2001 }
2002
Dino Mycle3b9536d2014-07-09 22:05:24 +05302003 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
2004 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
2005 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
2006 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
2007 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
2008 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
2009 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
2010 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
2011 }
2012 else
2013 {
2014 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
2015 }
2016
2017
Sunil Duttc69bccb2014-05-26 21:30:20 +05302018
2019 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302020 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2021 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_IFACE) ||
2022 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302023 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
2024 pWifiIfaceStat->beaconRx) ||
2025 nla_put_u32(vendor_event,
2026 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
2027 pWifiIfaceStat->mgmtRx) ||
2028 nla_put_u32(vendor_event,
2029 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
2030 pWifiIfaceStat->mgmtActionRx) ||
2031 nla_put_u32(vendor_event,
2032 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
2033 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302034 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302035 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
2036 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302037 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302038 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
2039 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302040 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302041 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
2042 pWifiIfaceStat->rssiAck))
2043 {
2044 hddLog(VOS_TRACE_LEVEL_ERROR,
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05302045 FL("QCA_WLAN_VENDOR_ATTR put fail"));
2046 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302047 return FALSE;
2048 }
2049
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05302050#ifdef FEATURE_EXT_LL_STAT
2051 /*
2052 * Ensure when EXT_LL_STAT is supported by both host and fwr,
2053 * then host should send Leaky AP stats to upper layer,
2054 * otherwise no need to send these stats.
2055 */
2056 if(sme_IsFeatureSupportedByFW(EXT_LL_STAT) &&
2057 sme_IsFeatureSupportedByDriver(EXT_LL_STAT)
2058 )
2059 {
2060 hddLog(VOS_TRACE_LEVEL_INFO,
2061 FL("EXT_LL_STAT is supported by fwr and host %u %u %u %llu"),
2062 pWifiIfaceStat->leakyApStat.is_leaky_ap,
2063 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked,
2064 pWifiIfaceStat->leakyApStat.rx_leak_window,
2065 pWifiIfaceStat->leakyApStat.avg_bcn_spread);
2066 if (nla_put_u32(vendor_event,
2067 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_DETECTED,
2068 pWifiIfaceStat->leakyApStat.is_leaky_ap) ||
2069 nla_put_u32(vendor_event,
2070 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_AVG_NUM_FRAMES_LEAKED,
2071 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked) ||
2072 nla_put_u32(vendor_event,
2073 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_GUARD_TIME,
2074 pWifiIfaceStat->leakyApStat.rx_leak_window) ||
2075 nla_put_u64(vendor_event,
2076 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_AVERAGE_TSF_OFFSET,
2077 pWifiIfaceStat->leakyApStat.avg_bcn_spread))
2078 {
2079 hddLog(VOS_TRACE_LEVEL_ERROR,
2080 FL("EXT_LL_STAT put fail"));
2081 vos_mem_free(pWifiIfaceStatTL);
2082 return FALSE;
2083 }
2084 }
2085#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +05302086 wmmInfo = nla_nest_start(vendor_event,
2087 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302088 if(!wmmInfo)
2089 {
2090 vos_mem_free(pWifiIfaceStatTL);
2091 return FALSE;
2092 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302093 for (i = 0; i < WIFI_AC_MAX; i++)
2094 {
2095 struct nlattr *wmmStats;
2096 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302097 if(!wmmStats)
2098 {
2099 vos_mem_free(pWifiIfaceStatTL);
2100 return FALSE;
2101 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302102 if (FALSE == put_wifi_wmm_ac_stat(
2103 &pWifiIfaceStat->AccessclassStats[i],
2104 vendor_event))
2105 {
2106 hddLog(VOS_TRACE_LEVEL_ERROR,
2107 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05302108 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302109 return FALSE;
2110 }
2111
2112 nla_nest_end(vendor_event, wmmStats);
2113 }
2114 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +05302115 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302116 return TRUE;
2117}
2118
2119static tSirWifiInterfaceMode
2120 hdd_map_device_to_ll_iface_mode ( int deviceMode )
2121{
2122 switch (deviceMode)
2123 {
2124 case WLAN_HDD_INFRA_STATION:
2125 return WIFI_INTERFACE_STA;
2126 case WLAN_HDD_SOFTAP:
2127 return WIFI_INTERFACE_SOFTAP;
2128 case WLAN_HDD_P2P_CLIENT:
2129 return WIFI_INTERFACE_P2P_CLIENT;
2130 case WLAN_HDD_P2P_GO:
2131 return WIFI_INTERFACE_P2P_GO;
2132 case WLAN_HDD_IBSS:
2133 return WIFI_INTERFACE_IBSS;
2134 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05302135 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302136 }
2137}
2138
2139static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
2140 tpSirWifiInterfaceInfo pInfo)
2141{
2142 v_U8_t *staMac = NULL;
2143 hdd_station_ctx_t *pHddStaCtx;
2144 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
2145 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
2146
2147 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
2148
2149 vos_mem_copy(pInfo->macAddr,
2150 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
2151
2152 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
2153 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
2154 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
2155 {
2156 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2157 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
2158 {
2159 pInfo->state = WIFI_DISCONNECTED;
2160 }
2161 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
2162 {
2163 hddLog(VOS_TRACE_LEVEL_ERROR,
2164 "%s: Session ID %d, Connection is in progress", __func__,
2165 pAdapter->sessionId);
2166 pInfo->state = WIFI_ASSOCIATING;
2167 }
2168 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
2169 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
2170 {
2171 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
2172 hddLog(VOS_TRACE_LEVEL_ERROR,
2173 "%s: client " MAC_ADDRESS_STR
2174 " is in the middle of WPS/EAPOL exchange.", __func__,
2175 MAC_ADDR_ARRAY(staMac));
2176 pInfo->state = WIFI_AUTHENTICATING;
2177 }
2178 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
2179 {
2180 pInfo->state = WIFI_ASSOCIATED;
2181 vos_mem_copy(pInfo->bssid,
2182 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
2183 vos_mem_copy(pInfo->ssid,
2184 pHddStaCtx->conn_info.SSID.SSID.ssId,
2185 pHddStaCtx->conn_info.SSID.SSID.length);
2186 //NULL Terminate the string.
2187 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
2188 }
2189 }
2190 vos_mem_copy(pInfo->countryStr,
2191 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
2192
2193 vos_mem_copy(pInfo->apCountryStr,
2194 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
2195
2196 return TRUE;
2197}
2198
2199/*
2200 * hdd_link_layer_process_peer_stats () - This function is called after
2201 * receiving Link Layer Peer statistics from FW.This function converts
2202 * the firmware data to the NL data and sends the same to the kernel/upper
2203 * layers.
2204 */
2205static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
2206 v_VOID_t *pData)
2207{
2208 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302209 tpSirWifiPeerStat pWifiPeerStat;
2210 tpSirWifiPeerInfo pWifiPeerInfo;
2211 struct nlattr *peerInfo;
2212 struct sk_buff *vendor_event;
2213 int status, i;
2214
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302215 ENTER();
2216
Sunil Duttc69bccb2014-05-26 21:30:20 +05302217 status = wlan_hdd_validate_context(pHddCtx);
2218 if (0 != status)
2219 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302220 return;
2221 }
2222
2223 pWifiPeerStat = (tpSirWifiPeerStat) pData;
2224
2225 hddLog(VOS_TRACE_LEVEL_INFO,
2226 "LL_STATS_PEER_ALL : numPeers %u",
2227 pWifiPeerStat->numPeers);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302228 /*
2229 * Allocate a size of 4096 for the peer stats comprising
2230 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
2231 * sizeof (tSirWifiRateStat).Each field is put with an
2232 * NL attribute.The size of 4096 is considered assuming
2233 * that number of rates shall not exceed beyond 50 with
2234 * the sizeof (tSirWifiRateStat) being 32.
2235 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302236 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2237 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302238 if (!vendor_event)
2239 {
2240 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302241 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
Sunil Duttc69bccb2014-05-26 21:30:20 +05302242 __func__);
2243 return;
2244 }
2245 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302246 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2247 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_PEER) ||
2248 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302249 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
2250 pWifiPeerStat->numPeers))
2251 {
2252 hddLog(VOS_TRACE_LEVEL_ERROR,
2253 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
2254 kfree_skb(vendor_event);
2255 return;
2256 }
2257
2258 peerInfo = nla_nest_start(vendor_event,
2259 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302260 if(!peerInfo)
2261 {
2262 hddLog(VOS_TRACE_LEVEL_ERROR,
2263 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
2264 __func__);
2265 kfree_skb(vendor_event);
2266 return;
2267 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302268
2269 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
2270 pWifiPeerStat->peerInfo);
2271
2272 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
2273 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302274 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302275 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302276
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302277 if(!peers)
2278 {
2279 hddLog(VOS_TRACE_LEVEL_ERROR,
2280 "%s: peer stats put fail",
2281 __func__);
2282 kfree_skb(vendor_event);
2283 return;
2284 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302285 if (FALSE == put_wifi_peer_info(
2286 pWifiPeerInfo, vendor_event))
2287 {
2288 hddLog(VOS_TRACE_LEVEL_ERROR,
2289 "%s: put_wifi_peer_info put fail", __func__);
2290 kfree_skb(vendor_event);
2291 return;
2292 }
2293
2294 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
2295 pWifiPeerStat->peerInfo +
2296 (i * sizeof(tSirWifiPeerInfo)) +
2297 (numRate * sizeof (tSirWifiRateStat)));
2298 nla_nest_end(vendor_event, peers);
2299 }
2300 nla_nest_end(vendor_event, peerInfo);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302301 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302302 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302303}
2304
2305/*
2306 * hdd_link_layer_process_iface_stats () - This function is called after
2307 * receiving Link Layer Interface statistics from FW.This function converts
2308 * the firmware data to the NL data and sends the same to the kernel/upper
2309 * layers.
2310 */
2311static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
2312 v_VOID_t *pData)
2313{
2314 tpSirWifiIfaceStat pWifiIfaceStat;
2315 struct sk_buff *vendor_event;
2316 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2317 int status;
2318
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302319 ENTER();
2320
Sunil Duttc69bccb2014-05-26 21:30:20 +05302321 status = wlan_hdd_validate_context(pHddCtx);
2322 if (0 != status)
2323 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302324 return;
2325 }
2326 /*
2327 * Allocate a size of 4096 for the interface stats comprising
2328 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
2329 * assuming that all these fit with in the limit.Please take
2330 * a call on the limit based on the data requirements on
2331 * interface statistics.
2332 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302333 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2334 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302335 if (!vendor_event)
2336 {
2337 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302338 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05302339 return;
2340 }
2341
2342 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
2343
Dino Mycle3b9536d2014-07-09 22:05:24 +05302344
2345 if (FALSE == hdd_get_interface_info( pAdapter,
2346 &pWifiIfaceStat->info))
2347 {
2348 hddLog(VOS_TRACE_LEVEL_ERROR,
2349 FL("hdd_get_interface_info get fail") );
2350 kfree_skb(vendor_event);
2351 return;
2352 }
2353
2354 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
2355 vendor_event))
2356 {
2357 hddLog(VOS_TRACE_LEVEL_ERROR,
2358 FL("put_wifi_iface_stats fail") );
2359 kfree_skb(vendor_event);
2360 return;
2361 }
2362
Sunil Duttc69bccb2014-05-26 21:30:20 +05302363 hddLog(VOS_TRACE_LEVEL_INFO,
2364 "WMI_LINK_STATS_IFACE Data");
2365
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302366 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302367
2368 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302369}
2370
2371/*
2372 * hdd_link_layer_process_radio_stats () - This function is called after
2373 * receiving Link Layer Radio statistics from FW.This function converts
2374 * the firmware data to the NL data and sends the same to the kernel/upper
2375 * layers.
2376 */
2377static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
2378 v_VOID_t *pData)
2379{
2380 int status, i;
2381 tpSirWifiRadioStat pWifiRadioStat;
2382 tpSirWifiChannelStats pWifiChannelStats;
2383 struct sk_buff *vendor_event;
2384 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2385 struct nlattr *chList;
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;
2393 }
2394 pWifiRadioStat = (tpSirWifiRadioStat) pData;
2395
2396 hddLog(VOS_TRACE_LEVEL_INFO,
2397 "LL_STATS_RADIO"
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302398 " number of radios = %u"
Sunil Duttc69bccb2014-05-26 21:30:20 +05302399 " radio is %d onTime is %u "
2400 " txTime is %u rxTime is %u "
2401 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05302402 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05302403 " onTimePnoScan is %u onTimeHs20 is %u "
2404 " numChannels is %u",
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302405 NUM_RADIOS,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302406 pWifiRadioStat->radio, pWifiRadioStat->onTime,
2407 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
2408 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302409 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302410 pWifiRadioStat->onTimeRoamScan,
2411 pWifiRadioStat->onTimePnoScan,
2412 pWifiRadioStat->onTimeHs20,
2413 pWifiRadioStat->numChannels);
2414 /*
2415 * Allocate a size of 4096 for the Radio stats comprising
2416 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
2417 * (tSirWifiChannelStats).Each channel data is put with an
2418 * NL attribute.The size of 4096 is considered assuming that
2419 * number of channels shall not exceed beyond 60 with the
2420 * sizeof (tSirWifiChannelStats) being 24 bytes.
2421 */
2422
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302423 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2424 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302425 if (!vendor_event)
2426 {
2427 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302428 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05302429 return;
2430 }
2431
2432 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302433 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2434 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO) ||
2435 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302436 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
2437 pWifiRadioStat->radio) ||
2438 nla_put_u32(vendor_event,
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302439 QCA_WLAN_VENDOR_ATTR_LL_STATS_NUM_RADIOS,
2440 NUM_RADIOS) ||
2441 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302442 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
2443 pWifiRadioStat->onTime) ||
2444 nla_put_u32(vendor_event,
2445 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
2446 pWifiRadioStat->txTime) ||
2447 nla_put_u32(vendor_event,
2448 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
2449 pWifiRadioStat->rxTime) ||
2450 nla_put_u32(vendor_event,
2451 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
2452 pWifiRadioStat->onTimeScan) ||
2453 nla_put_u32(vendor_event,
2454 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
2455 pWifiRadioStat->onTimeNbd) ||
2456 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302457 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
2458 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05302459 nla_put_u32(vendor_event,
2460 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
2461 pWifiRadioStat->onTimeRoamScan) ||
2462 nla_put_u32(vendor_event,
2463 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
2464 pWifiRadioStat->onTimePnoScan) ||
2465 nla_put_u32(vendor_event,
2466 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
2467 pWifiRadioStat->onTimeHs20) ||
2468 nla_put_u32(vendor_event,
2469 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
2470 pWifiRadioStat->numChannels))
2471 {
2472 hddLog(VOS_TRACE_LEVEL_ERROR,
2473 FL("QCA_WLAN_VENDOR_ATTR put fail"));
2474 kfree_skb(vendor_event);
2475 return ;
2476 }
2477
2478 chList = nla_nest_start(vendor_event,
2479 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302480 if(!chList)
2481 {
2482 hddLog(VOS_TRACE_LEVEL_ERROR,
2483 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
2484 __func__);
2485 kfree_skb(vendor_event);
2486 return;
2487 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302488 for (i = 0; i < pWifiRadioStat->numChannels; i++)
2489 {
2490 struct nlattr *chInfo;
2491
2492 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
2493 pWifiRadioStat->channels +
2494 (i * sizeof(tSirWifiChannelStats)));
2495
Sunil Duttc69bccb2014-05-26 21:30:20 +05302496 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302497 if(!chInfo)
2498 {
2499 hddLog(VOS_TRACE_LEVEL_ERROR,
2500 "%s: failed to put chInfo",
2501 __func__);
2502 kfree_skb(vendor_event);
2503 return;
2504 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302505
2506 if (nla_put_u32(vendor_event,
2507 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
2508 pWifiChannelStats->channel.width) ||
2509 nla_put_u32(vendor_event,
2510 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
2511 pWifiChannelStats->channel.centerFreq) ||
2512 nla_put_u32(vendor_event,
2513 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
2514 pWifiChannelStats->channel.centerFreq0) ||
2515 nla_put_u32(vendor_event,
2516 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
2517 pWifiChannelStats->channel.centerFreq1) ||
2518 nla_put_u32(vendor_event,
2519 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
2520 pWifiChannelStats->onTime) ||
2521 nla_put_u32(vendor_event,
2522 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
2523 pWifiChannelStats->ccaBusyTime))
2524 {
2525 hddLog(VOS_TRACE_LEVEL_ERROR,
2526 FL("cfg80211_vendor_event_alloc failed") );
2527 kfree_skb(vendor_event);
2528 return ;
2529 }
2530 nla_nest_end(vendor_event, chInfo);
2531 }
2532 nla_nest_end(vendor_event, chList);
2533
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302534 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302535
2536 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302537 return;
2538}
2539
2540/*
2541 * hdd_link_layer_stats_ind_callback () - This function is called after
2542 * receiving Link Layer indications from FW.This callback converts the firmware
2543 * data to the NL data and send the same to the kernel/upper layers.
2544 */
2545static void hdd_link_layer_stats_ind_callback ( void *pCtx,
2546 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05302547 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302548{
Dino Mycled3d50022014-07-07 12:58:25 +05302549 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
2550 hdd_adapter_t *pAdapter = NULL;
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302551 struct hdd_ll_stats_context *context;
Dino Mycled3d50022014-07-07 12:58:25 +05302552 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302553 int status;
2554
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302555 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302556
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302557 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302558 if (0 != status)
2559 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302560 return;
2561 }
2562
Dino Mycled3d50022014-07-07 12:58:25 +05302563 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
2564 if (NULL == pAdapter)
2565 {
2566 hddLog(VOS_TRACE_LEVEL_ERROR,
2567 FL(" MAC address %pM does not exist with host"),
2568 macAddr);
2569 return;
2570 }
2571
Sunil Duttc69bccb2014-05-26 21:30:20 +05302572 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05302573 "%s: Interface: %s LLStats indType: %d", __func__,
2574 pAdapter->dev->name, indType);
2575
Sunil Duttc69bccb2014-05-26 21:30:20 +05302576 switch (indType)
2577 {
2578 case SIR_HAL_LL_STATS_RESULTS_RSP:
2579 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302580 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302581 "LL_STATS RESP paramID = 0x%x, ifaceId = %u MAC: %pM "
2582 "respId = %u, moreResultToFollow = %u",
2583 linkLayerStatsResults->paramId, linkLayerStatsResults->ifaceId,
2584 macAddr, linkLayerStatsResults->respId,
2585 linkLayerStatsResults->moreResultToFollow);
2586
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302587 spin_lock(&hdd_context_lock);
2588 context = &pHddCtx->ll_stats_context;
2589 /* validate response received from target */
2590 if ((context->request_id != linkLayerStatsResults->respId) ||
2591 !(context->request_bitmap & linkLayerStatsResults->paramId))
2592 {
2593 spin_unlock(&hdd_context_lock);
2594 hddLog(LOGE,
2595 FL("Error : Request id %d response id %d request bitmap 0x%x"
2596 "response bitmap 0x%x"),
2597 context->request_id, linkLayerStatsResults->respId,
2598 context->request_bitmap, linkLayerStatsResults->paramId);
2599 return;
2600 }
2601 spin_unlock(&hdd_context_lock);
2602
Sunil Duttc69bccb2014-05-26 21:30:20 +05302603 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
2604 {
2605 hdd_link_layer_process_radio_stats(pAdapter,
2606 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302607 spin_lock(&hdd_context_lock);
2608 context->request_bitmap &= ~(WMI_LINK_STATS_RADIO);
2609 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302610 }
2611 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
2612 {
2613 hdd_link_layer_process_iface_stats(pAdapter,
2614 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302615 spin_lock(&hdd_context_lock);
2616 context->request_bitmap &= ~(WMI_LINK_STATS_IFACE);
2617 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302618 }
2619 else if ( linkLayerStatsResults->paramId &
2620 WMI_LINK_STATS_ALL_PEER )
2621 {
2622 hdd_link_layer_process_peer_stats(pAdapter,
2623 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302624 spin_lock(&hdd_context_lock);
2625 context->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER);
2626 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302627 } /* WMI_LINK_STATS_ALL_PEER */
2628 else
2629 {
2630 hddLog(VOS_TRACE_LEVEL_ERROR,
2631 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
2632 }
2633
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302634 spin_lock(&hdd_context_lock);
2635 /* complete response event if all requests are completed */
2636 if (0 == context->request_bitmap)
2637 complete(&context->response_event);
2638 spin_unlock(&hdd_context_lock);
2639
Sunil Duttc69bccb2014-05-26 21:30:20 +05302640 break;
2641 }
2642 default:
2643 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
2644 break;
2645 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302646
2647 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302648 return;
2649}
2650
2651const struct
2652nla_policy
2653qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
2654{
2655 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
2656 { .type = NLA_U32 },
2657 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
2658 { .type = NLA_U32 },
2659};
2660
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302661static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
2662 struct wireless_dev *wdev,
2663 const void *data,
2664 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302665{
2666 int status;
2667 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302668 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302669 struct net_device *dev = wdev->netdev;
2670 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2671 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2672
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302673 ENTER();
2674
Sunil Duttc69bccb2014-05-26 21:30:20 +05302675 status = wlan_hdd_validate_context(pHddCtx);
2676 if (0 != status)
2677 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302678 return -EINVAL;
2679 }
2680
2681 if (NULL == pAdapter)
2682 {
2683 hddLog(VOS_TRACE_LEVEL_ERROR,
2684 FL("HDD adapter is Null"));
2685 return -ENODEV;
2686 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302687 /* check the LLStats Capability */
2688 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2689 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2690 {
Anurag Chouhan65ea6dc2016-10-25 19:59:14 +05302691 hddLog(VOS_TRACE_LEVEL_WARN,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302692 FL("Link Layer Statistics not supported by Firmware"));
2693 return -EINVAL;
2694 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302695
2696 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
2697 (struct nlattr *)data,
2698 data_len, qca_wlan_vendor_ll_set_policy))
2699 {
2700 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2701 return -EINVAL;
2702 }
2703 if (!tb_vendor
2704 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
2705 {
2706 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
2707 return -EINVAL;
2708 }
2709 if (!tb_vendor[
2710 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
2711 {
2712 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
2713 return -EINVAL;
2714 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302715 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302716 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302717
Dino Mycledf0a5d92014-07-04 09:41:55 +05302718 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302719 nla_get_u32(
2720 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
2721
Dino Mycledf0a5d92014-07-04 09:41:55 +05302722 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302723 nla_get_u32(
2724 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
2725
Dino Mycled3d50022014-07-07 12:58:25 +05302726 vos_mem_copy(linkLayerStatsSetReq.macAddr,
2727 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302728
2729
2730 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302731 "LL_STATS_SET reqId = %d, MAC = %pM, mpduSizeThreshold = %d "
2732 "Statistics Gathering = %d ",
2733 linkLayerStatsSetReq.reqId, linkLayerStatsSetReq.macAddr,
2734 linkLayerStatsSetReq.mpduSizeThreshold,
2735 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302736
2737 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
2738 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05302739 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302740 {
2741 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2742 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302743 return -EINVAL;
2744
2745 }
Srinivas Dasari98947432014-11-07 19:41:24 +05302746
Sunil Duttc69bccb2014-05-26 21:30:20 +05302747 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302748 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302749 {
2750 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2751 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302752 return -EINVAL;
2753 }
2754
2755 pAdapter->isLinkLayerStatsSet = 1;
2756
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302757 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302758 return 0;
2759}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302760static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
2761 struct wireless_dev *wdev,
2762 const void *data,
2763 int data_len)
2764{
2765 int ret = 0;
2766
2767 vos_ssr_protect(__func__);
2768 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
2769 vos_ssr_unprotect(__func__);
2770
2771 return ret;
2772}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302773
2774const struct
2775nla_policy
2776qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
2777{
2778 /* Unsigned 32bit value provided by the caller issuing the GET stats
2779 * command. When reporting
2780 * the stats results, the driver uses the same value to indicate
2781 * which GET request the results
2782 * correspond to.
2783 */
2784 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
2785
2786 /* Unsigned 32bit value . bit mask to identify what statistics are
2787 requested for retrieval */
2788 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
2789};
2790
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302791static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
2792 struct wireless_dev *wdev,
2793 const void *data,
2794 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302795{
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302796 unsigned long rc;
2797 struct hdd_ll_stats_context *context;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302798 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2799 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302800 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302801 struct net_device *dev = wdev->netdev;
2802 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma10313ba2015-07-29 19:14:39 +05302803 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302804 int status;
2805
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302806 ENTER();
2807
Sunil Duttc69bccb2014-05-26 21:30:20 +05302808 status = wlan_hdd_validate_context(pHddCtx);
2809 if (0 != status)
2810 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302811 return -EINVAL ;
2812 }
2813
2814 if (NULL == pAdapter)
2815 {
2816 hddLog(VOS_TRACE_LEVEL_FATAL,
2817 "%s: HDD adapter is Null", __func__);
2818 return -ENODEV;
2819 }
Mukul Sharma10313ba2015-07-29 19:14:39 +05302820
2821 if (pHddStaCtx == NULL)
2822 {
2823 hddLog(VOS_TRACE_LEVEL_FATAL,
2824 "%s: HddStaCtx is Null", __func__);
2825 return -ENODEV;
2826 }
2827
Dino Mycledf0a5d92014-07-04 09:41:55 +05302828 /* check the LLStats Capability */
2829 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2830 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2831 {
2832 hddLog(VOS_TRACE_LEVEL_ERROR,
2833 FL("Link Layer Statistics not supported by Firmware"));
2834 return -EINVAL;
2835 }
2836
Sunil Duttc69bccb2014-05-26 21:30:20 +05302837
2838 if (!pAdapter->isLinkLayerStatsSet)
2839 {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05302840 hddLog(VOS_TRACE_LEVEL_ERROR,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302841 "%s: isLinkLayerStatsSet : %d",
2842 __func__, pAdapter->isLinkLayerStatsSet);
2843 return -EINVAL;
2844 }
2845
Mukul Sharma10313ba2015-07-29 19:14:39 +05302846 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
2847 {
2848 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2849 "%s: Roaming in progress, so unable to proceed this request", __func__);
2850 return -EBUSY;
2851 }
2852
Sunil Duttc69bccb2014-05-26 21:30:20 +05302853 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
2854 (struct nlattr *)data,
2855 data_len, qca_wlan_vendor_ll_get_policy))
2856 {
2857 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2858 return -EINVAL;
2859 }
2860
2861 if (!tb_vendor
2862 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
2863 {
2864 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
2865 return -EINVAL;
2866 }
2867
2868 if (!tb_vendor
2869 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
2870 {
2871 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
2872 return -EINVAL;
2873 }
2874
Sunil Duttc69bccb2014-05-26 21:30:20 +05302875
Dino Mycledf0a5d92014-07-04 09:41:55 +05302876 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302877 nla_get_u32( tb_vendor[
2878 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05302879 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302880 nla_get_u32( tb_vendor[
2881 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
2882
Dino Mycled3d50022014-07-07 12:58:25 +05302883 vos_mem_copy(linkLayerStatsGetReq.macAddr,
2884 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302885
2886 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302887 "LL_STATS_GET reqId = %d, MAC = %pM, paramIdMask = %d",
2888 linkLayerStatsGetReq.reqId, linkLayerStatsGetReq.macAddr,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302889 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302890
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302891 spin_lock(&hdd_context_lock);
2892 context = &pHddCtx->ll_stats_context;
2893 context->request_id = linkLayerStatsGetReq.reqId;
2894 context->request_bitmap = linkLayerStatsGetReq.paramIdMask;
2895 INIT_COMPLETION(context->response_event);
2896 spin_unlock(&hdd_context_lock);
2897
Sunil Duttc69bccb2014-05-26 21:30:20 +05302898 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302899 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302900 {
2901 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2902 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302903 return -EINVAL;
2904 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302905
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302906 rc = wait_for_completion_timeout(&context->response_event,
2907 msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS));
2908 if (!rc)
2909 {
2910 hddLog(LOGE,
2911 FL("Target response timed out request id %d request bitmap 0x%x"),
2912 context->request_id, context->request_bitmap);
2913 return -ETIMEDOUT;
2914 }
2915
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302916 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302917 return 0;
2918}
2919
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302920static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
2921 struct wireless_dev *wdev,
2922 const void *data,
2923 int data_len)
2924{
2925 int ret = 0;
2926
2927 vos_ssr_protect(__func__);
2928 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
2929 vos_ssr_unprotect(__func__);
2930
2931 return ret;
2932}
2933
Sunil Duttc69bccb2014-05-26 21:30:20 +05302934const struct
2935nla_policy
2936qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
2937{
2938 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
2939 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
2940 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
2941 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
2942};
2943
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302944static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2945 struct wireless_dev *wdev,
2946 const void *data,
2947 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302948{
2949 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2950 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302951 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302952 struct net_device *dev = wdev->netdev;
2953 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2954 u32 statsClearReqMask;
2955 u8 stopReq;
2956 int status;
2957
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302958 ENTER();
2959
Sunil Duttc69bccb2014-05-26 21:30:20 +05302960 status = wlan_hdd_validate_context(pHddCtx);
2961 if (0 != status)
2962 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302963 return -EINVAL;
2964 }
2965
2966 if (NULL == pAdapter)
2967 {
2968 hddLog(VOS_TRACE_LEVEL_FATAL,
2969 "%s: HDD adapter is Null", __func__);
2970 return -ENODEV;
2971 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302972 /* check the LLStats Capability */
2973 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2974 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2975 {
2976 hddLog(VOS_TRACE_LEVEL_ERROR,
2977 FL("Enable LLStats Capability"));
2978 return -EINVAL;
2979 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302980
2981 if (!pAdapter->isLinkLayerStatsSet)
2982 {
2983 hddLog(VOS_TRACE_LEVEL_FATAL,
2984 "%s: isLinkLayerStatsSet : %d",
2985 __func__, pAdapter->isLinkLayerStatsSet);
2986 return -EINVAL;
2987 }
2988
2989 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
2990 (struct nlattr *)data,
2991 data_len, qca_wlan_vendor_ll_clr_policy))
2992 {
2993 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2994 return -EINVAL;
2995 }
2996
2997 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
2998
2999 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
3000 {
3001 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
3002 return -EINVAL;
3003
3004 }
3005
Sunil Duttc69bccb2014-05-26 21:30:20 +05303006
Dino Mycledf0a5d92014-07-04 09:41:55 +05303007 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05303008 nla_get_u32(
3009 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
3010
Dino Mycledf0a5d92014-07-04 09:41:55 +05303011 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05303012 nla_get_u8(
3013 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
3014
3015 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05303016 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05303017
Dino Mycled3d50022014-07-07 12:58:25 +05303018 vos_mem_copy(linkLayerStatsClearReq.macAddr,
3019 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05303020
3021 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05303022 "LL_STATS_CLEAR reqId = %d, MAC = %pM,"
3023 "statsClearReqMask = 0x%X, stopReq = %d",
3024 linkLayerStatsClearReq.reqId,
3025 linkLayerStatsClearReq.macAddr,
3026 linkLayerStatsClearReq.statsClearReqMask,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303027 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05303028
3029 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303030 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05303031 {
3032 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05303033 hdd_station_ctx_t *pHddStaCtx;
3034
3035 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3036 if (VOS_STATUS_SUCCESS !=
3037 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
3038 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
3039 {
3040 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
3041 "WLANTL_ClearInterfaceStats Failed", __func__);
3042 return -EINVAL;
3043 }
3044 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
3045 (statsClearReqMask & WIFI_STATS_IFACE)) {
3046 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
3047 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
3048 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
3049 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
3050 }
3051
Sunil Duttc69bccb2014-05-26 21:30:20 +05303052 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
3053 2 * sizeof(u32) +
3054 NLMSG_HDRLEN);
3055
3056 if (temp_skbuff != NULL)
3057 {
3058
3059 if (nla_put_u32(temp_skbuff,
3060 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
3061 statsClearReqMask) ||
3062 nla_put_u32(temp_skbuff,
3063 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
3064 stopReq))
3065 {
3066 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
3067 kfree_skb(temp_skbuff);
3068 return -EINVAL;
3069 }
3070 /* If the ask is to stop the stats collection as part of clear
3071 * (stopReq = 1) , ensure that no further requests of get
3072 * go to the firmware by having isLinkLayerStatsSet set to 0.
3073 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303074 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05303075 * case the firmware is just asked to clear the statistics.
3076 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05303077 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05303078 pAdapter->isLinkLayerStatsSet = 0;
3079 return cfg80211_vendor_cmd_reply(temp_skbuff);
3080 }
3081 return -ENOMEM;
3082 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303083
3084 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05303085 return -EINVAL;
3086}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303087static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
3088 struct wireless_dev *wdev,
3089 const void *data,
3090 int data_len)
3091{
3092 int ret = 0;
3093
3094 vos_ssr_protect(__func__);
3095 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
3096 vos_ssr_unprotect(__func__);
3097
3098 return ret;
3099
3100
3101}
Sunil Duttc69bccb2014-05-26 21:30:20 +05303102#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
3103
Dino Mycle6fb96c12014-06-10 11:52:40 +05303104#ifdef WLAN_FEATURE_EXTSCAN
3105static const struct nla_policy
3106wlan_hdd_extscan_config_policy
3107 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
3108{
3109 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
3110 { .type = NLA_U32 },
3111 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
3112 { .type = NLA_U32 },
SaidiReddy Yenugaf2145922017-05-26 18:19:31 +05303113 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS] =
3114 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303115 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
3116 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
3117 { .type = NLA_U32 },
3118 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
3119 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
3120
3121 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
3122 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
3123 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
3124 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
3125 { .type = NLA_U8 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303126 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] =
3127 { .type = NLA_U32 },
3128 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT] =
3129 { .type = NLA_U32 },
3130 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] =
3131 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303132 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
3133 { .type = NLA_U32 },
3134 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
3135 { .type = NLA_U32 },
3136 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
3137 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303138 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] =
3139 { .type = NLA_U8 },
3140 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05303141 { .type = NLA_U8 },
3142 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
3143 { .type = NLA_U8 },
3144 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
3145 { .type = NLA_U8 },
3146
3147 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
3148 { .type = NLA_U32 },
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05303149 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] = {
3150 .type = NLA_UNSPEC,
3151 .len = HDD_MAC_ADDR_LEN},
Dino Mycle6fb96c12014-06-10 11:52:40 +05303152 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
3153 { .type = NLA_S32 },
3154 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
3155 { .type = NLA_S32 },
3156 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
3157 { .type = NLA_U32 },
3158 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
3159 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303160 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] =
3161 { .type = NLA_U32 },
3162 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] =
3163 { .type = NLA_BINARY,
3164 .len = IEEE80211_MAX_SSID_LEN + 1 },
3165 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05303166 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303167 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] =
3168 { .type = NLA_U32 },
3169 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] =
3170 { .type = NLA_U8 },
3171 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] =
3172 { .type = NLA_S32 },
3173 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] =
3174 { .type = NLA_S32 },
3175 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] =
3176 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303177};
3178
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303179/**
3180 * wlan_hdd_cfg80211_extscan_get_capabilities_rsp() - response from target
3181 * @ctx: hdd global context
3182 * @data: capabilities data
3183 *
3184 * Return: none
3185 */
3186static void
3187wlan_hdd_cfg80211_extscan_get_capabilities_rsp(void *ctx, void *pMsg)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303188{
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303189 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303190 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303191 tSirEXTScanCapabilitiesEvent *data =
3192 (tSirEXTScanCapabilitiesEvent *) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303193
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303194 ENTER();
3195
3196 if (wlan_hdd_validate_context(pHddCtx))
3197 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303198 return;
3199 }
3200
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303201 if (!pMsg)
3202 {
3203 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3204 return;
3205 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303206
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303207 vos_spin_lock_acquire(&hdd_context_lock);
3208
3209 context = &pHddCtx->ext_scan_context;
3210 /* validate response received from target*/
3211 if (context->request_id != data->requestId)
3212 {
3213 vos_spin_lock_release(&hdd_context_lock);
3214 hddLog(LOGE,
3215 FL("Target response id did not match: request_id %d resposne_id %d"),
3216 context->request_id, data->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303217 return;
3218 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303219 else
3220 {
3221 context->capability_response = *data;
3222 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303223 }
3224
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303225 vos_spin_lock_release(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303226
Dino Mycle6fb96c12014-06-10 11:52:40 +05303227 return;
3228}
3229
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303230/*
3231 * define short names for the global vendor params
3232 * used by wlan_hdd_send_ext_scan_capability()
3233 */
3234#define PARAM_REQUEST_ID \
3235 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
3236#define PARAM_STATUS \
3237 QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS
3238#define MAX_SCAN_CACHE_SIZE \
3239 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE
3240#define MAX_SCAN_BUCKETS \
3241 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS
3242#define MAX_AP_CACHE_PER_SCAN \
3243 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN
3244#define MAX_RSSI_SAMPLE_SIZE \
3245 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE
3246#define MAX_SCAN_RPT_THRHOLD \
3247 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
3248#define MAX_HOTLIST_BSSIDS \
3249 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS
3250#define MAX_BSSID_HISTORY_ENTRIES \
3251 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
3252#define MAX_HOTLIST_SSIDS \
3253 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303254#define MAX_SIGNIFICANT_WIFI_CHANGE_APS \
3255 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303256
3257static int wlan_hdd_send_ext_scan_capability(void *ctx)
3258{
3259 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3260 struct sk_buff *skb = NULL;
3261 int ret;
3262 tSirEXTScanCapabilitiesEvent *data;
3263 tANI_U32 nl_buf_len;
3264
3265 ret = wlan_hdd_validate_context(pHddCtx);
3266 if (0 != ret)
3267 {
3268 return ret;
3269 }
3270
3271 data = &(pHddCtx->ext_scan_context.capability_response);
3272
3273 nl_buf_len = NLMSG_HDRLEN;
3274 nl_buf_len += (sizeof(data->requestId) + NLA_HDRLEN) +
3275 (sizeof(data->status) + NLA_HDRLEN) +
3276 (sizeof(data->scanCacheSize) + NLA_HDRLEN) +
3277 (sizeof(data->scanBuckets) + NLA_HDRLEN) +
3278 (sizeof(data->maxApPerScan) + NLA_HDRLEN) +
3279 (sizeof(data->maxRssiSampleSize) + NLA_HDRLEN) +
3280 (sizeof(data->maxScanReportingThreshold) + NLA_HDRLEN) +
3281 (sizeof(data->maxHotlistAPs) + NLA_HDRLEN) +
3282 (sizeof(data->maxBsidHistoryEntries) + NLA_HDRLEN) +
3283 (sizeof(data->maxHotlistSSIDs) + NLA_HDRLEN);
3284
3285 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, nl_buf_len);
3286
3287 if (!skb)
3288 {
3289 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
3290 return -ENOMEM;
3291 }
3292
3293 hddLog(LOG1, "Req Id (%u) Status (%u)", data->requestId, data->status);
3294 hddLog(LOG1, "Scan cache size (%u) Scan buckets (%u) Max AP per scan (%u)",
3295 data->scanCacheSize, data->scanBuckets, data->maxApPerScan);
3296 hddLog(LOG1, "max_rssi_sample_size (%u) max_scan_reporting_threshold (%u)",
3297 data->maxRssiSampleSize, data->maxScanReportingThreshold);
3298 hddLog(LOG1, "max_hotlist_bssids (%u) max_bssid_history_entries (%u)"
3299 "max_hotlist_ssids (%u)", data->maxHotlistAPs,
3300 data->maxBsidHistoryEntries, data->maxHotlistSSIDs);
3301
3302 if (nla_put_u32(skb, PARAM_REQUEST_ID, data->requestId) ||
3303 nla_put_u32(skb, PARAM_STATUS, data->status) ||
3304 nla_put_u32(skb, MAX_SCAN_CACHE_SIZE, data->scanCacheSize) ||
3305 nla_put_u32(skb, MAX_SCAN_BUCKETS, data->scanBuckets) ||
3306 nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN,
3307 data->maxApPerScan) ||
3308 nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE,
3309 data->maxRssiSampleSize) ||
3310 nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD,
3311 data->maxScanReportingThreshold) ||
3312 nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->maxHotlistAPs) ||
3313 nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES,
3314 data->maxBsidHistoryEntries) ||
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303315 nla_put_u32(skb, MAX_HOTLIST_SSIDS, data->maxHotlistSSIDs) ||
3316 nla_put_u32(skb, MAX_SIGNIFICANT_WIFI_CHANGE_APS, 0))
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303317 {
3318 hddLog(LOGE, FL("nla put fail"));
3319 goto nla_put_failure;
3320 }
3321
3322 cfg80211_vendor_cmd_reply(skb);
3323 return 0;
3324
3325nla_put_failure:
3326 kfree_skb(skb);
3327 return -EINVAL;;
3328}
3329
3330/*
3331 * done with short names for the global vendor params
3332 * used by wlan_hdd_send_ext_scan_capability()
3333 */
3334#undef PARAM_REQUEST_ID
3335#undef PARAM_STATUS
3336#undef MAX_SCAN_CACHE_SIZE
3337#undef MAX_SCAN_BUCKETS
3338#undef MAX_AP_CACHE_PER_SCAN
3339#undef MAX_RSSI_SAMPLE_SIZE
3340#undef MAX_SCAN_RPT_THRHOLD
3341#undef MAX_HOTLIST_BSSIDS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303342#undef MAX_BSSID_HISTORY_ENTRIES
3343#undef MAX_HOTLIST_SSIDS
Dino Mycle6fb96c12014-06-10 11:52:40 +05303344
3345static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
3346{
3347 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
3348 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303349 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303350 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303351
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303352 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303353
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303354 if (wlan_hdd_validate_context(pHddCtx))
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303355 return;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303356
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303357 if (!pMsg)
3358 {
3359 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303360 return;
3361 }
3362
Dino Mycle6fb96c12014-06-10 11:52:40 +05303363 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3364 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
3365
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303366 context = &pHddCtx->ext_scan_context;
3367 spin_lock(&hdd_context_lock);
3368 if (context->request_id == pData->requestId) {
3369 context->response_status = pData->status ? -EINVAL : 0;
3370 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303371 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303372 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303373
3374 /*
3375 * Store the Request ID for comparing with the requestID obtained
3376 * in other requests.HDD shall return a failure is the extscan_stop
3377 * request is issued with a different requestId as that of the
3378 * extscan_start request. Also, This requestId shall be used while
3379 * indicating the full scan results to the upper layers.
3380 * The requestId is stored with the assumption that the firmware
3381 * shall return the ext scan start request's requestId in ext scan
3382 * start response.
3383 */
3384 if (pData->status == 0)
3385 pMac->sme.extScanStartReqId = pData->requestId;
3386
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303387 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303388 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303389}
3390
3391
3392static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
3393{
3394 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
3395 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303396 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303397
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303398 ENTER();
3399
3400 if (wlan_hdd_validate_context(pHddCtx)){
3401 return;
3402 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303403
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303404 if (!pMsg)
3405 {
3406 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303407 return;
3408 }
3409
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303410 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3411 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303412
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303413 context = &pHddCtx->ext_scan_context;
3414 spin_lock(&hdd_context_lock);
3415 if (context->request_id == pData->requestId) {
3416 context->response_status = pData->status ? -EINVAL : 0;
3417 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303418 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303419 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303420
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303421 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303422 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303423}
3424
Dino Mycle6fb96c12014-06-10 11:52:40 +05303425static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
3426 void *pMsg)
3427{
3428 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303429 tpSirEXTScanSetBssidHotListRspParams pData =
3430 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303431 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303432
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303433 ENTER();
3434
3435 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05303436 return;
3437 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303438
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303439 if (!pMsg)
3440 {
3441 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3442 return;
3443 }
3444
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303445 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3446 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303447
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303448 context = &pHddCtx->ext_scan_context;
3449 spin_lock(&hdd_context_lock);
3450 if (context->request_id == pData->requestId) {
3451 context->response_status = pData->status ? -EINVAL : 0;
3452 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303453 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303454 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303455
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303456 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303457 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303458}
3459
3460static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
3461 void *pMsg)
3462{
3463 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303464 tpSirEXTScanResetBssidHotlistRspParams pData =
3465 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303466 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303467
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303468 ENTER();
3469
3470 if (wlan_hdd_validate_context(pHddCtx)) {
3471 return;
3472 }
3473 if (!pMsg)
3474 {
3475 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303476 return;
3477 }
3478
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303479 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3480 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303481
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303482 context = &pHddCtx->ext_scan_context;
3483 spin_lock(&hdd_context_lock);
3484 if (context->request_id == pData->requestId) {
3485 context->response_status = pData->status ? -EINVAL : 0;
3486 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303487 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303488 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303489
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303490 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303491 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303492}
3493
Dino Mycle6fb96c12014-06-10 11:52:40 +05303494static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
3495 void *pMsg)
3496{
3497 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3498 struct sk_buff *skb = NULL;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303499 tANI_U32 i = 0, j, resultsPerEvent, scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303500 tANI_S32 totalResults;
3501 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303502 tpSirWifiScanResult pSirWifiScanResult, head_ptr;
3503 struct hdd_ext_scan_context *context;
3504 bool ignore_cached_results = false;
3505 tExtscanCachedScanResult *result;
3506 struct nlattr *nla_results;
3507 tANI_U16 ieLength= 0;
3508 tANI_U8 *ie = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303509
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303510 ENTER();
3511
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303512 if (wlan_hdd_validate_context(pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303513 return;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303514
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303515 if (!pMsg)
3516 {
3517 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3518 return;
3519 }
3520
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303521 spin_lock(&hdd_context_lock);
3522 context = &pHddCtx->ext_scan_context;
3523 ignore_cached_results = context->ignore_cached_results;
3524 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303525
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303526 if (ignore_cached_results) {
3527 hddLog(LOGE,
3528 FL("Ignore the cached results received after timeout"));
3529 return;
3530 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303531
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303532 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u More Data %u No of scan ids %u",
3533 pData->requestId, pData->moreData, pData->scanResultSize);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303534
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303535 result = (tExtscanCachedScanResult *)&(pData->result);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303536
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303537 for (scan_id_index = 0; scan_id_index < pData->scanResultSize;
3538 scan_id_index++) {
3539 result+= scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303540
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303541 totalResults = result->num_results;
3542 hddLog(VOS_TRACE_LEVEL_INFO, "scan_id %u flags %u Num results %u",
3543 result->scan_id, result->flags, totalResults);
3544 i = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303545
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303546 do{
3547 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
3548 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
3549 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303550
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303551 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
3552 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN);
3553
3554 if (!skb) {
3555 hddLog(VOS_TRACE_LEVEL_ERROR,
3556 FL("cfg80211_vendor_event_alloc failed"));
3557 return;
3558 }
3559
3560 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
3561
3562 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3563 pData->requestId) ||
3564 nla_put_u32(skb,
3565 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3566 resultsPerEvent)) {
3567 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3568 goto fail;
3569 }
3570 if (nla_put_u8(skb,
3571 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3572 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303573 {
3574 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3575 goto fail;
3576 }
3577
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303578 if (nla_put_u32(skb,
3579 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
3580 result->scan_id)) {
3581 hddLog(LOGE, FL("put fail"));
3582 goto fail;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303583 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303584
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303585 nla_results = nla_nest_start(skb,
3586 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_LIST);
3587 if (!nla_results)
3588 goto fail;
3589
3590 if (resultsPerEvent) {
3591 struct nlattr *aps;
3592 struct nlattr *nla_result;
3593
3594 nla_result = nla_nest_start(skb, scan_id_index);
3595 if(!nla_result)
3596 goto fail;
3597
3598 if (nla_put_u32(skb,
3599 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
3600 result->scan_id) ||
3601 nla_put_u32(skb,
3602 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_FLAGS,
3603 result->flags) ||
3604 nla_put_u32(skb,
3605 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3606 totalResults)) {
3607 hddLog(LOGE, FL("put fail"));
3608 goto fail;
3609 }
3610
3611 aps = nla_nest_start(skb,
3612 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3613 if (!aps)
3614 {
3615 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3616 goto fail;
3617 }
3618
3619 head_ptr = (tpSirWifiScanResult) &(result->ap);
3620
3621 for (j = 0; j < resultsPerEvent; j++, i++) {
3622 struct nlattr *ap;
3623 pSirWifiScanResult = head_ptr + i;
3624
3625 /*
Srinivas Dasari91727c12016-03-23 17:59:06 +05303626 * Firmware returns timestamp from extscan_start till
3627 * BSSID was cached (in micro seconds). Add this with
3628 * time gap between system boot up to extscan_start
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303629 * to derive the time since boot when the
3630 * BSSID was cached.
3631 */
Srinivas Dasari91727c12016-03-23 17:59:06 +05303632 pSirWifiScanResult->ts +=
3633 pHddCtx->extscan_start_time_since_boot;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303634 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
3635 "Ssid (%s)"
3636 "Bssid: %pM "
3637 "Channel (%u)"
3638 "Rssi (%d)"
3639 "RTT (%u)"
3640 "RTT_SD (%u)"
3641 "Beacon Period %u"
3642 "Capability 0x%x "
3643 "Ie length %d",
3644 i,
3645 pSirWifiScanResult->ts,
3646 pSirWifiScanResult->ssid,
3647 pSirWifiScanResult->bssid,
3648 pSirWifiScanResult->channel,
3649 pSirWifiScanResult->rssi,
3650 pSirWifiScanResult->rtt,
3651 pSirWifiScanResult->rtt_sd,
3652 pSirWifiScanResult->beaconPeriod,
3653 pSirWifiScanResult->capability,
3654 ieLength);
3655
3656 ap = nla_nest_start(skb, j + 1);
3657 if (!ap)
3658 {
3659 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3660 goto fail;
3661 }
3662
3663 if (nla_put_u64(skb,
3664 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3665 pSirWifiScanResult->ts) )
3666 {
3667 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3668 goto fail;
3669 }
3670 if (nla_put(skb,
3671 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3672 sizeof(pSirWifiScanResult->ssid),
3673 pSirWifiScanResult->ssid) )
3674 {
3675 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3676 goto fail;
3677 }
3678 if (nla_put(skb,
3679 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3680 sizeof(pSirWifiScanResult->bssid),
3681 pSirWifiScanResult->bssid) )
3682 {
3683 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3684 goto fail;
3685 }
3686 if (nla_put_u32(skb,
3687 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3688 pSirWifiScanResult->channel) )
3689 {
3690 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3691 goto fail;
3692 }
3693 if (nla_put_s32(skb,
3694 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
3695 pSirWifiScanResult->rssi) )
3696 {
3697 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3698 goto fail;
3699 }
3700 if (nla_put_u32(skb,
3701 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3702 pSirWifiScanResult->rtt) )
3703 {
3704 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3705 goto fail;
3706 }
3707 if (nla_put_u32(skb,
3708 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3709 pSirWifiScanResult->rtt_sd))
3710 {
3711 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3712 goto fail;
3713 }
3714 if (nla_put_u32(skb,
3715 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3716 pSirWifiScanResult->beaconPeriod))
3717 {
3718 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3719 goto fail;
3720 }
3721 if (nla_put_u32(skb,
3722 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3723 pSirWifiScanResult->capability))
3724 {
3725 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3726 goto fail;
3727 }
3728 if (nla_put_u32(skb,
3729 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
3730 ieLength))
3731 {
3732 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3733 goto fail;
3734 }
3735
3736 if (ieLength)
3737 if (nla_put(skb,
3738 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3739 ieLength, ie)) {
3740 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3741 goto fail;
3742 }
3743
3744 nla_nest_end(skb, ap);
3745 }
3746 nla_nest_end(skb, aps);
3747 nla_nest_end(skb, nla_result);
3748 }
3749
3750 nla_nest_end(skb, nla_results);
3751
3752 cfg80211_vendor_cmd_reply(skb);
3753
3754 } while (totalResults > 0);
3755 }
3756
3757 if (!pData->moreData) {
3758 spin_lock(&hdd_context_lock);
3759 context->response_status = 0;
3760 complete(&context->response_event);
3761 spin_unlock(&hdd_context_lock);
3762 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303763
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303764 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303765 return;
3766fail:
3767 kfree_skb(skb);
3768 return;
3769}
3770
3771static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
3772 void *pMsg)
3773{
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303774 tpSirEXTScanHotlistMatch pData = (tpSirEXTScanHotlistMatch) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303775 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3776 struct sk_buff *skb = NULL;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303777 tANI_U32 i, index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303778
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303779 ENTER();
3780
3781 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303782 hddLog(LOGE,
3783 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303784 return;
3785 }
3786 if (!pMsg)
3787 {
3788 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303789 return;
3790 }
3791
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303792 if (pData->bss_found)
3793 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX;
3794 else
3795 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX;
3796
Dino Mycle6fb96c12014-06-10 11:52:40 +05303797 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303798#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3799 NULL,
3800#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303801 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303802 index, GFP_KERNEL);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303803
3804 if (!skb) {
3805 hddLog(VOS_TRACE_LEVEL_ERROR,
3806 FL("cfg80211_vendor_event_alloc failed"));
3807 return;
3808 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303809
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303810 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3811 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numHotlistBss);
3812 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
3813 hddLog(VOS_TRACE_LEVEL_INFO, "ap_found %u", pData->bss_found);
3814
3815 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303816 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
3817 "Ssid (%s) "
3818 "Bssid (" MAC_ADDRESS_STR ") "
3819 "Channel (%u) "
3820 "Rssi (%d) "
3821 "RTT (%u) "
3822 "RTT_SD (%u) ",
3823 i,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303824 pData->bssHotlist[i].ts,
3825 pData->bssHotlist[i].ssid,
3826 MAC_ADDR_ARRAY(pData->bssHotlist[i].bssid),
3827 pData->bssHotlist[i].channel,
3828 pData->bssHotlist[i].rssi,
3829 pData->bssHotlist[i].rtt,
3830 pData->bssHotlist[i].rtt_sd);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303831 }
3832
3833 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3834 pData->requestId) ||
3835 nla_put_u32(skb,
3836 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303837 pData->numHotlistBss)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303838 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3839 goto fail;
3840 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303841 if (pData->numHotlistBss) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303842 struct nlattr *aps;
3843
3844 aps = nla_nest_start(skb,
3845 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3846 if (!aps)
3847 goto fail;
3848
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303849 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303850 struct nlattr *ap;
3851
3852 ap = nla_nest_start(skb, i + 1);
3853 if (!ap)
3854 goto fail;
3855
3856 if (nla_put_u64(skb,
3857 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303858 pData->bssHotlist[i].ts) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303859 nla_put(skb,
3860 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303861 sizeof(pData->bssHotlist[i].ssid),
3862 pData->bssHotlist[i].ssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303863 nla_put(skb,
3864 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303865 sizeof(pData->bssHotlist[i].bssid),
3866 pData->bssHotlist[i].bssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303867 nla_put_u32(skb,
3868 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303869 pData->bssHotlist[i].channel) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303870 nla_put_s32(skb,
3871 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303872 pData->bssHotlist[i].rssi) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303873 nla_put_u32(skb,
3874 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303875 pData->bssHotlist[i].rtt) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303876 nla_put_u32(skb,
3877 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303878 pData->bssHotlist[i].rtt_sd))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303879 goto fail;
3880
3881 nla_nest_end(skb, ap);
3882 }
3883 nla_nest_end(skb, aps);
3884
3885 if (nla_put_u8(skb,
3886 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3887 pData->moreData))
3888 goto fail;
3889 }
3890
3891 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303892 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303893 return;
3894
3895fail:
3896 kfree_skb(skb);
3897 return;
3898
3899}
Dino Mycle6fb96c12014-06-10 11:52:40 +05303900
3901static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
3902 void *pMsg)
3903{
3904 struct sk_buff *skb;
3905 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3906 tpSirWifiFullScanResultEvent pData =
3907 (tpSirWifiFullScanResultEvent) (pMsg);
3908
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303909 ENTER();
3910
3911 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303912 hddLog(LOGE,
3913 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303914 return;
3915 }
3916 if (!pMsg)
3917 {
3918 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303919 return;
3920 }
3921
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303922 /*
3923 * If the full scan result including IE data exceeds NL 4K size
3924 * limitation, drop that beacon/probe rsp frame.
3925 */
3926 if ((sizeof(*pData) + pData->ieLength) >= EXTSCAN_EVENT_BUF_SIZE) {
3927 hddLog(LOGE, FL("Frame exceeded NL size limilation, drop it!"));
3928 return;
3929 }
3930
Dino Mycle6fb96c12014-06-10 11:52:40 +05303931 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303932#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3933 NULL,
3934#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303935 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3936 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
3937 GFP_KERNEL);
3938
3939 if (!skb) {
3940 hddLog(VOS_TRACE_LEVEL_ERROR,
3941 FL("cfg80211_vendor_event_alloc failed"));
3942 return;
3943 }
3944
Dino Mycle6fb96c12014-06-10 11:52:40 +05303945 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
3946 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
3947 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
3948 "Ssid (%s)"
3949 "Bssid (" MAC_ADDRESS_STR ")"
3950 "Channel (%u)"
3951 "Rssi (%d)"
3952 "RTT (%u)"
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303953 "RTT_SD (%u)"
3954 "Bcn Period %d"
3955 "Capability 0x%X "),
Dino Mycle6fb96c12014-06-10 11:52:40 +05303956 pData->ap.ts,
3957 pData->ap.ssid,
3958 MAC_ADDR_ARRAY(pData->ap.bssid),
3959 pData->ap.channel,
3960 pData->ap.rssi,
3961 pData->ap.rtt,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303962 pData->ap.rtt_sd,
3963 pData->ap.beaconPeriod,
3964 pData->ap.capability);
3965
Dino Mycle6fb96c12014-06-10 11:52:40 +05303966 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
3967 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3968 pData->requestId) ||
3969 nla_put_u64(skb,
3970 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3971 pData->ap.ts) ||
3972 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3973 sizeof(pData->ap.ssid),
3974 pData->ap.ssid) ||
3975 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3976 WNI_CFG_BSSID_LEN,
3977 pData->ap.bssid) ||
3978 nla_put_u32(skb,
3979 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3980 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05303981 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303982 pData->ap.rssi) ||
3983 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3984 pData->ap.rtt) ||
3985 nla_put_u32(skb,
3986 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3987 pData->ap.rtt_sd) ||
3988 nla_put_u16(skb,
3989 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3990 pData->ap.beaconPeriod) ||
3991 nla_put_u16(skb,
3992 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3993 pData->ap.capability) ||
3994 nla_put_u32(skb,
3995 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303996 pData->ieLength) ||
3997 nla_put_u8(skb,
3998 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3999 pData->moreData))
Dino Mycle6fb96c12014-06-10 11:52:40 +05304000 {
4001 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4002 goto nla_put_failure;
4003 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304004
4005 if (pData->ieLength) {
4006 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
4007 pData->ieLength,
4008 pData->ie))
4009 {
4010 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4011 goto nla_put_failure;
4012 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304013 }
4014
4015 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304016 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304017 return;
4018
4019nla_put_failure:
4020 kfree_skb(skb);
4021 return;
4022}
4023
4024static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
4025 void *pMsg)
4026{
4027 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4028 struct sk_buff *skb = NULL;
4029 tpSirEXTScanResultsAvailableIndParams pData =
4030 (tpSirEXTScanResultsAvailableIndParams) pMsg;
4031
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304032 ENTER();
4033
4034 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304035 hddLog(LOGE,
4036 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304037 return;
4038 }
4039 if (!pMsg)
4040 {
4041 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304042 return;
4043 }
4044
4045 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304046#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4047 NULL,
4048#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05304049 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4050 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
4051 GFP_KERNEL);
4052
4053 if (!skb) {
4054 hddLog(VOS_TRACE_LEVEL_ERROR,
4055 FL("cfg80211_vendor_event_alloc failed"));
4056 return;
4057 }
4058
Dino Mycle6fb96c12014-06-10 11:52:40 +05304059 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
4060 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
4061 pData->numResultsAvailable);
4062 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
4063 pData->requestId) ||
4064 nla_put_u32(skb,
4065 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
4066 pData->numResultsAvailable)) {
4067 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4068 goto nla_put_failure;
4069 }
4070
4071 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304072 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304073 return;
4074
4075nla_put_failure:
4076 kfree_skb(skb);
4077 return;
4078}
4079
4080static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
4081{
4082 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4083 struct sk_buff *skb = NULL;
4084 tpSirEXTScanProgressIndParams pData =
4085 (tpSirEXTScanProgressIndParams) pMsg;
4086
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304087 ENTER();
4088
4089 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304090 hddLog(LOGE,
4091 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304092 return;
4093 }
4094 if (!pMsg)
4095 {
4096 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304097 return;
4098 }
4099
4100 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304101#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4102 NULL,
4103#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05304104 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4105 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
4106 GFP_KERNEL);
4107
4108 if (!skb) {
4109 hddLog(VOS_TRACE_LEVEL_ERROR,
4110 FL("cfg80211_vendor_event_alloc failed"));
4111 return;
4112 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304113 hddLog(VOS_TRACE_LEVEL_INFO, FL("Request Id (%u) "), pData->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304114 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
4115 pData->extScanEventType);
4116 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
4117 pData->status);
4118
4119 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
4120 pData->extScanEventType) ||
4121 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05304122 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
4123 pData->requestId) ||
4124 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304125 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
4126 pData->status)) {
4127 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4128 goto nla_put_failure;
4129 }
4130
4131 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304132 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304133 return;
4134
4135nla_put_failure:
4136 kfree_skb(skb);
4137 return;
4138}
4139
4140void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
4141 void *pMsg)
4142{
4143 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4144
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304145 ENTER();
4146
Dino Mycle6fb96c12014-06-10 11:52:40 +05304147 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304148 return;
4149 }
4150
4151 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
4152
4153
4154 switch(evType) {
4155 case SIR_HAL_EXTSCAN_START_RSP:
4156 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
4157 break;
4158
4159 case SIR_HAL_EXTSCAN_STOP_RSP:
4160 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
4161 break;
4162 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
4163 /* There is no need to send this response to upper layer
4164 Just log the message */
4165 hddLog(VOS_TRACE_LEVEL_INFO,
4166 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
4167 break;
4168 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
4169 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
4170 break;
4171
4172 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
4173 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
4174 break;
4175
Dino Mycle6fb96c12014-06-10 11:52:40 +05304176 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304177 wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx, pMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304178 break;
4179 case SIR_HAL_EXTSCAN_PROGRESS_IND:
4180 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
4181 break;
4182 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
4183 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
4184 break;
4185 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
4186 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
4187 break;
4188 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
4189 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
4190 break;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304191 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
4192 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
4193 break;
4194 default:
4195 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
4196 break;
4197 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304198 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304199}
4200
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304201static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
4202 struct wireless_dev *wdev,
4203 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304204{
Dino Myclee8843b32014-07-04 14:21:45 +05304205 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304206 struct net_device *dev = wdev->netdev;
4207 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4208 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4209 struct nlattr
4210 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4211 eHalStatus status;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304212 struct hdd_ext_scan_context *context;
4213 unsigned long rc;
4214 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304215
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304216 ENTER();
4217
Dino Mycle6fb96c12014-06-10 11:52:40 +05304218 status = wlan_hdd_validate_context(pHddCtx);
4219 if (0 != status)
4220 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304221 return -EINVAL;
4222 }
Dino Myclee8843b32014-07-04 14:21:45 +05304223 /* check the EXTScan Capability */
4224 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304225 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4226 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304227 {
4228 hddLog(VOS_TRACE_LEVEL_ERROR,
4229 FL("EXTScan not enabled/supported by Firmware"));
4230 return -EINVAL;
4231 }
4232
Dino Mycle6fb96c12014-06-10 11:52:40 +05304233 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4234 data, dataLen,
4235 wlan_hdd_extscan_config_policy)) {
4236 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4237 return -EINVAL;
4238 }
4239
4240 /* Parse and fetch request Id */
4241 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4242 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4243 return -EINVAL;
4244 }
4245
Dino Myclee8843b32014-07-04 14:21:45 +05304246 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304247 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304248 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304249
Dino Myclee8843b32014-07-04 14:21:45 +05304250 reqMsg.sessionId = pAdapter->sessionId;
4251 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304252
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304253 vos_spin_lock_acquire(&hdd_context_lock);
4254 context = &pHddCtx->ext_scan_context;
4255 context->request_id = reqMsg.requestId;
4256 INIT_COMPLETION(context->response_event);
4257 vos_spin_lock_release(&hdd_context_lock);
4258
Dino Myclee8843b32014-07-04 14:21:45 +05304259 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304260 if (!HAL_STATUS_SUCCESS(status)) {
4261 hddLog(VOS_TRACE_LEVEL_ERROR,
4262 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304263 return -EINVAL;
4264 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304265
4266 rc = wait_for_completion_timeout(&context->response_event,
4267 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4268 if (!rc) {
4269 hddLog(LOGE, FL("Target response timed out"));
4270 return -ETIMEDOUT;
4271 }
4272
4273 ret = wlan_hdd_send_ext_scan_capability(pHddCtx);
4274 if (ret)
4275 hddLog(LOGE, FL("Failed to send ext scan capability to user space"));
4276
4277 return ret;
4278
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304279 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304280 return 0;
4281}
4282
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304283static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
4284 struct wireless_dev *wdev,
4285 const void *data, int dataLen)
4286{
4287 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304288
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304289 vos_ssr_protect(__func__);
4290 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
4291 vos_ssr_unprotect(__func__);
4292
4293 return ret;
4294}
4295
4296static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
4297 struct wireless_dev *wdev,
4298 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304299{
Dino Myclee8843b32014-07-04 14:21:45 +05304300 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304301 struct net_device *dev = wdev->netdev;
4302 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4303 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4304 struct nlattr
4305 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4306 eHalStatus status;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304307 struct hdd_ext_scan_context *context;
4308 unsigned long rc;
4309 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304310
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304311 ENTER();
4312
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304313 if (VOS_FTM_MODE == hdd_get_conparam()) {
4314 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4315 return -EINVAL;
4316 }
4317
Dino Mycle6fb96c12014-06-10 11:52:40 +05304318 status = wlan_hdd_validate_context(pHddCtx);
4319 if (0 != status)
4320 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304321 return -EINVAL;
4322 }
Dino Myclee8843b32014-07-04 14:21:45 +05304323 /* check the EXTScan Capability */
4324 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304325 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4326 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304327 {
4328 hddLog(VOS_TRACE_LEVEL_ERROR,
4329 FL("EXTScan not enabled/supported by Firmware"));
4330 return -EINVAL;
4331 }
4332
Dino Mycle6fb96c12014-06-10 11:52:40 +05304333 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4334 data, dataLen,
4335 wlan_hdd_extscan_config_policy)) {
4336 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4337 return -EINVAL;
4338 }
4339 /* Parse and fetch request Id */
4340 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4341 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4342 return -EINVAL;
4343 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304344
Dino Myclee8843b32014-07-04 14:21:45 +05304345 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304346 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4347
Dino Myclee8843b32014-07-04 14:21:45 +05304348 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304349
Dino Myclee8843b32014-07-04 14:21:45 +05304350 reqMsg.sessionId = pAdapter->sessionId;
4351 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304352
4353 /* Parse and fetch flush parameter */
4354 if (!tb
4355 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
4356 {
4357 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
4358 goto failed;
4359 }
Dino Myclee8843b32014-07-04 14:21:45 +05304360 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304361 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
4362
Dino Myclee8843b32014-07-04 14:21:45 +05304363 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304364
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304365 spin_lock(&hdd_context_lock);
4366 context = &pHddCtx->ext_scan_context;
4367 context->request_id = reqMsg.requestId;
4368 context->ignore_cached_results = false;
4369 INIT_COMPLETION(context->response_event);
4370 spin_unlock(&hdd_context_lock);
4371
Dino Myclee8843b32014-07-04 14:21:45 +05304372 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304373 if (!HAL_STATUS_SUCCESS(status)) {
4374 hddLog(VOS_TRACE_LEVEL_ERROR,
4375 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304376 return -EINVAL;
4377 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304378
4379 rc = wait_for_completion_timeout(&context->response_event,
4380 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4381 if (!rc) {
4382 hddLog(LOGE, FL("Target response timed out"));
4383 retval = -ETIMEDOUT;
4384 spin_lock(&hdd_context_lock);
4385 context->ignore_cached_results = true;
4386 spin_unlock(&hdd_context_lock);
4387 } else {
4388 spin_lock(&hdd_context_lock);
4389 retval = context->response_status;
4390 spin_unlock(&hdd_context_lock);
4391 }
4392
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304393 EXIT();
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304394 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304395
4396failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05304397 return -EINVAL;
4398}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304399static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
4400 struct wireless_dev *wdev,
4401 const void *data, int dataLen)
4402{
4403 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304404
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304405 vos_ssr_protect(__func__);
4406 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
4407 vos_ssr_unprotect(__func__);
4408
4409 return ret;
4410}
4411
4412static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304413 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05304414 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304415{
4416 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
4417 struct net_device *dev = wdev->netdev;
4418 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4419 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4420 struct nlattr
4421 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4422 struct nlattr
4423 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4424 struct nlattr *apTh;
4425 eHalStatus status;
4426 tANI_U8 i = 0;
4427 int rem;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304428 struct hdd_ext_scan_context *context;
4429 tANI_U32 request_id;
4430 unsigned long rc;
4431 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304432
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304433 ENTER();
4434
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304435 if (VOS_FTM_MODE == hdd_get_conparam()) {
4436 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4437 return -EINVAL;
4438 }
4439
Dino Mycle6fb96c12014-06-10 11:52:40 +05304440 status = wlan_hdd_validate_context(pHddCtx);
4441 if (0 != status)
4442 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304443 return -EINVAL;
4444 }
Dino Myclee8843b32014-07-04 14:21:45 +05304445 /* check the EXTScan Capability */
4446 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304447 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4448 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304449 {
4450 hddLog(VOS_TRACE_LEVEL_ERROR,
4451 FL("EXTScan not enabled/supported by Firmware"));
4452 return -EINVAL;
4453 }
4454
Dino Mycle6fb96c12014-06-10 11:52:40 +05304455 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4456 data, dataLen,
4457 wlan_hdd_extscan_config_policy)) {
4458 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4459 return -EINVAL;
4460 }
4461
4462 /* Parse and fetch request Id */
4463 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4464 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4465 return -EINVAL;
4466 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304467 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
4468 vos_mem_malloc(sizeof(*pReqMsg));
4469 if (!pReqMsg) {
4470 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4471 return -ENOMEM;
4472 }
4473
Dino Myclee8843b32014-07-04 14:21:45 +05304474
Dino Mycle6fb96c12014-06-10 11:52:40 +05304475 pReqMsg->requestId = nla_get_u32(
4476 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4477 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4478
4479 /* Parse and fetch number of APs */
4480 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
4481 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
4482 goto fail;
4483 }
4484
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304485 /* Parse and fetch lost ap sample size */
4486 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]) {
4487 hddLog(LOGE, FL("attr lost ap sample size failed"));
4488 goto fail;
4489 }
4490
4491 pReqMsg->lostBssidSampleSize = nla_get_u32(
4492 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]);
4493 hddLog(LOG1, FL("Lost ap sample size %d"), pReqMsg->lostBssidSampleSize);
4494
Dino Mycle6fb96c12014-06-10 11:52:40 +05304495 pReqMsg->sessionId = pAdapter->sessionId;
4496 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4497
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304498 pReqMsg->numBssid = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304499 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304500 if (pReqMsg->numBssid > WLAN_EXTSCAN_MAX_HOTLIST_APS) {
4501 hddLog(LOGE, FL("Number of AP: %u exceeds max: %u"),
4502 pReqMsg->numBssid, WLAN_EXTSCAN_MAX_HOTLIST_APS);
4503 goto fail;
4504 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304505 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numBssid);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304506
4507 nla_for_each_nested(apTh,
4508 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304509 if (i == pReqMsg->numBssid) {
4510 hddLog(LOGW, FL("Ignoring excess AP"));
4511 break;
4512 }
4513
Dino Mycle6fb96c12014-06-10 11:52:40 +05304514 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4515 nla_data(apTh), nla_len(apTh),
4516 NULL)) {
4517 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
4518 goto fail;
4519 }
4520
4521 /* Parse and fetch MAC address */
4522 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
4523 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
4524 goto fail;
4525 }
4526 memcpy(pReqMsg->ap[i].bssid, nla_data(
4527 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
4528 sizeof(tSirMacAddr));
4529 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
4530
4531 /* Parse and fetch low RSSI */
4532 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
4533 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
4534 goto fail;
4535 }
4536 pReqMsg->ap[i].low = nla_get_s32(
4537 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
4538 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
4539
4540 /* Parse and fetch high RSSI */
4541 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
4542 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
4543 goto fail;
4544 }
4545 pReqMsg->ap[i].high = nla_get_s32(
4546 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
4547 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
4548 pReqMsg->ap[i].high);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304549 i++;
4550 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304551
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304552 if (i < pReqMsg->numBssid) {
4553 hddLog(LOGW, FL("Number of AP %u less than expected %u"),
4554 i, pReqMsg->numBssid);
4555 pReqMsg->numBssid = i;
4556 }
4557
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304558 context = &pHddCtx->ext_scan_context;
4559 spin_lock(&hdd_context_lock);
4560 INIT_COMPLETION(context->response_event);
4561 context->request_id = request_id = pReqMsg->requestId;
4562 spin_unlock(&hdd_context_lock);
4563
Dino Mycle6fb96c12014-06-10 11:52:40 +05304564 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
4565 if (!HAL_STATUS_SUCCESS(status)) {
4566 hddLog(VOS_TRACE_LEVEL_ERROR,
4567 FL("sme_SetBssHotlist failed(err=%d)"), status);
4568 vos_mem_free(pReqMsg);
4569 return -EINVAL;
4570 }
4571
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304572 /* request was sent -- wait for the response */
4573 rc = wait_for_completion_timeout(&context->response_event,
4574 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4575
4576 if (!rc) {
4577 hddLog(LOGE, FL("sme_SetBssHotlist timed out"));
4578 retval = -ETIMEDOUT;
4579 } else {
4580 spin_lock(&hdd_context_lock);
4581 if (context->request_id == request_id)
4582 retval = context->response_status;
4583 else
4584 retval = -EINVAL;
4585 spin_unlock(&hdd_context_lock);
4586 }
4587
Dino Myclee8843b32014-07-04 14:21:45 +05304588 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304589 EXIT();
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304590 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304591
4592fail:
4593 vos_mem_free(pReqMsg);
4594 return -EINVAL;
4595}
4596
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304597static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
4598 struct wireless_dev *wdev,
4599 const void *data, int dataLen)
4600{
4601 int ret = 0;
4602
4603 vos_ssr_protect(__func__);
4604 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
4605 dataLen);
4606 vos_ssr_unprotect(__func__);
4607
4608 return ret;
4609}
4610
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304611static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304612 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304613 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304614{
Agrawal Ashish16abf782016-08-18 22:42:59 +05304615 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4616 struct net_device *dev = wdev->netdev;
4617 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4618 uint32_t chan_list[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4619 uint8_t num_channels = 0;
4620 uint8_t num_chan_new = 0;
4621 uint8_t buf[256] = {0};
Dino Mycle6fb96c12014-06-10 11:52:40 +05304622 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304623 tANI_U32 requestId, maxChannels;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304624 tWifiBand wifiBand;
4625 eHalStatus status;
4626 struct sk_buff *replySkb;
Agrawal Ashish16abf782016-08-18 22:42:59 +05304627 tANI_U8 i,j,k;
4628 int ret,len = 0;;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304629
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304630 ENTER();
4631
Dino Mycle6fb96c12014-06-10 11:52:40 +05304632 status = wlan_hdd_validate_context(pHddCtx);
4633 if (0 != status)
4634 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304635 return -EINVAL;
4636 }
Dino Myclee8843b32014-07-04 14:21:45 +05304637
Dino Mycle6fb96c12014-06-10 11:52:40 +05304638 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4639 data, dataLen,
4640 wlan_hdd_extscan_config_policy)) {
4641 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4642 return -EINVAL;
4643 }
4644
4645 /* Parse and fetch request Id */
4646 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4647 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4648 return -EINVAL;
4649 }
4650 requestId = nla_get_u32(
4651 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4652 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
4653
4654 /* Parse and fetch wifi band */
4655 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
4656 {
4657 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4658 return -EINVAL;
4659 }
4660 wifiBand = nla_get_u32(
4661 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
4662 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
4663
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304664 /* Parse and fetch max channels */
4665 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
4666 {
4667 hddLog(LOGE, FL("attr max channels failed"));
4668 return -EINVAL;
4669 }
4670 maxChannels = nla_get_u32(
4671 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
4672 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);
4673
Dino Mycle6fb96c12014-06-10 11:52:40 +05304674 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
Agrawal Ashish16abf782016-08-18 22:42:59 +05304675 wifiBand, chan_list,
4676 &num_channels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304677 if (eHAL_STATUS_SUCCESS != status) {
4678 hddLog(VOS_TRACE_LEVEL_ERROR,
4679 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
4680 return -EINVAL;
4681 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304682
Agrawal Ashish16abf782016-08-18 22:42:59 +05304683 num_channels = VOS_MIN(num_channels, maxChannels);
4684 num_chan_new = num_channels;
4685 /* remove the indoor only channels if iface is SAP */
4686 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
4687 {
4688 num_chan_new = 0;
4689 for (i = 0; i < num_channels; i++)
4690 for (j = 0; j < IEEE80211_NUM_BANDS; j++) {
4691 if (wiphy->bands[j] == NULL)
4692 continue;
4693 for (k = 0; k < wiphy->bands[j]->n_channels; k++) {
4694 if ((chan_list[i] ==
4695 wiphy->bands[j]->channels[k].center_freq) &&
4696 (!(wiphy->bands[j]->channels[k].flags &
4697 IEEE80211_CHAN_INDOOR_ONLY))) {
4698 chan_list[num_chan_new] = chan_list[i];
4699 num_chan_new++;
4700 }
4701 }
4702 }
4703 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304704
Agrawal Ashish16abf782016-08-18 22:42:59 +05304705 hddLog(LOG1, FL("Number of channels: %d"), num_chan_new);
4706 for (i = 0; i < num_chan_new; i++)
4707 len += scnprintf(buf + len, sizeof(buf) - len, "%u ", chan_list[i]);
4708 hddLog(LOG1, "Channels: %s", buf);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304709
4710 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
Agrawal Ashish16abf782016-08-18 22:42:59 +05304711 sizeof(u32) * num_chan_new +
Dino Mycle6fb96c12014-06-10 11:52:40 +05304712 NLMSG_HDRLEN);
4713
4714 if (!replySkb) {
4715 hddLog(VOS_TRACE_LEVEL_ERROR,
4716 FL("valid channels: buffer alloc fail"));
4717 return -EINVAL;
4718 }
4719 if (nla_put_u32(replySkb,
4720 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304721 num_chan_new) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05304722 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304723 sizeof(u32) * num_chan_new, chan_list)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304724
4725 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4726 kfree_skb(replySkb);
4727 return -EINVAL;
4728 }
4729
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304730 ret = cfg80211_vendor_cmd_reply(replySkb);
4731
4732 EXIT();
4733 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304734}
4735
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304736static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
4737 struct wireless_dev *wdev,
4738 const void *data, int dataLen)
4739{
4740 int ret = 0;
4741
4742 vos_ssr_protect(__func__);
4743 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
4744 dataLen);
4745 vos_ssr_unprotect(__func__);
4746
4747 return ret;
4748}
4749
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304750static int hdd_extscan_start_fill_bucket_channel_spec(
4751 hdd_context_t *pHddCtx,
4752 tpSirEXTScanStartReqParams pReqMsg,
4753 struct nlattr **tb)
4754{
4755 struct nlattr *bucket[
4756 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4757 struct nlattr *channel[
4758 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4759 struct nlattr *buckets;
4760 struct nlattr *channels;
4761 int rem1, rem2;
4762 eHalStatus status;
4763 tANI_U8 bktIndex, j, numChannels;
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304764 uint32_t expected_buckets;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304765 tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4766 tANI_U32 passive_max_chn_time, active_max_chn_time;
4767
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304768 expected_buckets = pReqMsg->numBuckets;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304769 bktIndex = 0;
4770
4771 nla_for_each_nested(buckets,
4772 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304773 if (bktIndex >= expected_buckets) {
4774 hddLog(LOGW, FL("ignoring excess buckets"));
4775 break;
4776 }
4777
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304778 if (nla_parse(bucket,
Ashish Kumar Dhanotiya9c93f562017-06-20 12:13:33 +05304779 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4780 nla_data(buckets), nla_len(buckets),
4781 wlan_hdd_extscan_config_policy)) {
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304782 hddLog(LOGE, FL("nla_parse failed"));
4783 return -EINVAL;
4784 }
4785
4786 /* Parse and fetch bucket spec */
4787 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4788 hddLog(LOGE, FL("attr bucket index failed"));
4789 return -EINVAL;
4790 }
4791 pReqMsg->buckets[bktIndex].bucket = nla_get_u8(
4792 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4793 hddLog(LOG1, FL("Bucket spec Index %d"),
4794 pReqMsg->buckets[bktIndex].bucket);
4795
4796 /* Parse and fetch wifi band */
4797 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4798 hddLog(LOGE, FL("attr wifi band failed"));
4799 return -EINVAL;
4800 }
4801 pReqMsg->buckets[bktIndex].band = nla_get_u8(
4802 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4803 hddLog(LOG1, FL("Wifi band %d"),
4804 pReqMsg->buckets[bktIndex].band);
4805
4806 /* Parse and fetch period */
4807 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4808 hddLog(LOGE, FL("attr period failed"));
4809 return -EINVAL;
4810 }
4811 pReqMsg->buckets[bktIndex].period = nla_get_u32(
4812 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4813 hddLog(LOG1, FL("period %d"),
4814 pReqMsg->buckets[bktIndex].period);
4815
4816 /* Parse and fetch report events */
4817 if (!bucket[
4818 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4819 hddLog(LOGE, FL("attr report events failed"));
4820 return -EINVAL;
4821 }
4822 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
4823 bucket[
4824 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4825 hddLog(LOG1, FL("report events %d"),
4826 pReqMsg->buckets[bktIndex].reportEvents);
4827
4828 /* Parse and fetch max period */
4829 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
4830 hddLog(LOGE, FL("attr max period failed"));
4831 return -EINVAL;
4832 }
4833 pReqMsg->buckets[bktIndex].max_period = nla_get_u32(
4834 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);
4835 hddLog(LOG1, FL("max period %u"),
4836 pReqMsg->buckets[bktIndex].max_period);
4837
4838 /* Parse and fetch exponent */
4839 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
4840 hddLog(LOGE, FL("attr exponent failed"));
4841 return -EINVAL;
4842 }
4843 pReqMsg->buckets[bktIndex].exponent = nla_get_u32(
4844 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
4845 hddLog(LOG1, FL("exponent %u"),
4846 pReqMsg->buckets[bktIndex].exponent);
4847
4848 /* Parse and fetch step count */
4849 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
4850 hddLog(LOGE, FL("attr step count failed"));
4851 return -EINVAL;
4852 }
4853 pReqMsg->buckets[bktIndex].step_count = nla_get_u32(
4854 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
4855 hddLog(LOG1, FL("Step count %u"),
4856 pReqMsg->buckets[bktIndex].step_count);
4857
4858 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time);
4859 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time);
4860
4861 /* Framework shall pass the channel list if the input WiFi band is
4862 * WIFI_BAND_UNSPECIFIED.
4863 * If the input WiFi band is specified (any value other than
4864 * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
4865 */
4866 if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) {
4867 numChannels = 0;
4868 hddLog(LOG1, "WiFi band is specified, driver to fill channel list");
4869 status = sme_GetValidChannelsByBand(pHddCtx->hHal,
4870 pReqMsg->buckets[bktIndex].band,
4871 chanList, &numChannels);
4872 if (!HAL_STATUS_SUCCESS(status)) {
4873 hddLog(LOGE,
4874 FL("sme_GetValidChannelsByBand failed (err=%d)"),
4875 status);
4876 return -EINVAL;
4877 }
4878
4879 pReqMsg->buckets[bktIndex].numChannels =
4880 VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS);
4881 hddLog(LOG1, FL("Num channels %d"),
4882 pReqMsg->buckets[bktIndex].numChannels);
4883
4884 for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels;
4885 j++) {
4886 pReqMsg->buckets[bktIndex].channels[j].channel =
4887 chanList[j];
4888 pReqMsg->buckets[bktIndex].channels[j].
4889 chnlClass = 0;
4890 if (CSR_IS_CHANNEL_DFS(
4891 vos_freq_to_chan(chanList[j]))) {
4892 pReqMsg->buckets[bktIndex].channels[j].
4893 passive = 1;
4894 pReqMsg->buckets[bktIndex].channels[j].
4895 dwellTimeMs = passive_max_chn_time;
4896 } else {
4897 pReqMsg->buckets[bktIndex].channels[j].
4898 passive = 0;
4899 pReqMsg->buckets[bktIndex].channels[j].
4900 dwellTimeMs = active_max_chn_time;
4901 }
4902
4903 hddLog(LOG1,
4904 "Channel %u Passive %u Dwell time %u ms",
4905 pReqMsg->buckets[bktIndex].channels[j].channel,
4906 pReqMsg->buckets[bktIndex].channels[j].passive,
4907 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4908 }
4909
4910 bktIndex++;
4911 continue;
4912 }
4913
4914 /* Parse and fetch number of channels */
4915 if (!bucket[
4916 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
4917 hddLog(LOGE, FL("attr num channels failed"));
4918 return -EINVAL;
4919 }
4920
4921 pReqMsg->buckets[bktIndex].numChannels =
4922 nla_get_u32(bucket[
4923 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
4924 hddLog(LOG1, FL("num channels %d"),
4925 pReqMsg->buckets[bktIndex].numChannels);
4926
4927 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
4928 hddLog(LOGE, FL("attr channel spec failed"));
4929 return -EINVAL;
4930 }
4931
4932 j = 0;
4933 nla_for_each_nested(channels,
4934 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
4935 if (nla_parse(channel,
4936 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4937 nla_data(channels), nla_len(channels),
4938 wlan_hdd_extscan_config_policy)) {
4939 hddLog(LOGE, FL("nla_parse failed"));
4940 return -EINVAL;
4941 }
4942
4943 /* Parse and fetch channel */
4944 if (!channel[
4945 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
4946 hddLog(LOGE, FL("attr channel failed"));
4947 return -EINVAL;
4948 }
4949 pReqMsg->buckets[bktIndex].channels[j].channel =
4950 nla_get_u32(channel[
4951 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
4952 hddLog(LOG1, FL("channel %u"),
4953 pReqMsg->buckets[bktIndex].channels[j].channel);
4954
4955 /* Parse and fetch dwell time */
4956 if (!channel[
4957 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
4958 hddLog(LOGE, FL("attr dwelltime failed"));
4959 return -EINVAL;
4960 }
4961 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
4962 nla_get_u32(channel[
4963 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
4964
4965 hddLog(LOG1, FL("Dwell time (%u ms)"),
4966 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4967
4968
4969 /* Parse and fetch channel spec passive */
4970 if (!channel[
4971 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
4972 hddLog(LOGE,
4973 FL("attr channel spec passive failed"));
4974 return -EINVAL;
4975 }
4976 pReqMsg->buckets[bktIndex].channels[j].passive =
4977 nla_get_u8(channel[
4978 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
4979 hddLog(LOG1, FL("Chnl spec passive %u"),
4980 pReqMsg->buckets[bktIndex].channels[j].passive);
4981
4982 j++;
4983 }
4984
4985 bktIndex++;
4986 }
4987
4988 return 0;
4989}
4990
4991
4992/*
4993 * define short names for the global vendor params
4994 * used by wlan_hdd_cfg80211_extscan_start()
4995 */
4996#define PARAM_MAX \
4997QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
4998#define PARAM_REQUEST_ID \
4999QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
5000#define PARAM_BASE_PERIOD \
5001QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
5002#define PARAM_MAX_AP_PER_SCAN \
5003QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
5004#define PARAM_RPT_THRHLD_PERCENT \
5005QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
5006#define PARAM_RPT_THRHLD_NUM_SCANS \
5007QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
5008#define PARAM_NUM_BUCKETS \
5009QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
5010
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305011static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305012 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305013 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305014{
Dino Myclee8843b32014-07-04 14:21:45 +05305015 tpSirEXTScanStartReqParams pReqMsg = NULL;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305016 struct net_device *dev = wdev->netdev;
5017 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5018 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5019 struct nlattr *tb[PARAM_MAX + 1];
5020 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305021 eHalStatus status;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305022 tANI_U32 request_id;
5023 struct hdd_ext_scan_context *context;
5024 unsigned long rc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305025
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305026 ENTER();
5027
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305028 if (VOS_FTM_MODE == hdd_get_conparam()) {
5029 hddLog(LOGE, FL("Command not allowed in FTM mode"));
5030 return -EINVAL;
5031 }
5032
Dino Mycle6fb96c12014-06-10 11:52:40 +05305033 status = wlan_hdd_validate_context(pHddCtx);
5034 if (0 != status)
5035 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305036 return -EINVAL;
5037 }
Dino Myclee8843b32014-07-04 14:21:45 +05305038 /* check the EXTScan Capability */
5039 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305040 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
5041 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05305042 {
5043 hddLog(VOS_TRACE_LEVEL_ERROR,
5044 FL("EXTScan not enabled/supported by Firmware"));
5045 return -EINVAL;
5046 }
5047
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305048 if (nla_parse(tb, PARAM_MAX,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305049 data, dataLen,
5050 wlan_hdd_extscan_config_policy)) {
5051 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5052 return -EINVAL;
5053 }
5054
5055 /* Parse and fetch request Id */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305056 if (!tb[PARAM_REQUEST_ID]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305057 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5058 return -EINVAL;
5059 }
5060
Dino Myclee8843b32014-07-04 14:21:45 +05305061 pReqMsg = (tpSirEXTScanStartReqParams)
5062 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05305063 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05305064 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
5065 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305066 }
5067
5068 pReqMsg->requestId = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305069 tb[PARAM_REQUEST_ID]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305070 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
5071
5072 pReqMsg->sessionId = pAdapter->sessionId;
5073 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
5074
5075 /* Parse and fetch base period */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305076 if (!tb[PARAM_BASE_PERIOD]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305077 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
5078 goto fail;
5079 }
5080 pReqMsg->basePeriod = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305081 tb[PARAM_BASE_PERIOD]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305082 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
5083 pReqMsg->basePeriod);
5084
5085 /* Parse and fetch max AP per scan */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305086 if (!tb[PARAM_MAX_AP_PER_SCAN]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305087 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
5088 goto fail;
5089 }
5090 pReqMsg->maxAPperScan = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305091 tb[PARAM_MAX_AP_PER_SCAN]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305092 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
5093 pReqMsg->maxAPperScan);
5094
5095 /* Parse and fetch report threshold */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305096 if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305097 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
5098 goto fail;
5099 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305100 pReqMsg->reportThresholdPercent = nla_get_u8(
5101 tb[PARAM_RPT_THRHLD_PERCENT]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305102 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305103 pReqMsg->reportThresholdPercent);
5104
5105 /* Parse and fetch report threshold num scans */
5106 if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
5107 hddLog(LOGE, FL("attr report_threshold num scans failed"));
5108 goto fail;
5109 }
5110 pReqMsg->reportThresholdNumScans = nla_get_u8(
5111 tb[PARAM_RPT_THRHLD_NUM_SCANS]);
5112 hddLog(LOG1, FL("Report Threshold num scans %d"),
5113 pReqMsg->reportThresholdNumScans);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305114
5115 /* Parse and fetch number of buckets */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305116 if (!tb[PARAM_NUM_BUCKETS]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305117 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
5118 goto fail;
5119 }
5120 pReqMsg->numBuckets = nla_get_u8(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305121 tb[PARAM_NUM_BUCKETS]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305122 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
5123 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
5124 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
5125 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
5126 }
5127 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
5128 pReqMsg->numBuckets);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305129
Dino Mycle6fb96c12014-06-10 11:52:40 +05305130 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
5131 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
5132 goto fail;
5133 }
5134
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305135 pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305136
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305137 if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
5138 goto fail;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05305139
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305140 context = &pHddCtx->ext_scan_context;
5141 spin_lock(&hdd_context_lock);
5142 INIT_COMPLETION(context->response_event);
5143 context->request_id = request_id = pReqMsg->requestId;
5144 spin_unlock(&hdd_context_lock);
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05305145
Dino Mycle6fb96c12014-06-10 11:52:40 +05305146 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
5147 if (!HAL_STATUS_SUCCESS(status)) {
5148 hddLog(VOS_TRACE_LEVEL_ERROR,
5149 FL("sme_EXTScanStart failed(err=%d)"), status);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305150 goto fail;
5151 }
5152
Srinivas Dasari91727c12016-03-23 17:59:06 +05305153 pHddCtx->extscan_start_time_since_boot = vos_get_monotonic_boottime();
5154
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305155 /* request was sent -- wait for the response */
5156 rc = wait_for_completion_timeout(&context->response_event,
5157 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5158
5159 if (!rc) {
5160 hddLog(LOGE, FL("sme_ExtScanStart timed out"));
5161 retval = -ETIMEDOUT;
5162 } else {
5163 spin_lock(&hdd_context_lock);
5164 if (context->request_id == request_id)
5165 retval = context->response_status;
5166 else
5167 retval = -EINVAL;
5168 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305169 }
5170
Dino Myclee8843b32014-07-04 14:21:45 +05305171 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305172 EXIT();
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305173 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305174
5175fail:
5176 vos_mem_free(pReqMsg);
5177 return -EINVAL;
5178}
5179
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305180/*
5181 * done with short names for the global vendor params
5182 * used by wlan_hdd_cfg80211_extscan_start()
5183 */
5184#undef PARAM_MAX
5185#undef PARAM_REQUEST_ID
5186#undef PARAM_BASE_PERIOD
5187#undef PARAMS_MAX_AP_PER_SCAN
5188#undef PARAMS_RPT_THRHLD_PERCENT
5189#undef PARAMS_RPT_THRHLD_NUM_SCANS
5190#undef PARAMS_NUM_BUCKETS
5191
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305192static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
5193 struct wireless_dev *wdev,
5194 const void *data, int dataLen)
5195{
5196 int ret = 0;
5197
5198 vos_ssr_protect(__func__);
5199 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
5200 vos_ssr_unprotect(__func__);
5201
5202 return ret;
5203}
5204
5205static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305206 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305207 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305208{
Dino Myclee8843b32014-07-04 14:21:45 +05305209 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305210 struct net_device *dev = wdev->netdev;
5211 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5212 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5213 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
5214 eHalStatus status;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305215 int retval;
5216 unsigned long rc;
5217 struct hdd_ext_scan_context *context;
5218 tANI_U32 request_id;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305219
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305220 ENTER();
5221
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305222 if (VOS_FTM_MODE == hdd_get_conparam()) {
5223 hddLog(LOGE, FL("Command not allowed in FTM mode"));
5224 return -EINVAL;
5225 }
5226
Dino Mycle6fb96c12014-06-10 11:52:40 +05305227 status = wlan_hdd_validate_context(pHddCtx);
5228 if (0 != status)
5229 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305230 return -EINVAL;
5231 }
Dino Myclee8843b32014-07-04 14:21:45 +05305232 /* check the EXTScan Capability */
5233 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305234 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
5235 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05305236 {
5237 hddLog(VOS_TRACE_LEVEL_ERROR,
5238 FL("EXTScan not enabled/supported by Firmware"));
5239 return -EINVAL;
5240 }
5241
Dino Mycle6fb96c12014-06-10 11:52:40 +05305242 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5243 data, dataLen,
5244 wlan_hdd_extscan_config_policy)) {
5245 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5246 return -EINVAL;
5247 }
5248
5249 /* Parse and fetch request Id */
5250 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
5251 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5252 return -EINVAL;
5253 }
5254
Dino Myclee8843b32014-07-04 14:21:45 +05305255 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05305256 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05305257 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305258
Dino Myclee8843b32014-07-04 14:21:45 +05305259 reqMsg.sessionId = pAdapter->sessionId;
5260 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305261
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305262 context = &pHddCtx->ext_scan_context;
5263 spin_lock(&hdd_context_lock);
5264 INIT_COMPLETION(context->response_event);
Sravanti Palakonda7539fb92016-02-26 17:49:21 +05305265 context->request_id = request_id = reqMsg.requestId;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305266 spin_unlock(&hdd_context_lock);
5267
Dino Myclee8843b32014-07-04 14:21:45 +05305268 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305269 if (!HAL_STATUS_SUCCESS(status)) {
5270 hddLog(VOS_TRACE_LEVEL_ERROR,
5271 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305272 return -EINVAL;
5273 }
5274
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305275 /* request was sent -- wait for the response */
5276 rc = wait_for_completion_timeout(&context->response_event,
5277 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5278
5279 if (!rc) {
5280 hddLog(LOGE, FL("sme_ExtScanStop timed out"));
5281 retval = -ETIMEDOUT;
5282 } else {
5283 spin_lock(&hdd_context_lock);
5284 if (context->request_id == request_id)
5285 retval = context->response_status;
5286 else
5287 retval = -EINVAL;
5288 spin_unlock(&hdd_context_lock);
5289 }
5290
5291 return retval;
5292
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305293 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05305294 return 0;
5295}
5296
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305297static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
5298 struct wireless_dev *wdev,
5299 const void *data, int dataLen)
5300{
5301 int ret = 0;
5302
5303 vos_ssr_protect(__func__);
5304 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
5305 vos_ssr_unprotect(__func__);
5306
5307 return ret;
5308}
5309
5310static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305311 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305312 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305313{
Dino Myclee8843b32014-07-04 14:21:45 +05305314 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305315 struct net_device *dev = wdev->netdev;
5316 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5317 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5318 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
5319 eHalStatus status;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305320 struct hdd_ext_scan_context *context;
5321 tANI_U32 request_id;
5322 unsigned long rc;
5323 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305324
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305325 ENTER();
5326
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305327 if (VOS_FTM_MODE == hdd_get_conparam()) {
5328 hddLog(LOGE, FL("Command not allowed in FTM mode"));
5329 return -EINVAL;
5330 }
5331
Dino Mycle6fb96c12014-06-10 11:52:40 +05305332 status = wlan_hdd_validate_context(pHddCtx);
5333 if (0 != status)
5334 {
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305335 hddLog(LOGE, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05305336 return -EINVAL;
5337 }
Dino Myclee8843b32014-07-04 14:21:45 +05305338 /* check the EXTScan Capability */
5339 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305340 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
5341 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05305342 {
5343 hddLog(VOS_TRACE_LEVEL_ERROR,
5344 FL("EXTScan not enabled/supported by Firmware"));
5345 return -EINVAL;
5346 }
5347
Dino Mycle6fb96c12014-06-10 11:52:40 +05305348 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5349 data, dataLen,
5350 wlan_hdd_extscan_config_policy)) {
5351 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5352 return -EINVAL;
5353 }
5354
5355 /* Parse and fetch request Id */
5356 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
5357 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5358 return -EINVAL;
5359 }
5360
Dino Myclee8843b32014-07-04 14:21:45 +05305361 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05305362 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05305363 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305364
Dino Myclee8843b32014-07-04 14:21:45 +05305365 reqMsg.sessionId = pAdapter->sessionId;
5366 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305367
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305368 context = &pHddCtx->ext_scan_context;
5369 spin_lock(&hdd_context_lock);
5370 INIT_COMPLETION(context->response_event);
5371 context->request_id = request_id = reqMsg.requestId;
5372 spin_unlock(&hdd_context_lock);
5373
Dino Myclee8843b32014-07-04 14:21:45 +05305374 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305375 if (!HAL_STATUS_SUCCESS(status)) {
5376 hddLog(VOS_TRACE_LEVEL_ERROR,
5377 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305378 return -EINVAL;
5379 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305380
5381 /* request was sent -- wait for the response */
5382 rc = wait_for_completion_timeout(&context->response_event,
5383 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5384 if (!rc) {
5385 hddLog(LOGE, FL("sme_ResetBssHotlist timed out"));
5386 retval = -ETIMEDOUT;
5387 } else {
5388 spin_lock(&hdd_context_lock);
5389 if (context->request_id == request_id)
5390 retval = context->response_status;
5391 else
5392 retval = -EINVAL;
5393 spin_unlock(&hdd_context_lock);
5394 }
5395
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305396 EXIT();
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305397 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305398}
5399
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305400static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
5401 struct wireless_dev *wdev,
5402 const void *data, int dataLen)
5403{
5404 int ret = 0;
5405
5406 vos_ssr_protect(__func__);
5407 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
5408 vos_ssr_unprotect(__func__);
5409
5410 return ret;
5411}
Dino Mycle6fb96c12014-06-10 11:52:40 +05305412#endif /* WLAN_FEATURE_EXTSCAN */
5413
Atul Mittal115287b2014-07-08 13:26:33 +05305414/*EXT TDLS*/
5415static const struct nla_policy
5416wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
5417{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305418 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {
5419 .type = NLA_UNSPEC,
5420 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305421 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
5422 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
5423 {.type = NLA_S32 },
5424 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
5425 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
5426
5427};
5428
5429static const struct nla_policy
5430wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
5431{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305432 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {
5433 .type = NLA_UNSPEC,
5434 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305435
5436};
5437
5438static const struct nla_policy
5439wlan_hdd_tdls_config_state_change_policy[
5440 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
5441{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305442 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {
5443 .type = NLA_UNSPEC,
5444 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305445 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
5446 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305447 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
5448 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
5449 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305450
5451};
5452
5453static const struct nla_policy
5454wlan_hdd_tdls_config_get_status_policy[
5455 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
5456{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305457 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {
5458 .type = NLA_UNSPEC,
5459 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305460 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
5461 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305462 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
5463 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
5464 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305465
5466};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305467
5468static const struct nla_policy
5469wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
5470{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305471 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {
5472 .type = NLA_UNSPEC,
5473 .len = VOS_MAC_ADDR_FIRST_3_BYTES},
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305474};
5475
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305476static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305477 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305478 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305479 int data_len)
5480{
5481
5482 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5483 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
5484
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305485 ENTER();
5486
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305487 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305488 return -EINVAL;
5489 }
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +05305490 if (0 == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05305491 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305492 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05305493 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305494 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05305495 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305496 return -ENOTSUPP;
5497 }
5498
5499 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
5500 data, data_len, wlan_hdd_mac_config)) {
5501 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5502 return -EINVAL;
5503 }
5504
5505 /* Parse and fetch mac address */
5506 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
5507 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5508 return -EINVAL;
5509 }
5510
5511 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
5512 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5513 VOS_MAC_ADDR_LAST_3_BYTES);
5514
Siddharth Bhal76972212014-10-15 16:22:51 +05305515 pHddCtx->spoofMacAddr.isEnabled = TRUE;
5516
5517 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305518 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5519 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05305520 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
5521 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
5522 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
5523 {
5524 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
5525 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
5526 VOS_MAC_ADDRESS_LEN);
5527 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305528 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305529
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +05305530 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
5531 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305532
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305533 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305534 return 0;
5535}
5536
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305537static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
5538 struct wireless_dev *wdev,
5539 const void *data,
5540 int data_len)
5541{
5542 int ret = 0;
5543
5544 vos_ssr_protect(__func__);
5545 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
5546 vos_ssr_unprotect(__func__);
5547
5548 return ret;
5549}
5550
5551static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305552 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305553 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305554 int data_len)
5555{
5556 u8 peer[6] = {0};
5557 struct net_device *dev = wdev->netdev;
5558 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5559 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5560 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
5561 eHalStatus ret;
5562 tANI_S32 state;
5563 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305564 tANI_S32 global_operating_class = 0;
5565 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05305566 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305567 int retVal;
5568
5569 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305570
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305571 if (!pAdapter) {
5572 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5573 return -EINVAL;
5574 }
5575
Atul Mittal115287b2014-07-08 13:26:33 +05305576 ret = wlan_hdd_validate_context(pHddCtx);
5577 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305578 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305579 return -EINVAL;
5580 }
5581 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305582 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305583 return -ENOTSUPP;
5584 }
5585 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
5586 data, data_len,
5587 wlan_hdd_tdls_config_get_status_policy)) {
5588 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5589 return -EINVAL;
5590 }
5591
5592 /* Parse and fetch mac address */
5593 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
5594 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5595 return -EINVAL;
5596 }
5597
5598 memcpy(peer, nla_data(
5599 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
5600 sizeof(peer));
5601 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5602
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05305603 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05305604
Atul Mittal115287b2014-07-08 13:26:33 +05305605 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305606 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05305607 NLMSG_HDRLEN);
5608
5609 if (!skb) {
5610 hddLog(VOS_TRACE_LEVEL_ERROR,
5611 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5612 return -EINVAL;
5613 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305614 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 +05305615 reason,
5616 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305617 global_operating_class,
5618 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05305619 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305620 if (nla_put_s32(skb,
5621 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
5622 state) ||
5623 nla_put_s32(skb,
5624 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
5625 reason) ||
5626 nla_put_s32(skb,
5627 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
5628 global_operating_class) ||
5629 nla_put_s32(skb,
5630 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
5631 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05305632
5633 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5634 goto nla_put_failure;
5635 }
5636
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305637 retVal = cfg80211_vendor_cmd_reply(skb);
5638 EXIT();
5639 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05305640
5641nla_put_failure:
5642 kfree_skb(skb);
5643 return -EINVAL;
5644}
5645
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305646static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
5647 struct wireless_dev *wdev,
5648 const void *data,
5649 int data_len)
5650{
5651 int ret = 0;
5652
5653 vos_ssr_protect(__func__);
5654 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
5655 vos_ssr_unprotect(__func__);
5656
5657 return ret;
5658}
5659
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05305660static int wlan_hdd_cfg80211_exttdls_callback(
5661#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
5662 const tANI_U8* mac,
5663#else
5664 tANI_U8* mac,
5665#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305666 tANI_S32 state,
5667 tANI_S32 reason,
5668 void *ctx)
5669{
5670 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05305671 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305672 tANI_S32 global_operating_class = 0;
5673 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305674 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05305675
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305676 ENTER();
5677
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305678 if (!pAdapter) {
5679 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5680 return -EINVAL;
5681 }
5682
5683 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05305684 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305685 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305686 return -EINVAL;
5687 }
5688
5689 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305690 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305691 return -ENOTSUPP;
5692 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05305693 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
5694#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
5695 NULL,
5696#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305697 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
5698 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
5699 GFP_KERNEL);
5700
5701 if (!skb) {
5702 hddLog(VOS_TRACE_LEVEL_ERROR,
5703 FL("cfg80211_vendor_event_alloc failed"));
5704 return -EINVAL;
5705 }
5706 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305707 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
5708 reason,
5709 state,
5710 global_operating_class,
5711 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05305712 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
5713 MAC_ADDR_ARRAY(mac));
5714
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305715 if (nla_put(skb,
5716 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
5717 VOS_MAC_ADDR_SIZE, mac) ||
5718 nla_put_s32(skb,
5719 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
5720 state) ||
5721 nla_put_s32(skb,
5722 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
5723 reason) ||
5724 nla_put_s32(skb,
5725 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
5726 channel) ||
5727 nla_put_s32(skb,
5728 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
5729 global_operating_class)
5730 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05305731 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5732 goto nla_put_failure;
5733 }
5734
5735 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305736 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05305737 return (0);
5738
5739nla_put_failure:
5740 kfree_skb(skb);
5741 return -EINVAL;
5742}
5743
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305744static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305745 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305746 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305747 int data_len)
5748{
5749 u8 peer[6] = {0};
5750 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305751 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5752 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
5753 eHalStatus status;
5754 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305755 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305756 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305757
5758 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305759
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305760 if (!dev) {
5761 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5762 return -EINVAL;
5763 }
5764
5765 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5766 if (!pAdapter) {
5767 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5768 return -EINVAL;
5769 }
5770
Atul Mittal115287b2014-07-08 13:26:33 +05305771 status = wlan_hdd_validate_context(pHddCtx);
5772 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305773 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305774 return -EINVAL;
5775 }
5776 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305777 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305778 return -ENOTSUPP;
5779 }
5780 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
5781 data, data_len,
5782 wlan_hdd_tdls_config_enable_policy)) {
5783 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5784 return -EINVAL;
5785 }
5786
5787 /* Parse and fetch mac address */
5788 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
5789 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5790 return -EINVAL;
5791 }
5792
5793 memcpy(peer, nla_data(
5794 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
5795 sizeof(peer));
5796 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5797
5798 /* Parse and fetch channel */
5799 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
5800 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
5801 return -EINVAL;
5802 }
5803 pReqMsg.channel = nla_get_s32(
5804 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
5805 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
5806
5807 /* Parse and fetch global operating class */
5808 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
5809 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
5810 return -EINVAL;
5811 }
5812 pReqMsg.global_operating_class = nla_get_s32(
5813 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
5814 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
5815 pReqMsg.global_operating_class);
5816
5817 /* Parse and fetch latency ms */
5818 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
5819 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
5820 return -EINVAL;
5821 }
5822 pReqMsg.max_latency_ms = nla_get_s32(
5823 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
5824 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
5825 pReqMsg.max_latency_ms);
5826
5827 /* Parse and fetch required bandwidth kbps */
5828 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
5829 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
5830 return -EINVAL;
5831 }
5832
5833 pReqMsg.min_bandwidth_kbps = nla_get_s32(
5834 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
5835 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
5836 pReqMsg.min_bandwidth_kbps);
5837
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305838 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05305839 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05305840 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305841 wlan_hdd_cfg80211_exttdls_callback);
5842
5843 EXIT();
5844 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305845}
5846
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305847static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
5848 struct wireless_dev *wdev,
5849 const void *data,
5850 int data_len)
5851{
5852 int ret = 0;
5853
5854 vos_ssr_protect(__func__);
5855 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
5856 vos_ssr_unprotect(__func__);
5857
5858 return ret;
5859}
5860
5861static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305862 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305863 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305864 int data_len)
5865{
5866 u8 peer[6] = {0};
5867 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305868 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5869 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
5870 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305871 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305872 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305873
5874 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305875
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305876 if (!dev) {
5877 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5878 return -EINVAL;
5879 }
5880
5881 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5882 if (!pAdapter) {
5883 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
5884 return -EINVAL;
5885 }
5886
Atul Mittal115287b2014-07-08 13:26:33 +05305887 status = wlan_hdd_validate_context(pHddCtx);
5888 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305889 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305890 return -EINVAL;
5891 }
5892 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305893 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305894 return -ENOTSUPP;
5895 }
5896 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
5897 data, data_len,
5898 wlan_hdd_tdls_config_disable_policy)) {
5899 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5900 return -EINVAL;
5901 }
5902 /* Parse and fetch mac address */
5903 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
5904 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5905 return -EINVAL;
5906 }
5907
5908 memcpy(peer, nla_data(
5909 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
5910 sizeof(peer));
5911 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5912
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305913 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
5914
5915 EXIT();
5916 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305917}
5918
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305919static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
5920 struct wireless_dev *wdev,
5921 const void *data,
5922 int data_len)
5923{
5924 int ret = 0;
5925
5926 vos_ssr_protect(__func__);
5927 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
5928 vos_ssr_unprotect(__func__);
5929
5930 return ret;
5931}
5932
Dasari Srinivas7875a302014-09-26 17:50:57 +05305933static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305934__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05305935 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305936 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05305937{
5938 struct net_device *dev = wdev->netdev;
5939 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5940 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5941 struct sk_buff *skb = NULL;
5942 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305943 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305944
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305945 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305946
5947 ret = wlan_hdd_validate_context(pHddCtx);
5948 if (0 != ret)
5949 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305950 return ret;
5951 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305952 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
5953 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
5954 fset |= WIFI_FEATURE_INFRA;
5955 }
5956
5957 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
5958 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
5959 fset |= WIFI_FEATURE_INFRA_5G;
5960 }
5961
5962#ifdef WLAN_FEATURE_P2P
5963 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
5964 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
5965 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
5966 fset |= WIFI_FEATURE_P2P;
5967 }
5968#endif
5969
5970 /* Soft-AP is supported currently by default */
5971 fset |= WIFI_FEATURE_SOFT_AP;
5972
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05305973 /* HOTSPOT is a supplicant feature, enable it by default */
5974 fset |= WIFI_FEATURE_HOTSPOT;
5975
Dasari Srinivas7875a302014-09-26 17:50:57 +05305976#ifdef WLAN_FEATURE_EXTSCAN
5977 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305978 sme_IsFeatureSupportedByFW(EXTENDED_SCAN) &&
5979 sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)) {
5980 hddLog(LOG1, FL("Enhanced EXTScan is supported by firmware"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05305981 fset |= WIFI_FEATURE_EXTSCAN;
5982 }
5983#endif
5984
Dasari Srinivas7875a302014-09-26 17:50:57 +05305985 if (sme_IsFeatureSupportedByFW(NAN)) {
5986 hddLog(LOG1, FL("NAN is supported by firmware"));
5987 fset |= WIFI_FEATURE_NAN;
5988 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305989
5990 /* D2D RTT is not supported currently by default */
Sourav Mohapatradf8b23c2017-11-17 17:50:31 +05305991 if (sme_IsFeatureSupportedByFW(RTT) &&
5992 pHddCtx->cfg_ini->enable_rtt_support) {
5993 hddLog(LOG1, FL("RTT is supported by firmware and framework"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05305994 fset |= WIFI_FEATURE_D2AP_RTT;
5995 }
5996
Padma, Santhosh Kumaraac4c4d2015-12-08 16:07:47 +05305997 if (sme_IsFeatureSupportedByFW(RTT3)) {
5998 hddLog(LOG1, FL("RTT3 is supported by firmware"));
5999 fset |= WIFI_FEATURE_RTT3;
6000 }
6001
Dasari Srinivas7875a302014-09-26 17:50:57 +05306002#ifdef FEATURE_WLAN_BATCH_SCAN
6003 if (fset & WIFI_FEATURE_EXTSCAN) {
6004 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
6005 fset &= ~WIFI_FEATURE_BATCH_SCAN;
6006 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
6007 hddLog(LOG1, FL("Batch scan is supported by firmware"));
6008 fset |= WIFI_FEATURE_BATCH_SCAN;
6009 }
6010#endif
6011
6012#ifdef FEATURE_WLAN_SCAN_PNO
6013 if (pHddCtx->cfg_ini->configPNOScanSupport &&
6014 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
6015 hddLog(LOG1, FL("PNO is supported by firmware"));
6016 fset |= WIFI_FEATURE_PNO;
6017 }
6018#endif
6019
6020 /* STA+STA is supported currently by default */
6021 fset |= WIFI_FEATURE_ADDITIONAL_STA;
6022
6023#ifdef FEATURE_WLAN_TDLS
6024 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
6025 sme_IsFeatureSupportedByFW(TDLS)) {
6026 hddLog(LOG1, FL("TDLS is supported by firmware"));
6027 fset |= WIFI_FEATURE_TDLS;
6028 }
6029
6030 /* TDLS_OFFCHANNEL is not supported currently by default */
6031#endif
6032
6033#ifdef WLAN_AP_STA_CONCURRENCY
6034 /* AP+STA concurrency is supported currently by default */
6035 fset |= WIFI_FEATURE_AP_STA;
6036#endif
6037
Mukul Sharma5add0532015-08-17 15:57:47 +05306038#ifdef WLAN_FEATURE_LINK_LAYER_STATS
Ajit Vaishya8353cfb2017-11-10 16:22:36 +05306039 if ((TRUE == pHddCtx->cfg_ini->fEnableLLStats) &&
6040 (TRUE == sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS))) {
Mukul Sharma5add0532015-08-17 15:57:47 +05306041 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
6042 hddLog(LOG1, FL("Link layer stats is supported by driver"));
Ajit Vaishya8353cfb2017-11-10 16:22:36 +05306043 }
Mukul Sharma5add0532015-08-17 15:57:47 +05306044#endif
6045
Dasari Srinivas7875a302014-09-26 17:50:57 +05306046 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
6047 NLMSG_HDRLEN);
6048
6049 if (!skb) {
6050 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6051 return -EINVAL;
6052 }
6053 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
6054
6055 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
6056 hddLog(LOGE, FL("nla put fail"));
6057 goto nla_put_failure;
6058 }
6059
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306060 ret = cfg80211_vendor_cmd_reply(skb);
6061 EXIT();
6062 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05306063
6064nla_put_failure:
6065 kfree_skb(skb);
6066 return -EINVAL;
6067}
6068
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306069static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306070wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
6071 struct wireless_dev *wdev,
6072 const void *data, int data_len)
6073{
6074 int ret = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306075 vos_ssr_protect(__func__);
6076 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
6077 vos_ssr_unprotect(__func__);
6078
6079 return ret;
6080}
6081
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306082
6083static const struct
6084nla_policy
6085qca_wlan_vendor_wifi_logger_get_ring_data_policy
6086[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1] = {
6087 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]
6088 = {.type = NLA_U32 },
6089};
6090
6091static int
6092 __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
6093 struct wireless_dev *wdev,
6094 const void *data,
6095 int data_len)
6096{
6097 int ret;
6098 VOS_STATUS status;
6099 uint32_t ring_id;
6100 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6101 struct nlattr *tb
6102 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1];
6103
6104 ENTER();
6105
6106 ret = wlan_hdd_validate_context(hdd_ctx);
6107 if (0 != ret) {
6108 return ret;
6109 }
6110
6111 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX,
6112 data, data_len,
6113 qca_wlan_vendor_wifi_logger_get_ring_data_policy)) {
6114 hddLog(LOGE, FL("Invalid attribute"));
6115 return -EINVAL;
6116 }
6117
6118 /* Parse and fetch ring id */
6119 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]) {
6120 hddLog(LOGE, FL("attr ATTR failed"));
6121 return -EINVAL;
6122 }
6123
6124 ring_id = nla_get_u32(
6125 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]);
6126
6127 hddLog(LOG1, FL("Bug report triggered by framework"));
6128
6129 status = vos_fatal_event_logs_req(WLAN_LOG_TYPE_NON_FATAL,
6130 WLAN_LOG_INDICATOR_FRAMEWORK,
6131 WLAN_LOG_REASON_CODE_FRAMEWORK,
Abhishek Singh837adf22015-10-01 17:37:37 +05306132 TRUE, TRUE
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306133 );
6134 if (VOS_STATUS_SUCCESS != status) {
6135 hddLog(LOGE, FL("Failed to trigger bug report"));
6136
6137 return -EINVAL;
6138 }
6139
6140 return 0;
6141
6142
6143}
6144
6145
6146static int
6147 wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
6148 struct wireless_dev *wdev,
6149 const void *data,
6150 int data_len)
6151{
6152 int ret = 0;
6153
6154 vos_ssr_protect(__func__);
6155 ret = __wlan_hdd_cfg80211_wifi_logger_get_ring_data(wiphy,
6156 wdev, data, data_len);
6157 vos_ssr_unprotect(__func__);
6158
6159 return ret;
6160
6161}
6162
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306163#define MAX_CONCURRENT_MATRIX \
6164 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX
6165#define MATRIX_CONFIG_PARAM_SET_SIZE_MAX \
6166 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX
6167static const struct nla_policy
6168wlan_hdd_get_concurrency_matrix_policy[MAX_CONCURRENT_MATRIX + 1] = {
6169 [MATRIX_CONFIG_PARAM_SET_SIZE_MAX] = {.type = NLA_U32},
6170};
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306171
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306172static int
6173__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306174 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306175 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306176{
6177 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
6178 uint8_t i, feature_sets, max_feature_sets;
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306179 struct nlattr *tb[MAX_CONCURRENT_MATRIX + 1];
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306180 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306181 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6182 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306183
6184 ENTER();
6185
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306186 ret = wlan_hdd_validate_context(pHddCtx);
6187 if (0 != ret)
6188 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306189 return ret;
6190 }
6191
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306192 if (nla_parse(tb, MAX_CONCURRENT_MATRIX, data, data_len,
6193 wlan_hdd_get_concurrency_matrix_policy)) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306194 hddLog(LOGE, FL("Invalid ATTR"));
6195 return -EINVAL;
6196 }
6197
6198 /* Parse and fetch max feature set */
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306199 if (!tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306200 hddLog(LOGE, FL("Attr max feature set size failed"));
6201 return -EINVAL;
6202 }
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306203 max_feature_sets = nla_get_u32(tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306204 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
6205
6206 /* Fill feature combination matrix */
6207 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306208 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6209 WIFI_FEATURE_P2P;
6210
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306211 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6212 WIFI_FEATURE_SOFT_AP;
6213
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306214 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
6215 WIFI_FEATURE_SOFT_AP;
6216
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306217 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6218 WIFI_FEATURE_SOFT_AP |
6219 WIFI_FEATURE_P2P;
6220
6221 /* Add more feature combinations here */
6222
6223 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
6224 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
6225 hddLog(LOG1, "Feature set matrix");
6226 for (i = 0; i < feature_sets; i++)
6227 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
6228
6229 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
6230 sizeof(u32) * feature_sets +
6231 NLMSG_HDRLEN);
6232
6233 if (reply_skb) {
6234 if (nla_put_u32(reply_skb,
6235 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
6236 feature_sets) ||
6237 nla_put(reply_skb,
6238 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
6239 sizeof(u32) * feature_sets, feature_set_matrix)) {
6240 hddLog(LOGE, FL("nla put fail"));
6241 kfree_skb(reply_skb);
6242 return -EINVAL;
6243 }
6244
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306245 ret = cfg80211_vendor_cmd_reply(reply_skb);
6246 EXIT();
6247 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306248 }
6249 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
6250 return -ENOMEM;
6251
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306252}
6253
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306254#undef MAX_CONCURRENT_MATRIX
6255#undef MATRIX_CONFIG_PARAM_SET_SIZE_MAX
6256
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306257static int
6258wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
6259 struct wireless_dev *wdev,
6260 const void *data, int data_len)
6261{
6262 int ret = 0;
6263
6264 vos_ssr_protect(__func__);
6265 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
6266 data_len);
6267 vos_ssr_unprotect(__func__);
6268
6269 return ret;
6270}
6271
c_manjeecfd1efb2015-09-25 19:32:34 +05306272
6273static int
6274__wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
6275 struct wireless_dev *wdev,
6276 const void *data, int data_len)
6277{
6278 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6279 int ret;
6280 ENTER();
6281
6282 ret = wlan_hdd_validate_context(pHddCtx);
6283 if (0 != ret)
6284 {
6285 return ret;
6286 }
6287
6288 if( !pHddCtx->cfg_ini->enableFwrMemDump ||
6289 (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
6290 {
6291 hddLog(VOS_TRACE_LEVEL_INFO, FL("FW dump Logging not supported"));
Ajit Vaishyac5ba8482017-11-16 14:10:37 +05306292 return -EOPNOTSUPP;
c_manjeecfd1efb2015-09-25 19:32:34 +05306293 }
6294 /*call common API for FW mem dump req*/
6295 ret = wlan_hdd_fw_mem_dump_req(pHddCtx);
6296
Abhishek Singhc783fa72015-12-09 18:07:34 +05306297 if (!ret)
c_manjee04b4c5c2015-10-13 18:35:01 +05306298 {
6299 /*indicate to userspace the status of fw mem dump */
6300 wlan_indicate_mem_dump_complete(true);
6301 }
6302 else
6303 {
6304 /*else send failure to userspace */
6305 wlan_indicate_mem_dump_complete(false);
6306 }
c_manjeecfd1efb2015-09-25 19:32:34 +05306307 EXIT();
6308 return ret;
6309}
6310
6311/**
6312 * wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump
6313 * @wiphy: pointer to wireless wiphy structure.
6314 * @wdev: pointer to wireless_dev structure.
6315 * @data: Pointer to the NL data.
6316 * @data_len:Length of @data
6317 *
6318 * This is called when wlan driver needs to get the firmware memory dump
6319 * via vendor specific command.
6320 *
6321 * Return: 0 on success, error number otherwise.
6322 */
6323
6324static int
6325wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
6326 struct wireless_dev *wdev,
6327 const void *data, int data_len)
Sushant Kaushik8e644982015-09-23 12:18:54 +05306328{
6329 int ret = 0;
6330 vos_ssr_protect(__func__);
6331 ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data,
6332 data_len);
6333 vos_ssr_unprotect(__func__);
6334 return ret;
6335}
c_manjeecfd1efb2015-09-25 19:32:34 +05306336
Sushant Kaushik8e644982015-09-23 12:18:54 +05306337static const struct
6338nla_policy
6339qca_wlan_vendor_wifi_logger_start_policy
6340[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
6341 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
6342 = {.type = NLA_U32 },
6343 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
6344 = {.type = NLA_U32 },
6345 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
6346 = {.type = NLA_U32 },
6347};
6348
6349/**
6350 * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
6351 * or disable the collection of packet statistics from the firmware
6352 * @wiphy: WIPHY structure pointer
6353 * @wdev: Wireless device structure pointer
6354 * @data: Pointer to the data received
6355 * @data_len: Length of the data received
6356 *
6357 * This function is used to enable or disable the collection of packet
6358 * statistics from the firmware
6359 *
6360 * Return: 0 on success and errno on failure
6361 */
6362static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6363 struct wireless_dev *wdev,
6364 const void *data,
6365 int data_len)
6366{
6367 eHalStatus status;
6368 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6369 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
6370 tAniWifiStartLog start_log;
6371
6372 status = wlan_hdd_validate_context(hdd_ctx);
6373 if (0 != status) {
6374 return -EINVAL;
6375 }
6376
6377 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
6378 data, data_len,
6379 qca_wlan_vendor_wifi_logger_start_policy)) {
6380 hddLog(LOGE, FL("Invalid attribute"));
6381 return -EINVAL;
6382 }
6383
6384 /* Parse and fetch ring id */
6385 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
6386 hddLog(LOGE, FL("attr ATTR failed"));
6387 return -EINVAL;
6388 }
6389 start_log.ringId = nla_get_u32(
6390 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
6391 hddLog(LOG1, FL("Ring ID=%d"), start_log.ringId);
6392
6393 /* Parse and fetch verbose level */
6394 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
6395 hddLog(LOGE, FL("attr verbose_level failed"));
6396 return -EINVAL;
6397 }
6398 start_log.verboseLevel = nla_get_u32(
6399 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
6400 hddLog(LOG1, FL("verbose_level=%d"), start_log.verboseLevel);
6401
6402 /* Parse and fetch flag */
6403 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
6404 hddLog(LOGE, FL("attr flag failed"));
6405 return -EINVAL;
6406 }
6407 start_log.flag = nla_get_u32(
6408 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
6409 hddLog(LOG1, FL("flag=%d"), start_log.flag);
6410
6411 if ((RING_ID_PER_PACKET_STATS == start_log.ringId) &&
Sushant Kaushik33200572015-08-05 16:46:20 +05306412 (!hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable ||
6413 !vos_isPktStatsEnabled()))
6414
Sushant Kaushik8e644982015-09-23 12:18:54 +05306415 {
6416 hddLog(LOGE, FL("per pkt stats not enabled"));
6417 return -EINVAL;
6418 }
Sushant Kaushik8e644982015-09-23 12:18:54 +05306419
Sushant Kaushik33200572015-08-05 16:46:20 +05306420 vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306421 return 0;
6422}
6423
6424/**
6425 * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
6426 * or disable the collection of packet statistics from the firmware
6427 * @wiphy: WIPHY structure pointer
6428 * @wdev: Wireless device structure pointer
6429 * @data: Pointer to the data received
6430 * @data_len: Length of the data received
6431 *
6432 * This function is used to enable or disable the collection of packet
6433 * statistics from the firmware
6434 *
6435 * Return: 0 on success and errno on failure
6436 */
6437static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6438 struct wireless_dev *wdev,
6439 const void *data,
6440 int data_len)
c_manjeecfd1efb2015-09-25 19:32:34 +05306441{
6442 int ret = 0;
6443
6444 vos_ssr_protect(__func__);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306445
6446 ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
6447 wdev, data, data_len);
c_manjeecfd1efb2015-09-25 19:32:34 +05306448 vos_ssr_unprotect(__func__);
6449
6450 return ret;
c_manjeecfd1efb2015-09-25 19:32:34 +05306451}
6452
6453
Agarwal Ashish738843c2014-09-25 12:27:56 +05306454static const struct nla_policy
6455wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
6456 +1] =
6457{
6458 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
6459};
6460
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306461static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306462 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306463 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306464 int data_len)
6465{
6466 struct net_device *dev = wdev->netdev;
6467 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6468 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6469 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6470 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
6471 eHalStatus status;
6472 u32 dfsFlag = 0;
6473
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306474 ENTER();
6475
Agarwal Ashish738843c2014-09-25 12:27:56 +05306476 status = wlan_hdd_validate_context(pHddCtx);
6477 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05306478 return -EINVAL;
6479 }
6480 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
6481 data, data_len,
6482 wlan_hdd_set_no_dfs_flag_config_policy)) {
6483 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6484 return -EINVAL;
6485 }
6486
6487 /* Parse and fetch required bandwidth kbps */
6488 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
6489 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
6490 return -EINVAL;
6491 }
6492
6493 dfsFlag = nla_get_u32(
6494 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
6495 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
6496 dfsFlag);
6497
6498 pHddCtx->disable_dfs_flag = dfsFlag;
6499
6500 sme_disable_dfs_channel(hHal, dfsFlag);
6501 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306502
6503 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05306504 return 0;
6505}
Atul Mittal115287b2014-07-08 13:26:33 +05306506
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306507static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
6508 struct wireless_dev *wdev,
6509 const void *data,
6510 int data_len)
6511{
6512 int ret = 0;
6513
6514 vos_ssr_protect(__func__);
6515 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
6516 vos_ssr_unprotect(__func__);
6517
6518 return ret;
6519
6520}
6521
Mukul Sharma2a271632014-10-13 14:59:01 +05306522const struct
6523nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
6524{
6525 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05306526 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
6527 .type = NLA_UNSPEC,
6528 .len = HDD_MAC_ADDR_LEN},
Mukul Sharma2a271632014-10-13 14:59:01 +05306529};
6530
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306531static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05306532 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05306533{
6534
6535 u8 bssid[6] = {0};
6536 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6537 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6538 eHalStatus status = eHAL_STATUS_SUCCESS;
6539 v_U32_t isFwrRoamEnabled = FALSE;
6540 int ret;
6541
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306542 ENTER();
6543
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306544 ret = wlan_hdd_validate_context(pHddCtx);
6545 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306546 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05306547 }
6548
6549 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
6550 data, data_len,
6551 qca_wlan_vendor_attr);
6552 if (ret){
6553 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6554 return -EINVAL;
6555 }
6556
6557 /* Parse and fetch Enable flag */
6558 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
6559 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
6560 return -EINVAL;
6561 }
6562
6563 isFwrRoamEnabled = nla_get_u32(
6564 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
6565
6566 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
6567
6568 /* Parse and fetch bssid */
6569 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
6570 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
6571 return -EINVAL;
6572 }
6573
6574 memcpy(bssid, nla_data(
6575 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
6576 sizeof(bssid));
6577 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
6578
6579 //Update roaming
6580 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306581 if (!HAL_STATUS_SUCCESS(status)) {
6582 hddLog(LOGE,
6583 FL("sme_ConfigFwrRoaming failed (err=%d)"), status);
6584 return -EINVAL;
6585 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306586 EXIT();
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306587 return 0;
Mukul Sharma2a271632014-10-13 14:59:01 +05306588}
6589
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306590static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
6591 struct wireless_dev *wdev, const void *data, int data_len)
6592{
6593 int ret = 0;
6594
6595 vos_ssr_protect(__func__);
6596 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
6597 vos_ssr_unprotect(__func__);
6598
6599 return ret;
6600}
6601
Sushant Kaushik847890c2015-09-28 16:05:17 +05306602static const struct
6603nla_policy
6604qca_wlan_vendor_get_wifi_info_policy[
6605 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
6606 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
6607 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
6608};
6609
6610
6611/**
6612 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6613 * @wiphy: pointer to wireless wiphy structure.
6614 * @wdev: pointer to wireless_dev structure.
6615 * @data: Pointer to the data to be passed via vendor interface
6616 * @data_len:Length of the data to be passed
6617 *
6618 * This is called when wlan driver needs to send wifi driver related info
6619 * (driver/fw version) to the user space application upon request.
6620 *
6621 * Return: Return the Success or Failure code.
6622 */
6623static int __wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6624 struct wireless_dev *wdev,
6625 const void *data, int data_len)
6626{
6627 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6628 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
6629 tSirVersionString version;
6630 uint32 version_len;
6631 uint8 attr;
6632 int status;
6633 struct sk_buff *reply_skb = NULL;
6634
6635 if (VOS_FTM_MODE == hdd_get_conparam()) {
6636 hddLog(LOGE, FL("Command not allowed in FTM mode"));
6637 return -EINVAL;
6638 }
6639
6640 status = wlan_hdd_validate_context(hdd_ctx);
6641 if (0 != status) {
6642 hddLog(LOGE, FL("HDD context is not valid"));
6643 return -EINVAL;
6644 }
6645
6646 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
6647 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
6648 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
6649 return -EINVAL;
6650 }
6651
6652 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
6653 hddLog(LOG1, FL("Rcvd req for Driver version Driver version is %s"),
6654 QWLAN_VERSIONSTR);
6655 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
6656 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
6657 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
6658 hddLog(LOG1, FL("Rcvd req for FW version FW version is %s"),
6659 hdd_ctx->fw_Version);
6660 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
6661 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
6662 } else {
6663 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
6664 return -EINVAL;
6665 }
6666
6667 version_len = strlen(version);
6668 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
6669 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
6670 if (!reply_skb) {
6671 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6672 return -ENOMEM;
6673 }
6674
6675 if (nla_put(reply_skb, attr, version_len, version)) {
6676 hddLog(LOGE, FL("nla put fail"));
6677 kfree_skb(reply_skb);
6678 return -EINVAL;
6679 }
6680
6681 return cfg80211_vendor_cmd_reply(reply_skb);
6682}
6683
6684/**
6685 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6686 * @wiphy: pointer to wireless wiphy structure.
6687 * @wdev: pointer to wireless_dev structure.
6688 * @data: Pointer to the data to be passed via vendor interface
6689 * @data_len:Length of the data to be passed
6690 * @data_len: Length of the data received
6691 *
6692 * This function is used to enable or disable the collection of packet
6693 * statistics from the firmware
6694 *
6695 * Return: 0 on success and errno on failure
6696 */
6697
6698static int
6699wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6700 struct wireless_dev *wdev,
6701 const void *data, int data_len)
6702
6703
6704{
6705 int ret = 0;
6706
6707 vos_ssr_protect(__func__);
6708 ret = __wlan_hdd_cfg80211_get_wifi_info(wiphy,
6709 wdev, data, data_len);
6710 vos_ssr_unprotect(__func__);
6711
6712 return ret;
6713}
6714
6715
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306716/*
6717 * define short names for the global vendor params
6718 * used by __wlan_hdd_cfg80211_monitor_rssi()
6719 */
6720#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX
6721#define PARAM_REQUEST_ID QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID
6722#define PARAM_CONTROL QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL
6723#define PARAM_MIN_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI
6724#define PARAM_MAX_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI
6725
6726/**---------------------------------------------------------------------------
6727
6728 \brief hdd_rssi_monitor_start_done - callback to be executed when rssi
6729 monitor start is completed successfully.
6730
6731 \return - None
6732
6733 --------------------------------------------------------------------------*/
6734void hdd_rssi_monitor_start_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6735{
6736 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6737
6738 if (NULL == pHddCtx)
6739 {
6740 hddLog(VOS_TRACE_LEVEL_ERROR,
6741 "%s: HDD context is NULL",__func__);
6742 return;
6743 }
6744
6745 if (VOS_STATUS_SUCCESS == status)
6746 {
6747 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor start successful"));
6748 }
6749 else
6750 {
6751 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor start not successful"));
6752 }
6753
6754 return;
6755}
6756
6757/**---------------------------------------------------------------------------
6758
6759 \brief hdd_rssi_monitor_stop_done - callback to be executed when rssi monitor
6760 stop is completed successfully.
6761
6762 \return - None
6763
6764 --------------------------------------------------------------------------*/
6765void hdd_rssi_monitor_stop_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6766{
6767 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6768
6769 if (NULL == pHddCtx)
6770 {
6771 hddLog(VOS_TRACE_LEVEL_ERROR,
6772 "%s: HDD context is NULL",__func__);
6773 return;
6774 }
6775
6776 if (VOS_STATUS_SUCCESS == status)
6777 {
6778 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor stop successful"));
6779 }
6780 else
6781 {
6782 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor stop not successful"));
6783 }
6784
6785 return;
6786}
6787
6788/**
6789 * __wlan_hdd_cfg80211_monitor_rssi() - monitor rssi
6790 * @wiphy: Pointer to wireless phy
6791 * @wdev: Pointer to wireless device
6792 * @data: Pointer to data
6793 * @data_len: Data length
6794 *
6795 * Return: 0 on success, negative errno on failure
6796 */
6797
6798static int
6799__wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy,
6800 struct wireless_dev *wdev,
6801 const void *data,
6802 int data_len)
6803{
6804 struct net_device *dev = wdev->netdev;
6805 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6806 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6807 hdd_station_ctx_t *pHddStaCtx;
6808 struct nlattr *tb[PARAM_MAX + 1];
6809 tpSirRssiMonitorReq pReq;
6810 eHalStatus status;
6811 int ret;
6812 uint32_t control;
6813 static const struct nla_policy policy[PARAM_MAX + 1] = {
6814 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6815 [PARAM_CONTROL] = { .type = NLA_U32 },
6816 [PARAM_MIN_RSSI] = { .type = NLA_S8 },
6817 [PARAM_MAX_RSSI] = { .type = NLA_S8 },
6818 };
6819
6820 ENTER();
6821
6822 ret = wlan_hdd_validate_context(hdd_ctx);
6823 if (0 != ret) {
6824 return -EINVAL;
6825 }
6826
6827 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6828 hddLog(LOGE, FL("Not in Connected state!"));
6829 return -ENOTSUPP;
6830 }
6831
6832 if (nla_parse(tb, PARAM_MAX, data, data_len, policy)) {
6833 hddLog(LOGE, FL("Invalid ATTR"));
6834 return -EINVAL;
6835 }
6836
6837 if (!tb[PARAM_REQUEST_ID]) {
6838 hddLog(LOGE, FL("attr request id failed"));
6839 return -EINVAL;
6840 }
6841
6842 if (!tb[PARAM_CONTROL]) {
6843 hddLog(LOGE, FL("attr control failed"));
6844 return -EINVAL;
6845 }
6846
6847 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6848
6849 pReq = vos_mem_malloc(sizeof(tSirRssiMonitorReq));
6850 if(NULL == pReq)
6851 {
6852 hddLog(LOGE,
6853 FL("vos_mem_alloc failed "));
6854 return eHAL_STATUS_FAILED_ALLOC;
6855 }
6856 vos_mem_set(pReq, sizeof(tSirRssiMonitorReq), 0);
6857
6858 pReq->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]);
6859 pReq->sessionId = pAdapter->sessionId;
6860 pReq->rssiMonitorCbContext = hdd_ctx;
6861 control = nla_get_u32(tb[PARAM_CONTROL]);
6862 vos_mem_copy( &pReq->currentBssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
6863
6864 hddLog(LOG1, FL("Request Id: %u Session_id: %d Control: %d"),
6865 pReq->requestId, pReq->sessionId, control);
6866
6867 if (control == QCA_WLAN_RSSI_MONITORING_START) {
6868 if (!tb[PARAM_MIN_RSSI]) {
6869 hddLog(LOGE, FL("attr min rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306870 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306871 }
6872
6873 if (!tb[PARAM_MAX_RSSI]) {
6874 hddLog(LOGE, FL("attr max rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306875 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306876 }
6877
6878 pReq->minRssi = nla_get_s8(tb[PARAM_MIN_RSSI]);
6879 pReq->maxRssi = nla_get_s8(tb[PARAM_MAX_RSSI]);
6880 pReq->rssiMonitorCallback = hdd_rssi_monitor_start_done;
6881
6882 if (!(pReq->minRssi < pReq->maxRssi)) {
6883 hddLog(LOGW, FL("min_rssi: %d must be less than max_rssi: %d"),
6884 pReq->minRssi, pReq->maxRssi);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306885 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306886 }
6887 hddLog(LOG1, FL("Min_rssi: %d Max_rssi: %d"),
6888 pReq->minRssi, pReq->maxRssi);
6889 status = sme_StartRssiMonitoring(hdd_ctx->hHal, pReq);
6890
6891 }
6892 else if (control == QCA_WLAN_RSSI_MONITORING_STOP) {
6893 pReq->rssiMonitorCallback = hdd_rssi_monitor_stop_done;
6894 status = sme_StopRssiMonitoring(hdd_ctx->hHal, pReq);
6895 }
6896 else {
6897 hddLog(LOGE, FL("Invalid control cmd: %d"), control);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306898 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306899 }
6900
6901 if (!HAL_STATUS_SUCCESS(status)) {
6902 hddLog(LOGE,
6903 FL("sme_set_rssi_monitoring failed(err=%d)"), status);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306904 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306905 }
6906
6907 return 0;
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306908fail:
6909 vos_mem_free(pReq);
6910 return -EINVAL;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306911}
6912
6913/*
6914 * done with short names for the global vendor params
6915 * used by __wlan_hdd_cfg80211_monitor_rssi()
6916 */
6917#undef PARAM_MAX
6918#undef PARAM_CONTROL
6919#undef PARAM_REQUEST_ID
6920#undef PARAM_MAX_RSSI
6921#undef PARAM_MIN_RSSI
6922
6923/**
6924 * wlan_hdd_cfg80211_monitor_rssi() - SSR wrapper to rssi monitoring
6925 * @wiphy: wiphy structure pointer
6926 * @wdev: Wireless device structure pointer
6927 * @data: Pointer to the data received
6928 * @data_len: Length of @data
6929 *
6930 * Return: 0 on success; errno on failure
6931 */
6932static int
6933wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, struct wireless_dev *wdev,
6934 const void *data, int data_len)
6935{
6936 int ret;
6937
6938 vos_ssr_protect(__func__);
6939 ret = __wlan_hdd_cfg80211_monitor_rssi(wiphy, wdev, data, data_len);
6940 vos_ssr_unprotect(__func__);
6941
6942 return ret;
6943}
6944
6945/**
6946 * hdd_rssi_threshold_breached_cb() - rssi breached NL event
6947 * @hddctx: HDD context
6948 * @data: rssi breached event data
6949 *
6950 * This function reads the rssi breached event %data and fill in the skb with
6951 * NL attributes and send up the NL event.
6952 * This callback execute in atomic context and must not invoke any
6953 * blocking calls.
6954 *
6955 * Return: none
6956 */
6957void hdd_rssi_threshold_breached_cb(void *hddctx,
6958 struct rssi_breach_event *data)
6959{
6960 hdd_context_t *pHddCtx = (hdd_context_t *)hddctx;
6961 int status;
6962 struct sk_buff *skb;
6963
6964 ENTER();
6965 status = wlan_hdd_validate_context(pHddCtx);
6966
6967 if (0 != status) {
6968 return;
6969 }
6970
6971 if (!data) {
6972 hddLog(LOGE, FL("data is null"));
6973 return;
6974 }
6975
6976 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
6977#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
6978 NULL,
6979#endif
6980 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
6981 QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX,
6982 GFP_KERNEL);
6983
6984 if (!skb) {
6985 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
6986 return;
6987 }
6988
6989 hddLog(LOG1, "Req Id: %u Current rssi: %d",
6990 data->request_id, data->curr_rssi);
6991 hddLog(LOG1, "Current BSSID: "MAC_ADDRESS_STR,
6992 MAC_ADDR_ARRAY(data->curr_bssid.bytes));
6993
6994 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
6995 data->request_id) ||
6996 nla_put(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID,
6997 sizeof(data->curr_bssid), data->curr_bssid.bytes) ||
6998 nla_put_s8(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI,
6999 data->curr_rssi)) {
7000 hddLog(LOGE, FL("nla put fail"));
7001 goto fail;
7002 }
7003
7004 cfg80211_vendor_event(skb, GFP_KERNEL);
7005 return;
7006
7007fail:
7008 kfree_skb(skb);
7009 return;
7010}
7011
7012
7013
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307014/**
7015 * __wlan_hdd_cfg80211_setband() - set band
7016 * @wiphy: Pointer to wireless phy
7017 * @wdev: Pointer to wireless device
7018 * @data: Pointer to data
7019 * @data_len: Data length
7020 *
7021 * Return: 0 on success, negative errno on failure
7022 */
7023static int
7024__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
7025 struct wireless_dev *wdev,
7026 const void *data,
7027 int data_len)
7028{
7029 struct net_device *dev = wdev->netdev;
7030 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7031 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
7032 int ret;
7033 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
7034 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
7035
7036 ENTER();
7037
7038 ret = wlan_hdd_validate_context(hdd_ctx);
7039 if (0 != ret) {
7040 hddLog(LOGE, FL("HDD context is not valid"));
7041 return ret;
7042 }
7043
7044 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7045 policy)) {
7046 hddLog(LOGE, FL("Invalid ATTR"));
7047 return -EINVAL;
7048 }
7049
7050 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
7051 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
7052 return -EINVAL;
7053 }
7054
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05307055 hdd_ctx->isSetBandByNL = TRUE;
7056 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307057 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05307058 hdd_ctx->isSetBandByNL = FALSE;
7059
7060 EXIT();
7061 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307062}
7063
7064/**
7065 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
7066 * @wiphy: wiphy structure pointer
7067 * @wdev: Wireless device structure pointer
7068 * @data: Pointer to the data received
7069 * @data_len: Length of @data
7070 *
7071 * Return: 0 on success; errno on failure
7072 */
7073static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
7074 struct wireless_dev *wdev,
7075 const void *data,
7076 int data_len)
7077{
7078 int ret = 0;
7079
7080 vos_ssr_protect(__func__);
7081 ret = __wlan_hdd_cfg80211_setband(wiphy,
7082 wdev, data, data_len);
7083 vos_ssr_unprotect(__func__);
7084
7085 return ret;
7086}
7087
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307088#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
7089/**
7090 * hdd_map_req_id_to_pattern_id() - map request id to pattern id
7091 * @hdd_ctx: HDD context
7092 * @request_id: [input] request id
7093 * @pattern_id: [output] pattern id
7094 *
7095 * This function loops through request id to pattern id array
7096 * if the slot is available, store the request id and return pattern id
7097 * if entry exists, return the pattern id
7098 *
7099 * Return: 0 on success and errno on failure
7100 */
7101static int hdd_map_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
7102 uint32_t request_id,
7103 uint8_t *pattern_id)
7104{
7105 uint32_t i;
7106
7107 mutex_lock(&hdd_ctx->op_ctx.op_lock);
7108 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
7109 {
7110 if (hdd_ctx->op_ctx.op_table[i].request_id == 0)
7111 {
7112 hdd_ctx->op_ctx.op_table[i].request_id = request_id;
7113 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7114 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7115 return 0;
7116 } else if (hdd_ctx->op_ctx.op_table[i].request_id ==
7117 request_id) {
7118 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7119 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7120 return 0;
7121 }
7122 }
7123 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7124 return -EINVAL;
7125}
7126
7127/**
7128 * hdd_unmap_req_id_to_pattern_id() - unmap request id to pattern id
7129 * @hdd_ctx: HDD context
7130 * @request_id: [input] request id
7131 * @pattern_id: [output] pattern id
7132 *
7133 * This function loops through request id to pattern id array
7134 * reset request id to 0 (slot available again) and
7135 * return pattern id
7136 *
7137 * Return: 0 on success and errno on failure
7138 */
7139static int hdd_unmap_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
7140 uint32_t request_id,
7141 uint8_t *pattern_id)
7142{
7143 uint32_t i;
7144
7145 mutex_lock(&hdd_ctx->op_ctx.op_lock);
7146 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
7147 {
7148 if (hdd_ctx->op_ctx.op_table[i].request_id == request_id)
7149 {
7150 hdd_ctx->op_ctx.op_table[i].request_id = 0;
7151 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7152 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7153 return 0;
7154 }
7155 }
7156 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7157 return -EINVAL;
7158}
7159
7160
7161/*
7162 * define short names for the global vendor params
7163 * used by __wlan_hdd_cfg80211_offloaded_packets()
7164 */
7165#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX
7166#define PARAM_REQUEST_ID \
7167 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID
7168#define PARAM_CONTROL \
7169 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL
7170#define PARAM_IP_PACKET \
7171 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA
7172#define PARAM_SRC_MAC_ADDR \
7173 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR
7174#define PARAM_DST_MAC_ADDR \
7175 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR
7176#define PARAM_PERIOD QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD
7177
7178/**
7179 * wlan_hdd_add_tx_ptrn() - add tx pattern
7180 * @adapter: adapter pointer
7181 * @hdd_ctx: hdd context
7182 * @tb: nl attributes
7183 *
7184 * This function reads the NL attributes and forms a AddTxPtrn message
7185 * posts it to SME.
7186 *
7187 */
7188static int
7189wlan_hdd_add_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
7190 struct nlattr **tb)
7191{
7192 struct sSirAddPeriodicTxPtrn *add_req;
7193 eHalStatus status;
7194 uint32_t request_id, ret, len;
7195 uint8_t pattern_id = 0;
7196 v_MACADDR_t dst_addr;
7197 uint16_t eth_type = htons(ETH_P_IP);
7198
7199 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(adapter)))
7200 {
7201 hddLog(LOGE, FL("Not in Connected state!"));
7202 return -ENOTSUPP;
7203 }
7204
7205 add_req = vos_mem_malloc(sizeof(*add_req));
7206 if (!add_req)
7207 {
7208 hddLog(LOGE, FL("memory allocation failed"));
7209 return -ENOMEM;
7210 }
7211
7212 /* Parse and fetch request Id */
7213 if (!tb[PARAM_REQUEST_ID])
7214 {
7215 hddLog(LOGE, FL("attr request id failed"));
7216 goto fail;
7217 }
7218
7219 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
7220 hddLog(LOG1, FL("Request Id: %u"), request_id);
7221 if (request_id == 0)
7222 {
7223 hddLog(LOGE, FL("request_id cannot be zero"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05307224 goto fail;
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307225 }
7226
7227 if (!tb[PARAM_PERIOD])
7228 {
7229 hddLog(LOGE, FL("attr period failed"));
7230 goto fail;
7231 }
7232 add_req->usPtrnIntervalMs = nla_get_u32(tb[PARAM_PERIOD]);
7233 hddLog(LOG1, FL("Period: %u ms"), add_req->usPtrnIntervalMs);
7234 if (add_req->usPtrnIntervalMs == 0)
7235 {
7236 hddLog(LOGE, FL("Invalid interval zero, return failure"));
7237 goto fail;
7238 }
7239
7240 if (!tb[PARAM_SRC_MAC_ADDR])
7241 {
7242 hddLog(LOGE, FL("attr source mac address failed"));
7243 goto fail;
7244 }
7245 nla_memcpy(add_req->macAddress, tb[PARAM_SRC_MAC_ADDR],
7246 VOS_MAC_ADDR_SIZE);
7247 hddLog(LOG1, "input src mac address: "MAC_ADDRESS_STR,
7248 MAC_ADDR_ARRAY(add_req->macAddress));
7249
7250 if (memcmp(add_req->macAddress, adapter->macAddressCurrent.bytes,
7251 VOS_MAC_ADDR_SIZE))
7252 {
7253 hddLog(LOGE,
7254 FL("input src mac address and connected ap bssid are different"));
7255 goto fail;
7256 }
7257
7258 if (!tb[PARAM_DST_MAC_ADDR])
7259 {
7260 hddLog(LOGE, FL("attr dst mac address failed"));
7261 goto fail;
7262 }
7263 nla_memcpy(dst_addr.bytes, tb[PARAM_DST_MAC_ADDR], VOS_MAC_ADDR_SIZE);
7264 hddLog(LOG1, "input dst mac address: "MAC_ADDRESS_STR,
7265 MAC_ADDR_ARRAY(dst_addr.bytes));
7266
7267 if (!tb[PARAM_IP_PACKET])
7268 {
7269 hddLog(LOGE, FL("attr ip packet failed"));
7270 goto fail;
7271 }
7272 add_req->ucPtrnSize = nla_len(tb[PARAM_IP_PACKET]);
7273 hddLog(LOG1, FL("IP packet len: %u"), add_req->ucPtrnSize);
7274
7275 if (add_req->ucPtrnSize < 0 ||
7276 add_req->ucPtrnSize > (PERIODIC_TX_PTRN_MAX_SIZE -
7277 HDD_ETH_HEADER_LEN))
7278 {
7279 hddLog(LOGE, FL("Invalid IP packet len: %d"),
7280 add_req->ucPtrnSize);
7281 goto fail;
7282 }
7283
7284 len = 0;
7285 vos_mem_copy(&add_req->ucPattern[0], dst_addr.bytes, VOS_MAC_ADDR_SIZE);
7286 len += VOS_MAC_ADDR_SIZE;
7287 vos_mem_copy(&add_req->ucPattern[len], add_req->macAddress,
7288 VOS_MAC_ADDR_SIZE);
7289 len += VOS_MAC_ADDR_SIZE;
7290 vos_mem_copy(&add_req->ucPattern[len], &eth_type, 2);
7291 len += 2;
7292
7293 /*
7294 * This is the IP packet, add 14 bytes Ethernet (802.3) header
7295 * ------------------------------------------------------------
7296 * | 14 bytes Ethernet (802.3) header | IP header and payload |
7297 * ------------------------------------------------------------
7298 */
7299 vos_mem_copy(&add_req->ucPattern[len],
7300 nla_data(tb[PARAM_IP_PACKET]),
7301 add_req->ucPtrnSize);
7302 add_req->ucPtrnSize += len;
7303
7304 VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7305 add_req->ucPattern, add_req->ucPtrnSize);
7306
7307 ret = hdd_map_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
7308 if (ret)
7309 {
7310 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
7311 goto fail;
7312 }
7313 add_req->ucPtrnId = pattern_id;
7314 hddLog(LOG1, FL("pattern id: %d"), add_req->ucPtrnId);
7315
7316 status = sme_AddPeriodicTxPtrn(hdd_ctx->hHal, add_req);
7317 if (!HAL_STATUS_SUCCESS(status))
7318 {
7319 hddLog(LOGE,
7320 FL("sme_AddPeriodicTxPtrn failed (err=%d)"), status);
7321 goto fail;
7322 }
7323
7324 EXIT();
7325 vos_mem_free(add_req);
7326 return 0;
7327
7328fail:
7329 vos_mem_free(add_req);
7330 return -EINVAL;
7331}
7332
7333/**
7334 * wlan_hdd_del_tx_ptrn() - delete tx pattern
7335 * @adapter: adapter pointer
7336 * @hdd_ctx: hdd context
7337 * @tb: nl attributes
7338 *
7339 * This function reads the NL attributes and forms a DelTxPtrn message
7340 * posts it to SME.
7341 *
7342 */
7343static int
7344wlan_hdd_del_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
7345 struct nlattr **tb)
7346{
7347 struct sSirDelPeriodicTxPtrn *del_req;
7348 eHalStatus status;
7349 uint32_t request_id, ret;
7350 uint8_t pattern_id = 0;
7351
7352 /* Parse and fetch request Id */
7353 if (!tb[PARAM_REQUEST_ID])
7354 {
7355 hddLog(LOGE, FL("attr request id failed"));
7356 return -EINVAL;
7357 }
7358 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
7359 if (request_id == 0)
7360 {
7361 hddLog(LOGE, FL("request_id cannot be zero"));
7362 return -EINVAL;
7363 }
7364
7365 ret = hdd_unmap_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
7366 if (ret)
7367 {
7368 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
7369 return -EINVAL;
7370 }
7371
7372 del_req = vos_mem_malloc(sizeof(*del_req));
7373 if (!del_req)
7374 {
7375 hddLog(LOGE, FL("memory allocation failed"));
7376 return -ENOMEM;
7377 }
7378
7379 vos_mem_set(del_req, sizeof(*del_req), 0);
7380 vos_mem_copy(del_req->macAddress, adapter->macAddressCurrent.bytes,
7381 VOS_MAC_ADDR_SIZE);
7382 hddLog(LOG1, MAC_ADDRESS_STR, MAC_ADDR_ARRAY(del_req->macAddress));
7383 del_req->ucPatternIdBitmap |= (0x1 << pattern_id);
7384 hddLog(LOG1, FL("Request Id: %u Pattern id: %d, bitmap %04x"),
7385 request_id, pattern_id, del_req->ucPatternIdBitmap);
7386
7387 status = sme_DelPeriodicTxPtrn(hdd_ctx->hHal, del_req);
7388 if (!HAL_STATUS_SUCCESS(status))
7389 {
7390 hddLog(LOGE,
7391 FL("sme_DelPeriodicTxPtrn failed (err=%d)"), status);
7392 goto fail;
7393 }
7394
7395 EXIT();
7396 vos_mem_free(del_req);
7397 return 0;
7398
7399fail:
7400 vos_mem_free(del_req);
7401 return -EINVAL;
7402}
7403
7404
7405/**
7406 * __wlan_hdd_cfg80211_offloaded_packets() - send offloaded packets
7407 * @wiphy: Pointer to wireless phy
7408 * @wdev: Pointer to wireless device
7409 * @data: Pointer to data
7410 * @data_len: Data length
7411 *
7412 * Return: 0 on success, negative errno on failure
7413 */
7414static int
7415__wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7416 struct wireless_dev *wdev,
7417 const void *data,
7418 int data_len)
7419{
7420 struct net_device *dev = wdev->netdev;
7421 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7422 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7423 struct nlattr *tb[PARAM_MAX + 1];
7424 uint8_t control;
7425 int ret;
7426 static const struct nla_policy policy[PARAM_MAX + 1] =
7427 {
7428 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
7429 [PARAM_CONTROL] = { .type = NLA_U32 },
7430 [PARAM_SRC_MAC_ADDR] = { .type = NLA_BINARY,
7431 .len = VOS_MAC_ADDR_SIZE },
7432 [PARAM_DST_MAC_ADDR] = { .type = NLA_BINARY,
7433 .len = VOS_MAC_ADDR_SIZE },
7434 [PARAM_PERIOD] = { .type = NLA_U32 },
7435 };
7436
7437 ENTER();
7438
7439 ret = wlan_hdd_validate_context(hdd_ctx);
7440 if (0 != ret)
7441 {
7442 hddLog(LOGE, FL("HDD context is not valid"));
7443 return ret;
7444 }
7445
7446 if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN))
7447 {
7448 hddLog(LOGE,
7449 FL("Periodic Tx Pattern Offload feature is not supported in FW!"));
7450 return -ENOTSUPP;
7451 }
7452
7453 if (nla_parse(tb, PARAM_MAX, data, data_len, policy))
7454 {
7455 hddLog(LOGE, FL("Invalid ATTR"));
7456 return -EINVAL;
7457 }
7458
7459 if (!tb[PARAM_CONTROL])
7460 {
7461 hddLog(LOGE, FL("attr control failed"));
7462 return -EINVAL;
7463 }
7464 control = nla_get_u32(tb[PARAM_CONTROL]);
7465 hddLog(LOG1, FL("Control: %d"), control);
7466
7467 if (control == WLAN_START_OFFLOADED_PACKETS)
7468 return wlan_hdd_add_tx_ptrn(adapter, hdd_ctx, tb);
7469 else if (control == WLAN_STOP_OFFLOADED_PACKETS)
7470 return wlan_hdd_del_tx_ptrn(adapter, hdd_ctx, tb);
7471 else
7472 {
7473 hddLog(LOGE, FL("Invalid control: %d"), control);
7474 return -EINVAL;
7475 }
7476}
7477
7478/*
7479 * done with short names for the global vendor params
7480 * used by __wlan_hdd_cfg80211_offloaded_packets()
7481 */
7482#undef PARAM_MAX
7483#undef PARAM_REQUEST_ID
7484#undef PARAM_CONTROL
7485#undef PARAM_IP_PACKET
7486#undef PARAM_SRC_MAC_ADDR
7487#undef PARAM_DST_MAC_ADDR
7488#undef PARAM_PERIOD
7489
7490/**
7491 * wlan_hdd_cfg80211_offloaded_packets() - Wrapper to offload packets
7492 * @wiphy: wiphy structure pointer
7493 * @wdev: Wireless device structure pointer
7494 * @data: Pointer to the data received
7495 * @data_len: Length of @data
7496 *
7497 * Return: 0 on success; errno on failure
7498 */
7499static int wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7500 struct wireless_dev *wdev,
7501 const void *data,
7502 int data_len)
7503{
7504 int ret = 0;
7505
7506 vos_ssr_protect(__func__);
7507 ret = __wlan_hdd_cfg80211_offloaded_packets(wiphy,
7508 wdev, data, data_len);
7509 vos_ssr_unprotect(__func__);
7510
7511 return ret;
7512}
7513#endif
7514
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307515static const struct
7516nla_policy
7517qca_wlan_vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05307518 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
7519 .type = NLA_BINARY,
7520 .len = HDD_MAC_ADDR_LEN},
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307521};
7522
7523/**
7524 * wlan_hdd_cfg80211_get_link_properties() - This function is used to
7525 * get link properties like nss, rate flags and operating frequency for
7526 * the connection with the given peer.
7527 * @wiphy: WIPHY structure pointer
7528 * @wdev: Wireless device structure pointer
7529 * @data: Pointer to the data received
7530 * @data_len: Length of the data received
7531 *
7532 * This function return the above link properties on success.
7533 *
7534 * Return: 0 on success and errno on failure
7535 */
7536static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
7537 struct wireless_dev *wdev,
7538 const void *data,
7539 int data_len)
7540{
7541 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7542 struct net_device *dev = wdev->netdev;
7543 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7544 hdd_station_ctx_t *hdd_sta_ctx;
7545 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX+1];
7546 uint8_t peer_mac[VOS_MAC_ADDR_SIZE];
7547 uint32_t sta_id;
7548 struct sk_buff *reply_skb;
7549 uint32_t rate_flags = 0;
7550 uint8_t nss;
7551 uint8_t final_rate_flags = 0;
7552 uint32_t freq;
7553 v_CONTEXT_t pVosContext = NULL;
7554 ptSapContext pSapCtx = NULL;
7555
7556 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
7557 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
7558 return -EINVAL;
7559 }
7560
7561 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7562 qca_wlan_vendor_attr_policy)) {
7563 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid attribute"));
7564 return -EINVAL;
7565 }
7566
7567 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
7568 hddLog(VOS_TRACE_LEVEL_ERROR,
7569 FL("Attribute peerMac not provided for mode=%d"),
7570 adapter->device_mode);
7571 return -EINVAL;
7572 }
7573
Ashish Kumar Dhanotiyaddaf0482017-06-23 15:22:42 +05307574 if (nla_len(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) < sizeof(peer_mac)) {
7575 hddLog(VOS_TRACE_LEVEL_ERROR,
7576 FL("Attribute peerMac is invalid=%d"),
7577 adapter->device_mode);
7578 return -EINVAL;
7579 }
7580
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307581 memcpy(peer_mac, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
7582 sizeof(peer_mac));
7583 hddLog(VOS_TRACE_LEVEL_INFO,
7584 FL("peerMac="MAC_ADDRESS_STR" for device_mode:%d"),
7585 MAC_ADDR_ARRAY(peer_mac), adapter->device_mode);
7586
7587 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
7588 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
7589 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
7590 if ((hdd_sta_ctx->conn_info.connState !=
7591 eConnectionState_Associated) ||
7592 !vos_mem_compare(hdd_sta_ctx->conn_info.bssId, peer_mac,
7593 VOS_MAC_ADDRESS_LEN)) {
7594 hddLog(VOS_TRACE_LEVEL_ERROR,
7595 FL("Not Associated to mac "MAC_ADDRESS_STR),
7596 MAC_ADDR_ARRAY(peer_mac));
7597 return -EINVAL;
7598 }
7599
7600 nss = 1; //pronto supports only one spatial stream
7601 freq = vos_chan_to_freq(
7602 hdd_sta_ctx->conn_info.operationChannel);
7603 rate_flags = hdd_sta_ctx->conn_info.rate_flags;
7604
7605 } else if (adapter->device_mode == WLAN_HDD_P2P_GO ||
7606 adapter->device_mode == WLAN_HDD_SOFTAP) {
7607
7608 pVosContext = ( WLAN_HDD_GET_CTX(adapter))->pvosContext;
7609 pSapCtx = VOS_GET_SAP_CB(pVosContext);
7610 if(pSapCtx == NULL){
7611 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7612 FL("psapCtx is NULL"));
7613 return -ENOENT;
7614 }
7615
7616
7617 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
7618 if (pSapCtx->aStaInfo[sta_id].isUsed &&
7619 !vos_is_macaddr_broadcast(
7620 &pSapCtx->aStaInfo[sta_id].macAddrSTA) &&
7621 vos_mem_compare(
7622 &pSapCtx->aStaInfo[sta_id].macAddrSTA,
7623 peer_mac, VOS_MAC_ADDRESS_LEN))
7624 break;
7625 }
7626
7627 if (WLAN_MAX_STA_COUNT == sta_id) {
7628 hddLog(VOS_TRACE_LEVEL_ERROR,
7629 FL("No active peer with mac="MAC_ADDRESS_STR),
7630 MAC_ADDR_ARRAY(peer_mac));
7631 return -EINVAL;
7632 }
7633
7634 nss = 1; //pronto supports only one spatial stream
7635 freq = vos_chan_to_freq(
7636 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operatingChannel);
7637 rate_flags = pSapCtx->aStaInfo[sta_id].rate_flags;
7638 } else {
7639 hddLog(VOS_TRACE_LEVEL_ERROR,
7640 FL("Not Associated! with mac"MAC_ADDRESS_STR),
7641 MAC_ADDR_ARRAY(peer_mac));
7642 return -EINVAL;
7643 }
7644
7645 if (!(rate_flags & eHAL_TX_RATE_LEGACY)) {
7646 if (rate_flags & eHAL_TX_RATE_VHT80) {
7647 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7648 final_rate_flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
7649 } else if (rate_flags & eHAL_TX_RATE_VHT40) {
7650 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7651 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7652 } else if (rate_flags & eHAL_TX_RATE_VHT20) {
7653 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7654 } else if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40)) {
7655 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7656 if (rate_flags & eHAL_TX_RATE_HT40)
7657 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7658 }
7659
7660 if (rate_flags & eHAL_TX_RATE_SGI) {
7661 if (!(final_rate_flags & RATE_INFO_FLAGS_VHT_MCS))
7662 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7663 final_rate_flags |= RATE_INFO_FLAGS_SHORT_GI;
7664 }
7665 }
7666
7667 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7668 sizeof(u8) + sizeof(u8) + sizeof(u32) + NLMSG_HDRLEN);
7669
7670 if (NULL == reply_skb) {
7671 hddLog(VOS_TRACE_LEVEL_ERROR,
7672 FL("getLinkProperties: skb alloc failed"));
7673 return -EINVAL;
7674 }
7675
7676 if (nla_put_u8(reply_skb,
7677 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS,
7678 nss) ||
7679 nla_put_u8(reply_skb,
7680 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS,
7681 final_rate_flags) ||
7682 nla_put_u32(reply_skb,
7683 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ,
7684 freq)) {
7685 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_put failed"));
7686 kfree_skb(reply_skb);
7687 return -EINVAL;
7688 }
7689
7690 return cfg80211_vendor_cmd_reply(reply_skb);
7691}
7692
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307693#define BEACON_MISS_THRESH_2_4 \
7694 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24
7695#define BEACON_MISS_THRESH_5_0 \
7696 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307697#define PARAM_WIFICONFIG_MAX QCA_WLAN_VENDOR_ATTR_CONFIG_MAX
7698#define PARAM_MODULATED_DTIM QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM
7699#define PARAM_STATS_AVG_FACTOR QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR
7700#define PARAM_GUARD_TIME QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307701#define PARAM_BCNMISS_PENALTY_PARAM_COUNT \
7702 QCA_WLAN_VENDOR_ATTR_CONFIG_PENALIZE_AFTER_NCONS_BEACON_MISS
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307703
7704/**
7705 * __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7706 * vendor command
7707 *
7708 * @wiphy: wiphy device pointer
7709 * @wdev: wireless device pointer
7710 * @data: Vendor command data buffer
7711 * @data_len: Buffer length
7712 *
7713 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7714 *
7715 * Return: EOK or other error codes.
7716 */
7717
7718static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7719 struct wireless_dev *wdev,
7720 const void *data,
7721 int data_len)
7722{
7723 struct net_device *dev = wdev->netdev;
7724 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7725 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7726 hdd_station_ctx_t *pHddStaCtx;
7727 struct nlattr *tb[PARAM_WIFICONFIG_MAX + 1];
7728 tpSetWifiConfigParams pReq;
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307729 tModifyRoamParamsReqParams modifyRoamParamsReq;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307730 eHalStatus status;
7731 int ret_val;
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307732 uint8_t hb_thresh_val;
7733
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307734 static const struct nla_policy policy[PARAM_WIFICONFIG_MAX + 1] = {
7735 [PARAM_STATS_AVG_FACTOR] = { .type = NLA_U16 },
7736 [PARAM_MODULATED_DTIM] = { .type = NLA_U32 },
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307737 [PARAM_GUARD_TIME] = { .type = NLA_U32},
7738 [PARAM_BCNMISS_PENALTY_PARAM_COUNT] =
7739 { .type = NLA_U32},
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307740 [BEACON_MISS_THRESH_2_4] = { .type = NLA_U8 },
7741 [BEACON_MISS_THRESH_5_0] = { .type = NLA_U8 },
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307742 };
7743
7744 ENTER();
7745
7746 if (VOS_FTM_MODE == hdd_get_conparam()) {
7747 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7748 return -EINVAL;
7749 }
7750
7751 ret_val = wlan_hdd_validate_context(pHddCtx);
7752 if (ret_val) {
7753 return ret_val;
7754 }
7755
7756 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7757
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307758 if (nla_parse(tb, PARAM_WIFICONFIG_MAX, data, data_len, policy)) {
7759 hddLog(LOGE, FL("Invalid ATTR"));
7760 return -EINVAL;
7761 }
7762
7763 /* check the Wifi Capability */
7764 if ( (TRUE != pHddCtx->cfg_ini->fEnableWifiConfig) &&
7765 (TRUE != sme_IsFeatureSupportedByFW(WIFI_CONFIG)))
7766 {
7767 hddLog(VOS_TRACE_LEVEL_ERROR,
7768 FL("WIFICONFIG not supported by Firmware"));
7769 return -EINVAL;
7770 }
7771
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307772 if (tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]) {
7773 modifyRoamParamsReq.param = WIFI_CONFIG_SET_BCNMISS_PENALTY_COUNT;
7774 modifyRoamParamsReq.value =
7775 nla_get_u32(tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]);
7776
7777 if (eHAL_STATUS_SUCCESS !=
7778 sme_setBcnMissPenaltyCount(pHddCtx->hHal,&modifyRoamParamsReq))
7779 {
7780 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed", __func__);
7781 ret_val = -EINVAL;
7782 }
7783 return ret_val;
7784 }
7785
7786 /* Moved this down in order to provide provision to set beacon
7787 * miss penalty count irrespective of connection state.
7788 */
7789 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
7790 hddLog(LOGE, FL("Not in Connected state!"));
7791 return -ENOTSUPP;
7792 }
7793
7794 pReq = vos_mem_malloc(sizeof(tSetWifiConfigParams));
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307795
7796 if (!pReq) {
7797 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7798 "%s: Not able to allocate memory for tSetWifiConfigParams",
7799 __func__);
7800 return eHAL_STATUS_E_MALLOC_FAILED;
7801 }
7802
7803 vos_mem_set(pReq, sizeof(tSetWifiConfigParams), 0);
7804
7805 pReq->sessionId = pAdapter->sessionId;
7806 vos_mem_copy( &pReq->bssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
7807
7808 if (tb[PARAM_MODULATED_DTIM]) {
7809 pReq->paramValue = nla_get_u32(
7810 tb[PARAM_MODULATED_DTIM]);
7811 hddLog(LOG1, FL("Modulated DTIM: pReq->paramValue:%d "),
7812 pReq->paramValue);
Arun Khandavalli876886f2015-11-23 11:42:27 +05307813 pHddCtx->cfg_ini->enableDynamicDTIM = pReq->paramValue;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307814 hdd_set_pwrparams(pHddCtx);
7815 if (BMPS == pmcGetPmcState(pHddCtx->hHal)) {
7816 hddLog( LOG1, FL("WifiConfig: Requesting FullPower!"));
7817
7818 sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
7819 iw_full_power_cbfn, pAdapter,
7820 eSME_FULL_PWR_NEEDED_BY_HDD);
7821 }
7822 else
7823 {
7824 hddLog( LOG1, FL("WifiConfig Not in BMPS state"));
7825 }
7826 }
7827
7828 if (tb[PARAM_STATS_AVG_FACTOR]) {
7829 pReq->paramType = WIFI_CONFIG_SET_AVG_STATS_FACTOR;
7830 pReq->paramValue = nla_get_u16(
7831 tb[PARAM_STATS_AVG_FACTOR]);
7832 hddLog(LOG1, FL("AVG_STATS_FACTOR pReq->paramType:%d,pReq->paramValue:%d "),
7833 pReq->paramType, pReq->paramValue);
7834 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7835
7836 if (eHAL_STATUS_SUCCESS != status)
7837 {
7838 vos_mem_free(pReq);
7839 pReq = NULL;
7840 ret_val = -EPERM;
7841 return ret_val;
7842 }
7843 }
7844
7845
7846 if (tb[PARAM_GUARD_TIME]) {
7847 pReq->paramType = WIFI_CONFIG_SET_GUARD_TIME;
7848 pReq->paramValue = nla_get_u32(
7849 tb[PARAM_GUARD_TIME]);
7850 hddLog(LOG1, FL("GUARD_TIME pReq->paramType:%d,pReq->paramValue:%d "),
7851 pReq->paramType, pReq->paramValue);
7852 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7853
7854 if (eHAL_STATUS_SUCCESS != status)
7855 {
7856 vos_mem_free(pReq);
7857 pReq = NULL;
7858 ret_val = -EPERM;
7859 return ret_val;
7860 }
7861
7862 }
7863
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307864 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]) {
7865 hb_thresh_val = nla_get_u8(
7866 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]);
7867
7868 hddLog(LOG1, "WLAN set heartbeat threshold for 2.4Ghz %d",
7869 hb_thresh_val);
7870 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7871 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
7872 NULL, eANI_BOOLEAN_FALSE);
7873
7874 status = sme_update_hb_threshold(
7875 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
7876 WNI_CFG_HEART_BEAT_THRESHOLD,
7877 hb_thresh_val, eCSR_BAND_24);
7878 if (eHAL_STATUS_SUCCESS != status) {
7879 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
7880 vos_mem_free(pReq);
7881 pReq = NULL;
7882 return -EPERM;
7883 }
7884 }
7885
7886 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]) {
7887 hb_thresh_val = nla_get_u8(
7888 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]);
7889
7890 hddLog(LOG1, "WLAN set heartbeat threshold for 5Ghz %d",
7891 hb_thresh_val);
7892 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7893 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
7894 NULL, eANI_BOOLEAN_FALSE);
7895
7896 status = sme_update_hb_threshold(
7897 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
7898 WNI_CFG_HEART_BEAT_THRESHOLD,
7899 hb_thresh_val, eCSR_BAND_5G);
7900 if (eHAL_STATUS_SUCCESS != status) {
7901 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
7902 vos_mem_free(pReq);
7903 pReq = NULL;
7904 return -EPERM;
7905 }
7906 }
7907
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307908 EXIT();
7909 return ret_val;
7910}
7911
7912/**
7913 * wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7914 * vendor command
7915 *
7916 * @wiphy: wiphy device pointer
7917 * @wdev: wireless device pointer
7918 * @data: Vendor command data buffer
7919 * @data_len: Buffer length
7920 *
7921 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7922 *
7923 * Return: EOK or other error codes.
7924 */
7925static int wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7926 struct wireless_dev *wdev,
7927 const void *data,
7928 int data_len)
7929{
7930 int ret;
7931
7932 vos_ssr_protect(__func__);
7933 ret = __wlan_hdd_cfg80211_wifi_configuration_set(wiphy, wdev,
7934 data, data_len);
7935 vos_ssr_unprotect(__func__);
7936
7937 return ret;
7938}
Anurag Chouhan6ee81542017-02-09 18:09:27 +05307939
7940/*
7941 * define short names for the global vendor params
7942 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
7943 */
7944#define STATS_SET_INVALID \
7945 QCA_ATTR_NUD_STATS_SET_INVALID
7946#define STATS_SET_START \
7947 QCA_ATTR_NUD_STATS_SET_START
7948#define STATS_GW_IPV4 \
7949 QCA_ATTR_NUD_STATS_GW_IPV4
7950#define STATS_SET_MAX \
7951 QCA_ATTR_NUD_STATS_SET_MAX
7952
7953const struct nla_policy
7954qca_wlan_vendor_set_nud_stats[STATS_SET_MAX +1] =
7955{
7956 [STATS_SET_START] = {.type = NLA_FLAG },
7957 [STATS_GW_IPV4] = {.type = NLA_U32 },
7958};
7959
7960/**
7961 * hdd_set_nud_stats_cb() - hdd callback api to get status
7962 * @data: pointer to adapter
7963 * @rsp: status
7964 *
7965 * Return: None
7966 */
7967static void hdd_set_nud_stats_cb(void *data, VOS_STATUS rsp)
7968{
7969
7970 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
7971
7972 if (NULL == adapter)
7973 return;
7974
7975 if (VOS_STATUS_SUCCESS == rsp) {
7976 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7977 "%s success received STATS_SET_START", __func__);
7978 } else {
7979 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7980 "%s STATS_SET_START Failed!!", __func__);
7981 }
7982 return;
7983}
7984
7985/**
7986 * __wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
7987 * @wiphy: pointer to wireless wiphy structure.
7988 * @wdev: pointer to wireless_dev structure.
7989 * @data: pointer to apfind configuration data.
7990 * @data_len: the length in byte of apfind data.
7991 *
7992 * This is called when wlan driver needs to send arp stats to
7993 * firmware.
7994 *
7995 * Return: An error code or 0 on success.
7996 */
7997static int __wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
7998 struct wireless_dev *wdev,
7999 const void *data, int data_len)
8000{
8001 struct nlattr *tb[STATS_SET_MAX + 1];
8002 struct net_device *dev = wdev->netdev;
8003 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8004 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05308005 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308006 setArpStatsParams arp_stats_params;
8007 int err = 0;
8008
8009 ENTER();
8010
8011 err = wlan_hdd_validate_context(hdd_ctx);
8012 if (0 != err)
8013 return err;
8014
8015 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
8016 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8017 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
8018 return -EINVAL;
8019 }
8020
8021 err = nla_parse(tb, STATS_SET_MAX, data, data_len,
8022 qca_wlan_vendor_set_nud_stats);
8023 if (err)
8024 {
8025 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8026 "%s STATS_SET_START ATTR", __func__);
8027 return err;
8028 }
8029
8030 if (tb[STATS_SET_START])
8031 {
8032 if (!tb[STATS_GW_IPV4]) {
8033 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8034 "%s STATS_SET_START CMD", __func__);
8035 return -EINVAL;
8036 }
8037 arp_stats_params.flag = true;
8038 arp_stats_params.ip_addr = nla_get_u32(tb[STATS_GW_IPV4]);
8039 } else {
8040 arp_stats_params.flag = false;
8041 }
Anurag Chouhan630c5562017-03-23 14:51:47 +05308042 if (arp_stats_params.flag)
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308043 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8044 "%s STATS_SET_START Cleared!!", __func__);
Anurag Chouhan630c5562017-03-23 14:51:47 +05308045 vos_mem_zero(&adapter->hdd_stats.hddArpStats,
8046 sizeof(adapter->hdd_stats.hddArpStats));
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308047
8048 arp_stats_params.pkt_type = 1; // ARP packet type
8049
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05308050 if (arp_stats_params.flag) {
8051 hdd_ctx->track_arp_ip = arp_stats_params.ip_addr;
8052 WLANTL_SetARPFWDatapath(pVosContext, true);
8053 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8054 "%s Set FW in data path for ARP with tgt IP :%d",
8055 __func__, hdd_ctx->track_arp_ip);
8056 }
8057 else {
8058 WLANTL_SetARPFWDatapath(pVosContext, false);
8059 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8060 "%s Remove FW from data path", __func__);
8061 }
8062
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308063 arp_stats_params.rsp_cb_fn = hdd_set_nud_stats_cb;
8064 arp_stats_params.data_ctx = adapter;
8065
8066 if (eHAL_STATUS_SUCCESS !=
8067 sme_set_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
8068 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8069 "%s STATS_SET_START CMD Failed!!", __func__);
8070 return -EINVAL;
8071 }
8072
8073 EXIT();
8074
8075 return err;
8076}
8077
8078/**
8079 * wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
8080 * @wiphy: pointer to wireless wiphy structure.
8081 * @wdev: pointer to wireless_dev structure.
8082 * @data: pointer to apfind configuration data.
8083 * @data_len: the length in byte of apfind data.
8084 *
8085 * This is called when wlan driver needs to send arp stats to
8086 * firmware.
8087 *
8088 * Return: An error code or 0 on success.
8089 */
8090static int wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
8091 struct wireless_dev *wdev,
8092 const void *data, int data_len)
8093{
8094 int ret;
8095
8096 vos_ssr_protect(__func__);
8097 ret = __wlan_hdd_cfg80211_set_nud_stats(wiphy, wdev, data, data_len);
8098 vos_ssr_unprotect(__func__);
8099
8100 return ret;
8101}
8102#undef STATS_SET_INVALID
8103#undef STATS_SET_START
8104#undef STATS_GW_IPV4
8105#undef STATS_SET_MAX
8106
8107/*
8108 * define short names for the global vendor params
8109 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
8110 */
8111#define STATS_GET_INVALID \
8112 QCA_ATTR_NUD_STATS_SET_INVALID
8113#define COUNT_FROM_NETDEV \
8114 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
8115#define COUNT_TO_LOWER_MAC \
8116 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
8117#define RX_COUNT_BY_LOWER_MAC \
8118 QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
8119#define COUNT_TX_SUCCESS \
8120 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
8121#define RSP_RX_COUNT_BY_LOWER_MAC \
8122 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
8123#define RSP_RX_COUNT_BY_UPPER_MAC \
8124 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
8125#define RSP_COUNT_TO_NETDEV \
8126 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
8127#define RSP_COUNT_OUT_OF_ORDER_DROP \
8128 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
8129#define AP_LINK_ACTIVE \
8130 QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
8131#define AP_LINK_DAD \
8132 QCA_ATTR_NUD_STATS_AP_LINK_DAD
8133#define STATS_GET_MAX \
8134 QCA_ATTR_NUD_STATS_GET_MAX
8135
8136const struct nla_policy
8137qca_wlan_vendor_get_nud_stats[STATS_GET_MAX +1] =
8138{
8139 [COUNT_FROM_NETDEV] = {.type = NLA_U16 },
8140 [COUNT_TO_LOWER_MAC] = {.type = NLA_U16 },
8141 [RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
8142 [COUNT_TX_SUCCESS] = {.type = NLA_U16 },
8143 [RSP_RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
8144 [RSP_RX_COUNT_BY_UPPER_MAC] = {.type = NLA_U16 },
8145 [RSP_COUNT_TO_NETDEV] = {.type = NLA_U16 },
8146 [RSP_COUNT_OUT_OF_ORDER_DROP] = {.type = NLA_U16 },
8147 [AP_LINK_ACTIVE] = {.type = NLA_FLAG },
8148 [AP_LINK_DAD] = {.type = NLA_FLAG },
8149};
8150
8151static void hdd_get_nud_stats_cb(void *data, rsp_stats *rsp)
8152{
8153
8154 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
8155 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
8156 struct hdd_nud_stats_context *context;
8157 int status;
8158
8159 ENTER();
8160
8161 if (NULL == adapter)
8162 return;
8163
8164 status = wlan_hdd_validate_context(hdd_ctx);
8165 if (0 != status) {
8166 return;
8167 }
8168
8169 if (!rsp) {
8170 hddLog(LOGE, FL("data is null"));
8171 return;
8172 }
8173
8174 adapter->hdd_stats.hddArpStats.tx_fw_cnt = rsp->tx_fw_cnt;
8175 adapter->hdd_stats.hddArpStats.rx_fw_cnt = rsp->rx_fw_cnt;
8176 adapter->hdd_stats.hddArpStats.tx_ack_cnt = rsp->tx_ack_cnt;
8177 adapter->dad |= rsp->dad;
8178
8179 spin_lock(&hdd_context_lock);
8180 context = &hdd_ctx->nud_stats_context;
8181 complete(&context->response_event);
8182 spin_unlock(&hdd_context_lock);
8183
8184 return;
8185}
8186static int __wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
8187 struct wireless_dev *wdev,
8188 const void *data, int data_len)
8189{
8190 int err = 0;
8191 unsigned long rc;
8192 struct hdd_nud_stats_context *context;
8193 struct net_device *dev = wdev->netdev;
8194 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8195 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8196 getArpStatsParams arp_stats_params;
8197 struct sk_buff *skb;
8198
8199 ENTER();
8200
8201 err = wlan_hdd_validate_context(hdd_ctx);
8202 if (0 != err)
8203 return err;
8204
8205 arp_stats_params.pkt_type = WLAN_NUD_STATS_ARP_PKT_TYPE;
8206 arp_stats_params.get_rsp_cb_fn = hdd_get_nud_stats_cb;
8207 arp_stats_params.data_ctx = adapter;
8208
8209 spin_lock(&hdd_context_lock);
8210 context = &hdd_ctx->nud_stats_context;
8211 INIT_COMPLETION(context->response_event);
8212 spin_unlock(&hdd_context_lock);
8213
8214 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
8215 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8216 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
8217 return -EINVAL;
8218 }
8219
8220 if (eHAL_STATUS_SUCCESS !=
8221 sme_get_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
8222 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8223 "%s STATS_SET_START CMD Failed!!", __func__);
8224 return -EINVAL;
8225 }
8226
8227 rc = wait_for_completion_timeout(&context->response_event,
8228 msecs_to_jiffies(WLAN_WAIT_TIME_NUD_STATS));
8229 if (!rc)
8230 {
8231 hddLog(LOGE,
8232 FL("Target response timed out request "));
8233 return -ETIMEDOUT;
8234 }
8235
8236 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
8237 WLAN_NUD_STATS_LEN);
8238 if (!skb)
8239 {
8240 hddLog(VOS_TRACE_LEVEL_ERROR,
8241 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
8242 __func__);
8243 return -ENOMEM;
8244 }
8245
8246 if (nla_put_u16(skb, COUNT_FROM_NETDEV,
8247 adapter->hdd_stats.hddArpStats.txCount) ||
8248 nla_put_u16(skb, COUNT_TO_LOWER_MAC,
8249 adapter->hdd_stats.hddArpStats.tx_host_fw_sent) ||
8250 nla_put_u16(skb, RX_COUNT_BY_LOWER_MAC,
8251 adapter->hdd_stats.hddArpStats.tx_fw_cnt) ||
8252 nla_put_u16(skb, COUNT_TX_SUCCESS,
8253 adapter->hdd_stats.hddArpStats.tx_ack_cnt) ||
8254 nla_put_u16(skb, RSP_RX_COUNT_BY_LOWER_MAC,
8255 adapter->hdd_stats.hddArpStats.rx_fw_cnt) ||
8256 nla_put_u16(skb, RSP_RX_COUNT_BY_UPPER_MAC,
8257 adapter->hdd_stats.hddArpStats.rxCount) ||
8258 nla_put_u16(skb, RSP_COUNT_TO_NETDEV,
8259 adapter->hdd_stats.hddArpStats.rxDelivered) ||
8260 nla_put_u16(skb, RSP_COUNT_OUT_OF_ORDER_DROP,
8261 adapter->hdd_stats.hddArpStats.rx_host_drop_reorder)) {
8262 hddLog(LOGE, FL("nla put fail"));
8263 kfree_skb(skb);
8264 return -EINVAL;
8265 }
8266 if (adapter->con_status)
8267 nla_put_flag(skb, AP_LINK_ACTIVE);
8268 if (adapter->dad)
8269 nla_put_flag(skb, AP_LINK_DAD);
8270
8271 cfg80211_vendor_cmd_reply(skb);
8272 return err;
8273}
8274
8275static int wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
8276 struct wireless_dev *wdev,
8277 const void *data, int data_len)
8278{
8279 int ret;
8280
8281 vos_ssr_protect(__func__);
8282 ret = __wlan_hdd_cfg80211_get_nud_stats(wiphy, wdev, data, data_len);
8283 vos_ssr_unprotect(__func__);
8284
8285 return ret;
8286}
8287
8288#undef QCA_ATTR_NUD_STATS_SET_INVALID
8289#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
8290#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
8291#undef QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
8292#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
8293#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
8294#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
8295#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
8296#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
8297#undef QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
8298#undef QCA_ATTR_NUD_STATS_GET_MAX
8299
8300
8301
Kapil Guptaee33bf12016-12-20 18:27:37 +05308302#ifdef WLAN_FEATURE_APFIND
8303/**
8304 * __wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
8305 * @wiphy: pointer to wireless wiphy structure.
8306 * @wdev: pointer to wireless_dev structure.
8307 * @data: pointer to apfind configuration data.
8308 * @data_len: the length in byte of apfind data.
8309 *
8310 * This is called when wlan driver needs to send APFIND configurations to
8311 * firmware.
8312 *
8313 * Return: An error code or 0 on success.
8314 */
8315static int __wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
8316 struct wireless_dev *wdev,
8317 const void *data, int data_len)
8318{
8319 struct sme_ap_find_request_req apfind_req;
8320 VOS_STATUS status;
8321 int ret_val;
8322 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8323
8324 ENTER();
8325
8326 ret_val = wlan_hdd_validate_context(hdd_ctx);
8327 if (ret_val)
8328 return ret_val;
8329
8330 if (VOS_FTM_MODE == hdd_get_conparam()) {
8331 hddLog(LOGE, FL("Command not allowed in FTM mode"));
8332 return -EPERM;
8333 }
8334
8335 apfind_req.request_data_len = data_len;
8336 apfind_req.request_data = data;
8337
8338 status = sme_apfind_set_cmd(&apfind_req);
8339 if (VOS_STATUS_SUCCESS != status) {
8340 ret_val = -EIO;
8341 }
8342 return ret_val;
8343}
8344
8345/**
8346 * wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
8347 * @wiphy: pointer to wireless wiphy structure.
8348 * @wdev: pointer to wireless_dev structure.
8349 * @data: pointer to apfind configuration data.
8350 * @data_len: the length in byte of apfind data.
8351 *
8352 * This is called when wlan driver needs to send APFIND configurations to
8353 * firmware.
8354 *
8355 * Return: An error code or 0 on success.
8356 */
8357static int wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
8358 struct wireless_dev *wdev,
8359 const void *data, int data_len)
8360{
8361 int ret;
8362
8363 vos_ssr_protect(__func__);
8364 ret = __wlan_hdd_cfg80211_apfind_cmd(wiphy, wdev, data, data_len);
8365 vos_ssr_unprotect(__func__);
8366
8367 return ret;
8368}
8369#endif /* WLAN_FEATURE_APFIND */
Sunil Duttc69bccb2014-05-26 21:30:20 +05308370const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
8371{
Mukul Sharma2a271632014-10-13 14:59:01 +05308372 {
8373 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8374 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
8375 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8376 WIPHY_VENDOR_CMD_NEED_NETDEV |
8377 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308378 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05308379 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05308380
8381 {
8382 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8383 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
8384 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8385 WIPHY_VENDOR_CMD_NEED_NETDEV |
8386 WIPHY_VENDOR_CMD_NEED_RUNNING,
8387 .doit = wlan_hdd_cfg80211_nan_request
8388 },
8389
Sunil Duttc69bccb2014-05-26 21:30:20 +05308390#ifdef WLAN_FEATURE_LINK_LAYER_STATS
8391 {
8392 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8393 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
8394 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8395 WIPHY_VENDOR_CMD_NEED_NETDEV |
8396 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308397 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05308398 },
8399
8400 {
8401 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8402 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
8403 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8404 WIPHY_VENDOR_CMD_NEED_NETDEV |
8405 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308406 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05308407 },
8408
8409 {
8410 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8411 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
8412 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8413 WIPHY_VENDOR_CMD_NEED_NETDEV |
8414 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308415 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05308416 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308417#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308418#ifdef WLAN_FEATURE_EXTSCAN
8419 {
8420 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8421 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
8422 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8423 WIPHY_VENDOR_CMD_NEED_NETDEV |
8424 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308425 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05308426 },
8427 {
8428 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8429 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
8430 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8431 WIPHY_VENDOR_CMD_NEED_NETDEV |
8432 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308433 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05308434 },
8435 {
8436 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8437 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
8438 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8439 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308440 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05308441 },
8442 {
8443 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8444 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
8445 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8446 WIPHY_VENDOR_CMD_NEED_NETDEV |
8447 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308448 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05308449 },
8450 {
8451 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8452 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
8453 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8454 WIPHY_VENDOR_CMD_NEED_NETDEV |
8455 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308456 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05308457 },
8458 {
8459 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8460 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
8461 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8462 WIPHY_VENDOR_CMD_NEED_NETDEV |
8463 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308464 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308465 },
8466 {
8467 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8468 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
8469 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8470 WIPHY_VENDOR_CMD_NEED_NETDEV |
8471 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308472 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308473 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308474#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308475/*EXT TDLS*/
8476 {
8477 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8478 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
8479 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8480 WIPHY_VENDOR_CMD_NEED_NETDEV |
8481 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308482 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05308483 },
8484 {
8485 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8486 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
8487 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8488 WIPHY_VENDOR_CMD_NEED_NETDEV |
8489 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308490 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05308491 },
8492 {
8493 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8494 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
8495 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8496 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308497 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05308498 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05308499 {
8500 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8501 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
8502 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8503 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308504 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05308505 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05308506 {
8507 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8508 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
8509 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8510 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308511 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05308512 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308513 {
8514 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8515 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
8516 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8517 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308518 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308519 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308520 {
8521 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8522 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
8523 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8524 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308525 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308526 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308527 {
8528 .info.vendor_id = QCA_NL80211_VENDOR_ID,
c_manjeecfd1efb2015-09-25 19:32:34 +05308529 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
8530 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8531 WIPHY_VENDOR_CMD_NEED_NETDEV |
8532 WIPHY_VENDOR_CMD_NEED_RUNNING,
8533 .doit = wlan_hdd_cfg80211_get_fw_mem_dump
8534 },
8535 {
8536 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308537 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
8538 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8539 WIPHY_VENDOR_CMD_NEED_NETDEV |
8540 WIPHY_VENDOR_CMD_NEED_RUNNING,
8541 .doit = wlan_hdd_cfg80211_setband
Sushant Kaushik8e644982015-09-23 12:18:54 +05308542 },
8543 {
8544 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8545 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
8546 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8547 WIPHY_VENDOR_CMD_NEED_NETDEV,
8548 .doit = wlan_hdd_cfg80211_wifi_logger_start
8549 },
Sushant Kaushik847890c2015-09-28 16:05:17 +05308550 {
8551 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8552 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
8553 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8554 WIPHY_VENDOR_CMD_NEED_NETDEV|
8555 WIPHY_VENDOR_CMD_NEED_RUNNING,
8556 .doit = wlan_hdd_cfg80211_get_wifi_info
Sachin Ahujac08f72a2015-09-22 15:25:47 +05308557 },
8558 {
8559 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8560 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
8561 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8562 WIPHY_VENDOR_CMD_NEED_NETDEV |
8563 WIPHY_VENDOR_CMD_NEED_RUNNING,
8564 .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308565 },
8566 {
8567 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8568 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,
8569 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8570 WIPHY_VENDOR_CMD_NEED_NETDEV |
8571 WIPHY_VENDOR_CMD_NEED_RUNNING,
8572 .doit = wlan_hdd_cfg80211_monitor_rssi
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308573 },
8574#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
8575 {
8576 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8577 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS,
8578 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8579 WIPHY_VENDOR_CMD_NEED_NETDEV |
8580 WIPHY_VENDOR_CMD_NEED_RUNNING,
8581 .doit = wlan_hdd_cfg80211_offloaded_packets
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308582 },
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308583#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308584 {
8585 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8586 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
8587 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8588 WIPHY_VENDOR_CMD_NEED_NETDEV |
8589 WIPHY_VENDOR_CMD_NEED_RUNNING,
8590 .doit = wlan_hdd_cfg80211_get_link_properties
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05308591 },
8592 {
8593 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8594 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION,
8595 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8596 WIPHY_VENDOR_CMD_NEED_NETDEV |
8597 WIPHY_VENDOR_CMD_NEED_RUNNING,
8598 .doit = wlan_hdd_cfg80211_wifi_configuration_set
Kapil Guptaee33bf12016-12-20 18:27:37 +05308599 },
8600#ifdef WLAN_FEATURE_APFIND
8601 {
8602 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8603 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_APFIND,
8604 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8605 WIPHY_VENDOR_CMD_NEED_NETDEV,
8606 .doit = wlan_hdd_cfg80211_apfind_cmd
8607 },
8608#endif /* WLAN_FEATURE_APFIND */
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308609 {
8610 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8611 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET,
8612 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8613 WIPHY_VENDOR_CMD_NEED_NETDEV |
8614 WIPHY_VENDOR_CMD_NEED_RUNNING,
8615 .doit = wlan_hdd_cfg80211_set_nud_stats
8616 },
8617 {
8618 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8619 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8620 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8621 WIPHY_VENDOR_CMD_NEED_NETDEV |
8622 WIPHY_VENDOR_CMD_NEED_RUNNING,
8623 .doit = wlan_hdd_cfg80211_get_nud_stats
8624 },
Anurag Chouhanfcd20172017-07-19 17:25:19 +05308625 {
8626 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8627 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_STATION,
8628 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8629 WIPHY_VENDOR_CMD_NEED_NETDEV |
8630 WIPHY_VENDOR_CMD_NEED_RUNNING,
8631 .doit = hdd_cfg80211_get_station_cmd
8632 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308633};
8634
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008635/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05308636static const
8637struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008638{
8639#ifdef FEATURE_WLAN_CH_AVOID
8640 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05308641 .vendor_id = QCA_NL80211_VENDOR_ID,
8642 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008643 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308644#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
8645#ifdef WLAN_FEATURE_LINK_LAYER_STATS
8646 {
8647 /* Index = 1*/
8648 .vendor_id = QCA_NL80211_VENDOR_ID,
8649 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
8650 },
8651 {
8652 /* Index = 2*/
8653 .vendor_id = QCA_NL80211_VENDOR_ID,
8654 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
8655 },
8656 {
8657 /* Index = 3*/
8658 .vendor_id = QCA_NL80211_VENDOR_ID,
8659 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
8660 },
8661 {
8662 /* Index = 4*/
8663 .vendor_id = QCA_NL80211_VENDOR_ID,
8664 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
8665 },
8666 {
8667 /* Index = 5*/
8668 .vendor_id = QCA_NL80211_VENDOR_ID,
8669 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
8670 },
8671 {
8672 /* Index = 6*/
8673 .vendor_id = QCA_NL80211_VENDOR_ID,
8674 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
8675 },
8676#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308677#ifdef WLAN_FEATURE_EXTSCAN
8678 {
8679 .vendor_id = QCA_NL80211_VENDOR_ID,
8680 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
8681 },
8682 {
8683 .vendor_id = QCA_NL80211_VENDOR_ID,
8684 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
8685 },
8686 {
8687 .vendor_id = QCA_NL80211_VENDOR_ID,
8688 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
8689 },
8690 {
8691 .vendor_id = QCA_NL80211_VENDOR_ID,
8692 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
8693 },
8694 {
8695 .vendor_id = QCA_NL80211_VENDOR_ID,
8696 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
8697 },
8698 {
8699 .vendor_id = QCA_NL80211_VENDOR_ID,
8700 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
8701 },
8702 {
8703 .vendor_id = QCA_NL80211_VENDOR_ID,
8704 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
8705 },
8706 {
8707 .vendor_id = QCA_NL80211_VENDOR_ID,
8708 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
8709 },
8710 {
8711 .vendor_id = QCA_NL80211_VENDOR_ID,
8712 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
8713 },
8714 {
8715 .vendor_id = QCA_NL80211_VENDOR_ID,
8716 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
8717 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308718#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308719/*EXT TDLS*/
8720 {
8721 .vendor_id = QCA_NL80211_VENDOR_ID,
8722 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
8723 },
c_manjeecfd1efb2015-09-25 19:32:34 +05308724 [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
8725 .vendor_id = QCA_NL80211_VENDOR_ID,
8726 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
8727 },
8728
Srinivas Dasari030bad32015-02-18 23:23:54 +05308729
Srinivas Dasaribd1cf642017-01-23 14:54:41 +05308730 [QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX] = {
Srinivas Dasari030bad32015-02-18 23:23:54 +05308731 .vendor_id = QCA_NL80211_VENDOR_ID,
8732 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
8733 },
8734
Sushant Kaushik084f6592015-09-10 13:11:56 +05308735 {
8736 .vendor_id = QCA_NL80211_VENDOR_ID,
8737 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308738 },
8739 [QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = {
8740 .vendor_id = QCA_NL80211_VENDOR_ID,
8741 .subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI
8742 },
Padma, Santhosh Kumar7bbc7d92015-12-08 20:23:19 +05308743 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX] = {
8744 .vendor_id = QCA_NL80211_VENDOR_ID,
8745 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST
8746 },
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308747 [QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET_INDEX] = {
8748 .vendor_id = QCA_NL80211_VENDOR_ID,
8749 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8750 },
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008751};
8752
Jeff Johnson295189b2012-06-20 16:38:30 -07008753/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308754 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308755 * This function is called by hdd_wlan_startup()
8756 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308757 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07008758 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308759struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07008760{
8761 struct wiphy *wiphy;
8762 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308763 /*
8764 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07008765 */
8766 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
8767
8768 if (!wiphy)
8769 {
8770 /* Print error and jump into err label and free the memory */
8771 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
8772 return NULL;
8773 }
8774
Sunil Duttc69bccb2014-05-26 21:30:20 +05308775
Jeff Johnson295189b2012-06-20 16:38:30 -07008776 return wiphy;
8777}
8778
Anurag Chouhan343af7e2016-12-16 13:11:19 +05308779#if (LINUX_VERSION_CODE > KERNEL_VERSION(4,4,0)) || \
8780 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
8781/**
8782 * hdd_config_sched_scan_plans_to_wiphy() - configure sched scan plans to wiphy
8783 * @wiphy: pointer to wiphy
8784 * @config: pointer to config
8785 *
8786 * Return: None
8787 */
8788static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
8789 hdd_config_t *config)
8790{
8791 wiphy->max_sched_scan_plans = MAX_SCHED_SCAN_PLANS;
8792 if (config->max_sched_scan_plan_interval)
8793 wiphy->max_sched_scan_plan_interval =
8794 config->max_sched_scan_plan_interval;
8795 if (config->max_sched_scan_plan_iterations)
8796 wiphy->max_sched_scan_plan_iterations =
8797 config->max_sched_scan_plan_iterations;
8798}
8799#else
8800static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
8801 hdd_config_t *config)
8802{
8803}
8804#endif
8805
Jeff Johnson295189b2012-06-20 16:38:30 -07008806/*
8807 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308808 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07008809 * private ioctl to change the band value
8810 */
8811int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
8812{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308813 int i, j;
8814 eNVChannelEnabledType channelEnabledState;
8815
Jeff Johnsone7245742012-09-05 17:12:55 -07008816 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308817
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308818 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07008819 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308820
8821 if (NULL == wiphy->bands[i])
8822 {
8823 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
8824 __func__, i);
8825 continue;
8826 }
8827
8828 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
8829 {
8830 struct ieee80211_supported_band *band = wiphy->bands[i];
8831
8832 channelEnabledState = vos_nv_getChannelEnabledState(
8833 band->channels[j].hw_value);
8834
8835 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
8836 {
Abhishek Singh678227a2014-11-04 10:52:38 +05308837 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308838 continue;
8839 }
8840 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
8841 {
8842 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8843 continue;
8844 }
8845
8846 if (NV_CHANNEL_DISABLE == channelEnabledState ||
8847 NV_CHANNEL_INVALID == channelEnabledState)
8848 {
8849 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8850 }
8851 else if (NV_CHANNEL_DFS == channelEnabledState)
8852 {
8853 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
8854 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
8855 }
8856 else
8857 {
8858 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
8859 |IEEE80211_CHAN_RADAR);
8860 }
8861 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008862 }
8863 return 0;
8864}
8865/*
8866 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308867 * This function is called by hdd_wlan_startup()
8868 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07008869 * This function is used to initialize and register wiphy structure.
8870 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308871int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07008872 struct wiphy *wiphy,
8873 hdd_config_t *pCfg
8874 )
8875{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308876 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05308877 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
8878
Jeff Johnsone7245742012-09-05 17:12:55 -07008879 ENTER();
8880
Jeff Johnson295189b2012-06-20 16:38:30 -07008881 /* Now bind the underlying wlan device with wiphy */
8882 set_wiphy_dev(wiphy, dev);
8883
8884 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07008885
Kiet Lam6c583332013-10-14 05:37:09 +05308886#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07008887 /* the flag for the other case would be initialzed in
8888 vos_init_wiphy_from_nv_bin */
Manjeet Singh9e19de62016-08-18 18:26:41 +05308889#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
8890 wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
8891#else
Amar Singhal0a402232013-10-11 20:57:16 -07008892 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05308893#endif
Manjeet Singh9e19de62016-08-18 18:26:41 +05308894#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07008895
Amar Singhalfddc28c2013-09-05 13:03:40 -07008896 /* This will disable updating of NL channels from passive to
8897 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308898#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
8899 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
8900#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07008901 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308902#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07008903
Amar Singhala49cbc52013-10-08 18:37:44 -07008904
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008905#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07008906 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
8907 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
8908 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07008909 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308910#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Rajeev Kumar Sirasanagandla0d6dd752016-08-17 15:01:39 +05308911 wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308912#else
8913 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
8914#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008915#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07008916
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08008917#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07008918 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08008919#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07008920 || pCfg->isFastRoamIniFeatureEnabled
8921#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08008922#ifdef FEATURE_WLAN_ESE
8923 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07008924#endif
8925 )
8926 {
8927 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
8928 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08008929#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008930#ifdef FEATURE_WLAN_TDLS
8931 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
8932 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
8933#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308934#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05308935 if (pCfg->configPNOScanSupport)
8936 {
8937 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
8938 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
8939 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
8940 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
8941 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308942#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008943
Abhishek Singh10d85972015-04-17 10:27:23 +05308944#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
8945 wiphy->features |= NL80211_FEATURE_HT_IBSS;
8946#endif
8947
Amar Singhalfddc28c2013-09-05 13:03:40 -07008948#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07008949 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
8950 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07008951 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07008952 driver need to determine what to do with both
8953 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07008954
8955 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07008956#else
8957 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07008958#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008959
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308960 wiphy->max_scan_ssids = MAX_SCAN_SSID;
8961
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05308962 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07008963
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308964 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
8965
Jeff Johnson295189b2012-06-20 16:38:30 -07008966 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05308967 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
8968 | BIT(NL80211_IFTYPE_ADHOC)
8969 | BIT(NL80211_IFTYPE_P2P_CLIENT)
8970 | BIT(NL80211_IFTYPE_P2P_GO)
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308971 | BIT(NL80211_IFTYPE_AP)
8972 | BIT(NL80211_IFTYPE_MONITOR);
Jeff Johnson295189b2012-06-20 16:38:30 -07008973
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308974 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008975 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308976#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
8977 if( pCfg->enableMCC )
8978 {
8979 /* Currently, supports up to two channels */
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308980 wlan_hdd_iface_combination[0].num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008981
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308982 if( !pCfg->allowMCCGODiffBI )
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308983 wlan_hdd_iface_combination[0].beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008984
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308985 }
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308986 wiphy->iface_combinations = wlan_hdd_iface_combination;
8987 wiphy->n_iface_combinations = ARRAY_SIZE(wlan_hdd_iface_combination);
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008988#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308989 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008990
Jeff Johnson295189b2012-06-20 16:38:30 -07008991 /* Before registering we need to update the ht capabilitied based
8992 * on ini values*/
8993 if( !pCfg->ShortGI20MhzEnable )
8994 {
8995 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
8996 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
Jeff Johnson295189b2012-06-20 16:38:30 -07008997 }
8998
8999 if( !pCfg->ShortGI40MhzEnable )
9000 {
9001 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
9002 }
9003
9004 if( !pCfg->nChannelBondingMode5GHz )
9005 {
9006 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
9007 }
Agrawal Ashish97dec502015-11-26 20:20:58 +05309008 /*
9009 * In case of static linked driver at the time of driver unload,
9010 * module exit doesn't happens. Module cleanup helps in cleaning
9011 * of static memory.
9012 * If driver load happens statically, at the time of driver unload,
9013 * wiphy flags don't get reset because of static memory.
9014 * It's better not to store channel in static memory.
9015 */
9016 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
9017 wiphy->bands[IEEE80211_BAND_2GHZ]->channels =
9018 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_2_4_GHZ));
9019 if (wiphy->bands[IEEE80211_BAND_2GHZ]->channels == NULL)
9020 {
9021 hddLog(VOS_TRACE_LEVEL_ERROR,
9022 FL("Not enough memory to allocate channels"));
9023 return -ENOMEM;
9024 }
9025 vos_mem_copy(wiphy->bands[IEEE80211_BAND_2GHZ]->channels,
9026 &hdd_channels_2_4_GHZ[0],
9027 sizeof(hdd_channels_2_4_GHZ));
Jeff Johnson295189b2012-06-20 16:38:30 -07009028
Agrawal Ashish97dec502015-11-26 20:20:58 +05309029 if (true == hdd_is_5g_supported(pHddCtx))
9030 {
9031 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
9032 wiphy->bands[IEEE80211_BAND_5GHZ]->channels =
9033 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_5_GHZ));
9034 if (wiphy->bands[IEEE80211_BAND_5GHZ]->channels == NULL)
9035 {
9036 hddLog(VOS_TRACE_LEVEL_ERROR,
9037 FL("Not enough memory to allocate channels"));
9038 vos_mem_free(wiphy->bands[IEEE80211_BAND_2GHZ]->channels);
9039 wiphy->bands[IEEE80211_BAND_2GHZ]->channels = NULL;
9040 return -ENOMEM;
9041 }
9042 vos_mem_copy(wiphy->bands[IEEE80211_BAND_5GHZ]->channels,
9043 &hdd_channels_5_GHZ[0],
9044 sizeof(hdd_channels_5_GHZ));
9045 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309046
9047 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
9048 {
9049
9050 if (NULL == wiphy->bands[i])
9051 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05309052 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309053 __func__, i);
9054 continue;
9055 }
9056
9057 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
9058 {
9059 struct ieee80211_supported_band *band = wiphy->bands[i];
9060
9061 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
9062 {
9063 // Enable social channels for P2P
9064 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
9065 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
9066 else
9067 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9068 continue;
9069 }
9070 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
9071 {
9072 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9073 continue;
9074 }
9075 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009076 }
9077 /*Initialise the supported cipher suite details*/
9078 wiphy->cipher_suites = hdd_cipher_suites;
9079 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
9080
9081 /*signal strength in mBm (100*dBm) */
9082 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
9083
9084#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05309085 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07009086#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009087
Sunil Duttc69bccb2014-05-26 21:30:20 +05309088 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
9089 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08009090 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
9091 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
9092
Anurag Chouhan343af7e2016-12-16 13:11:19 +05309093 hdd_config_sched_scan_plans_to_wiphy(wiphy, pCfg);
9094
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309095 EXIT();
9096 return 0;
9097}
9098
9099/* In this function we are registering wiphy. */
9100int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
9101{
9102 ENTER();
9103 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009104 if (0 > wiphy_register(wiphy))
9105 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309106 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07009107 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9108 return -EIO;
9109 }
9110
9111 EXIT();
9112 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309113}
Jeff Johnson295189b2012-06-20 16:38:30 -07009114
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309115/* In this function we are updating channel list when,
9116 regulatory domain is FCC and country code is US.
9117 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
9118 As per FCC smart phone is not a indoor device.
9119 GO should not opeate on indoor channels */
9120void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
9121{
9122 int j;
9123 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9124 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
9125 //Default counrtycode from NV at the time of wiphy initialization.
9126 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
9127 &defaultCountryCode[0]))
9128 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009129 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309130 }
9131 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
9132 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309133 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
9134 {
9135 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
9136 return;
9137 }
9138 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
9139 {
9140 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
9141 // Mark UNII -1 band channel as passive
9142 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
9143 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
9144 }
9145 }
9146}
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309147/* This function registers for all frame which supplicant is interested in */
9148void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009149{
Jeff Johnson295189b2012-06-20 16:38:30 -07009150 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9151 /* Register for all P2P action, public action etc frames */
9152 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
Jeff Johnsone7245742012-09-05 17:12:55 -07009153 ENTER();
Abhishek Singh16e05762015-11-30 14:29:27 +05309154 /* Register frame indication call back */
9155 sme_register_mgmt_frame_ind_callback(hHal, hdd_indicate_mgmt_frame);
Jeff Johnson295189b2012-06-20 16:38:30 -07009156 /* Right now we are registering these frame when driver is getting
9157 initialized. Once we will move to 2.6.37 kernel, in which we have
9158 frame register ops, we will move this code as a part of that */
9159 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309160 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07009161 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
9162
9163 /* GAS Initial Response */
9164 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9165 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309166
Jeff Johnson295189b2012-06-20 16:38:30 -07009167 /* GAS Comeback Request */
9168 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9169 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
9170
9171 /* GAS Comeback Response */
9172 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9173 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
9174
9175 /* P2P Public Action */
9176 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309177 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07009178 P2P_PUBLIC_ACTION_FRAME_SIZE );
9179
9180 /* P2P Action */
9181 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9182 (v_U8_t*)P2P_ACTION_FRAME,
9183 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07009184
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05309185 /* WNM BSS Transition Request frame */
9186 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9187 (v_U8_t*)WNM_BSS_ACTION_FRAME,
9188 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07009189
9190 /* WNM-Notification */
9191 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9192 (v_U8_t*)WNM_NOTIFICATION_FRAME,
9193 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009194}
9195
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309196void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009197{
Jeff Johnson295189b2012-06-20 16:38:30 -07009198 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9199 /* Register for all P2P action, public action etc frames */
9200 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
9201
Jeff Johnsone7245742012-09-05 17:12:55 -07009202 ENTER();
9203
Jeff Johnson295189b2012-06-20 16:38:30 -07009204 /* Right now we are registering these frame when driver is getting
9205 initialized. Once we will move to 2.6.37 kernel, in which we have
9206 frame register ops, we will move this code as a part of that */
9207 /* GAS Initial Request */
9208
9209 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9210 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
9211
9212 /* GAS Initial Response */
9213 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9214 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309215
Jeff Johnson295189b2012-06-20 16:38:30 -07009216 /* GAS Comeback Request */
9217 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9218 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
9219
9220 /* GAS Comeback Response */
9221 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9222 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
9223
9224 /* P2P Public Action */
9225 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309226 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07009227 P2P_PUBLIC_ACTION_FRAME_SIZE );
9228
9229 /* P2P Action */
9230 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9231 (v_U8_t*)P2P_ACTION_FRAME,
9232 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07009233 /* WNM-Notification */
9234 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9235 (v_U8_t*)WNM_NOTIFICATION_FRAME,
9236 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009237}
9238
9239#ifdef FEATURE_WLAN_WAPI
9240void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05309241 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07009242{
9243 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9244 tCsrRoamSetKey setKey;
9245 v_BOOL_t isConnected = TRUE;
9246 int status = 0;
9247 v_U32_t roamId= 0xFF;
9248 tANI_U8 *pKeyPtr = NULL;
9249 int n = 0;
9250
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309251 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
9252 __func__, hdd_device_modetoString(pAdapter->device_mode),
9253 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009254
Gopichand Nakkalae7480202013-02-11 15:24:22 +05309255 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07009256 setKey.keyId = key_index; // Store Key ID
9257 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
9258 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
9259 setKey.paeRole = 0 ; // the PAE role
9260 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
9261 {
9262 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
9263 }
9264 else
9265 {
9266 isConnected = hdd_connIsConnected(pHddStaCtx);
9267 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
9268 }
9269 setKey.keyLength = key_Len;
9270 pKeyPtr = setKey.Key;
9271 memcpy( pKeyPtr, key, key_Len);
9272
Arif Hussain6d2a3322013-11-17 19:50:10 -08009273 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07009274 __func__, key_Len);
9275 for (n = 0 ; n < key_Len; n++)
9276 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
9277 __func__,n,setKey.Key[n]);
9278
9279 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9280 if ( isConnected )
9281 {
9282 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
9283 pAdapter->sessionId, &setKey, &roamId );
9284 }
9285 if ( status != 0 )
9286 {
9287 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9288 "[%4d] sme_RoamSetKey returned ERROR status= %d",
9289 __LINE__, status );
9290 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9291 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309292 /* Need to clear any trace of key value in the memory.
9293 * Thus zero out the memory even though it is local
9294 * variable.
9295 */
9296 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07009297}
9298#endif /* FEATURE_WLAN_WAPI*/
9299
9300#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309301int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009302 beacon_data_t **ppBeacon,
9303 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009304#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309305int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009306 beacon_data_t **ppBeacon,
9307 struct cfg80211_beacon_data *params,
9308 int dtim_period)
9309#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309310{
Jeff Johnson295189b2012-06-20 16:38:30 -07009311 int size;
9312 beacon_data_t *beacon = NULL;
9313 beacon_data_t *old = NULL;
Kapil Gupta137ef892016-12-13 19:38:00 +05309314 int head_len, tail_len, proberesp_ies_len, assocresp_ies_len;
9315 const u8 *head, *tail, *proberesp_ies, *assocresp_ies;
Jeff Johnson295189b2012-06-20 16:38:30 -07009316
Jeff Johnsone7245742012-09-05 17:12:55 -07009317 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07009318 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309319 {
9320 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9321 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009322 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309323 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009324
9325 old = pAdapter->sessionCtx.ap.beacon;
9326
9327 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309328 {
9329 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9330 FL("session(%d) old and new heads points to NULL"),
9331 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009332 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309333 }
9334
9335 if (params->tail && !params->tail_len)
9336 {
9337 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9338 FL("tail_len is zero but tail is not NULL"));
9339 return -EINVAL;
9340 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009341
Jeff Johnson295189b2012-06-20 16:38:30 -07009342#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
9343 /* Kernel 3.0 is not updating dtim_period for set beacon */
9344 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309345 {
9346 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9347 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009348 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309349 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009350#endif
9351
Kapil Gupta137ef892016-12-13 19:38:00 +05309352 if (params->head)
9353 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009354 head_len = params->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309355 head = params->head;
9356 } else
9357 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009358 head_len = old->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309359 head = old->head;
9360 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009361
Kapil Gupta137ef892016-12-13 19:38:00 +05309362 if (params->tail || !old)
9363 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009364 tail_len = params->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309365 tail = params->tail;
9366 } else
9367 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009368 tail_len = old->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309369 tail = old->tail;
9370 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009371
Kapil Gupta137ef892016-12-13 19:38:00 +05309372 if (params->proberesp_ies || !old)
9373 {
9374 proberesp_ies_len = params->proberesp_ies_len;
9375 proberesp_ies = params->proberesp_ies;
9376 } else
9377 {
9378 proberesp_ies_len = old->proberesp_ies_len;
9379 proberesp_ies = old->proberesp_ies;
9380 }
9381
9382 if (params->assocresp_ies || !old)
9383 {
9384 assocresp_ies_len = params->assocresp_ies_len;
9385 assocresp_ies = params->assocresp_ies;
9386 } else
9387 {
9388 assocresp_ies_len = old->assocresp_ies_len;
9389 assocresp_ies = old->assocresp_ies;
9390 }
9391
9392 size = sizeof(beacon_data_t) + head_len + tail_len +
9393 proberesp_ies_len + assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009394
9395 beacon = kzalloc(size, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009396 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309397 {
9398 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9399 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009400 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309401 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009402
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009403#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Kapil Gupta137ef892016-12-13 19:38:00 +05309404 if (params->dtim_period)
Jeff Johnson295189b2012-06-20 16:38:30 -07009405 beacon->dtim_period = params->dtim_period;
9406 else
9407 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009408#else
Kapil Gupta137ef892016-12-13 19:38:00 +05309409 if (dtim_period)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009410 beacon->dtim_period = dtim_period;
9411 else
9412 beacon->dtim_period = old->dtim_period;
9413#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309414
Jeff Johnson295189b2012-06-20 16:38:30 -07009415 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
9416 beacon->tail = beacon->head + head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309417 beacon->proberesp_ies = beacon->tail + tail_len;
9418 beacon->assocresp_ies = beacon->proberesp_ies + proberesp_ies_len;
9419
Jeff Johnson295189b2012-06-20 16:38:30 -07009420 beacon->head_len = head_len;
9421 beacon->tail_len = tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309422 beacon->proberesp_ies_len = proberesp_ies_len;
9423 beacon->assocresp_ies_len= assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009424
c_manjee527ecac2017-01-25 12:25:27 +05309425 if (head && head_len)
9426 memcpy(beacon->head, head, head_len);
9427 if (tail && tail_len)
9428 memcpy(beacon->tail, tail, tail_len);
9429 if (proberesp_ies && proberesp_ies_len)
9430 memcpy(beacon->proberesp_ies, proberesp_ies, proberesp_ies_len);
9431 if (assocresp_ies && assocresp_ies_len)
9432 memcpy(beacon->assocresp_ies, assocresp_ies, assocresp_ies_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009433
9434 *ppBeacon = beacon;
9435
9436 kfree(old);
9437
9438 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009439}
Jeff Johnson295189b2012-06-20 16:38:30 -07009440
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309441v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
9442#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
9443 const v_U8_t *pIes,
9444#else
9445 v_U8_t *pIes,
9446#endif
9447 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009448{
9449 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309450 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07009451 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309452
Jeff Johnson295189b2012-06-20 16:38:30 -07009453 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309454 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009455 elem_id = ptr[0];
9456 elem_len = ptr[1];
9457 left -= 2;
9458 if(elem_len > left)
9459 {
9460 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07009461 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009462 eid,elem_len,left);
9463 return NULL;
9464 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309465 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009466 {
9467 return ptr;
9468 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309469
Jeff Johnson295189b2012-06-20 16:38:30 -07009470 left -= elem_len;
9471 ptr += (elem_len + 2);
9472 }
9473 return NULL;
9474}
9475
Jeff Johnson295189b2012-06-20 16:38:30 -07009476/* Check if rate is 11g rate or not */
9477static int wlan_hdd_rate_is_11g(u8 rate)
9478{
Sanjay Devnani28322e22013-06-21 16:13:40 -07009479 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009480 u8 i;
9481 for (i = 0; i < 8; i++)
9482 {
9483 if(rate == gRateArray[i])
9484 return TRUE;
9485 }
9486 return FALSE;
9487}
9488
9489/* Check for 11g rate and set proper 11g only mode */
9490static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
9491 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
9492{
9493 u8 i, num_rates = pIe[0];
9494
9495 pIe += 1;
9496 for ( i = 0; i < num_rates; i++)
9497 {
9498 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
9499 {
9500 /* If rate set have 11g rate than change the mode to 11G */
9501 *pSapHw_mode = eSAP_DOT11_MODE_11g;
9502 if (pIe[i] & BASIC_RATE_MASK)
9503 {
9504 /* If we have 11g rate as basic rate, it means mode
9505 is 11g only mode.
9506 */
9507 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
9508 *pCheckRatesfor11g = FALSE;
9509 }
9510 }
9511 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
9512 {
9513 *require_ht = TRUE;
9514 }
9515 }
9516 return;
9517}
9518
9519static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
9520{
9521 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9522 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9523 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9524 u8 checkRatesfor11g = TRUE;
9525 u8 require_ht = FALSE;
9526 u8 *pIe=NULL;
9527
9528 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
9529
9530 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
9531 pBeacon->head_len, WLAN_EID_SUPP_RATES);
9532 if (pIe != NULL)
9533 {
9534 pIe += 1;
9535 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9536 &pConfig->SapHw_mode);
9537 }
9538
9539 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9540 WLAN_EID_EXT_SUPP_RATES);
9541 if (pIe != NULL)
9542 {
9543
9544 pIe += 1;
9545 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9546 &pConfig->SapHw_mode);
9547 }
9548
9549 if( pConfig->channel > 14 )
9550 {
9551 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
9552 }
9553
9554 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9555 WLAN_EID_HT_CAPABILITY);
9556
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309557 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009558 {
9559 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
9560 if(require_ht)
9561 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
9562 }
9563}
9564
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309565static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
9566 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
9567{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009568 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309569 v_U8_t *pIe = NULL;
9570 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9571
9572 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
9573 pBeacon->tail, pBeacon->tail_len);
9574
9575 if (pIe)
9576 {
9577 ielen = pIe[1] + 2;
9578 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9579 {
9580 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
9581 }
9582 else
9583 {
9584 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
9585 return -EINVAL;
9586 }
9587 *total_ielen += ielen;
9588 }
9589 return 0;
9590}
9591
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009592static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
9593 v_U8_t *genie, v_U8_t *total_ielen)
9594{
9595 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9596 int left = pBeacon->tail_len;
9597 v_U8_t *ptr = pBeacon->tail;
9598 v_U8_t elem_id, elem_len;
9599 v_U16_t ielen = 0;
9600
9601 if ( NULL == ptr || 0 == left )
9602 return;
9603
9604 while (left >= 2)
9605 {
9606 elem_id = ptr[0];
9607 elem_len = ptr[1];
9608 left -= 2;
9609 if (elem_len > left)
9610 {
9611 hddLog( VOS_TRACE_LEVEL_ERROR,
9612 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
9613 elem_id, elem_len, left);
9614 return;
9615 }
Ashish Kumar Dhanotiya6af276b2017-08-22 16:53:48 +05309616 if ((IE_EID_VENDOR == elem_id) && (elem_len >= WPS_OUI_TYPE_SIZE))
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009617 {
9618 /* skipping the VSIE's which we don't want to include or
9619 * it will be included by existing code
9620 */
9621 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
9622#ifdef WLAN_FEATURE_WFD
9623 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
9624#endif
9625 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9626 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9627 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
9628 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9629 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
9630 {
9631 ielen = ptr[1] + 2;
9632 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9633 {
9634 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
9635 *total_ielen += ielen;
9636 }
9637 else
9638 {
9639 hddLog( VOS_TRACE_LEVEL_ERROR,
9640 "IE Length is too big "
9641 "IEs eid=%d elem_len=%d total_ie_lent=%d",
9642 elem_id, elem_len, *total_ielen);
9643 }
9644 }
9645 }
9646
9647 left -= elem_len;
9648 ptr += (elem_len + 2);
9649 }
9650 return;
9651}
9652
Kapil Gupta137ef892016-12-13 19:38:00 +05309653int wlan_hdd_cfg80211_update_apies(hdd_adapter_t *pHostapdAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009654{
9655 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309656 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009657 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07009658 int ret = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +05309659 beacon_data_t *pBeacon = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009660
9661 genie = vos_mem_malloc(MAX_GENIE_LEN);
9662
9663 if(genie == NULL) {
9664
9665 return -ENOMEM;
9666 }
9667
Kapil Gupta137ef892016-12-13 19:38:00 +05309668 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309669 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9670 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009671 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309672 hddLog(LOGE,
9673 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309674 ret = -EINVAL;
9675 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009676 }
9677
9678#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309679 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9680 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
9681 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309682 hddLog(LOGE,
9683 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309684 ret = -EINVAL;
9685 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009686 }
9687#endif
9688
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309689 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9690 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009691 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309692 hddLog(LOGE,
9693 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309694 ret = -EINVAL;
9695 goto done;
9696 }
9697
9698 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
9699 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009700 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07009701 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009702
9703 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9704 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
9705 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
9706 {
9707 hddLog(LOGE,
9708 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009709 ret = -EINVAL;
9710 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009711 }
9712
9713 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9714 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
9715 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9716 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9717 ==eHAL_STATUS_FAILURE)
9718 {
9719 hddLog(LOGE,
9720 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009721 ret = -EINVAL;
9722 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009723 }
9724
9725 // Added for ProResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +05309726 if ((pBeacon->proberesp_ies != NULL) && (pBeacon->proberesp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009727 {
Kapil Gupta137ef892016-12-13 19:38:00 +05309728 u16 rem_probe_resp_ie_len = pBeacon->proberesp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009729 u8 probe_rsp_ie_len[3] = {0};
9730 u8 counter = 0;
9731 /* Check Probe Resp Length if it is greater then 255 then Store
9732 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
9733 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
9734 Store More then 255 bytes into One Variable.
9735 */
9736 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
9737 {
9738 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
9739 {
9740 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
9741 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
9742 }
9743 else
9744 {
9745 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
9746 rem_probe_resp_ie_len = 0;
9747 }
9748 }
9749
9750 rem_probe_resp_ie_len = 0;
9751
9752 if (probe_rsp_ie_len[0] > 0)
9753 {
9754 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9755 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
Kapil Gupta137ef892016-12-13 19:38:00 +05309756 (tANI_U8*)&pBeacon->
9757 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07009758 probe_rsp_ie_len[0], NULL,
9759 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9760 {
9761 hddLog(LOGE,
9762 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009763 ret = -EINVAL;
9764 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009765 }
9766 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
9767 }
9768
9769 if (probe_rsp_ie_len[1] > 0)
9770 {
9771 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9772 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
Kapil Gupta137ef892016-12-13 19:38:00 +05309773 (tANI_U8*)&pBeacon->
9774 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07009775 probe_rsp_ie_len[1], NULL,
9776 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9777 {
9778 hddLog(LOGE,
9779 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009780 ret = -EINVAL;
9781 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009782 }
9783 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
9784 }
9785
9786 if (probe_rsp_ie_len[2] > 0)
9787 {
9788 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9789 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
Kapil Gupta137ef892016-12-13 19:38:00 +05309790 (tANI_U8*)&pBeacon->
9791 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07009792 probe_rsp_ie_len[2], NULL,
9793 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9794 {
9795 hddLog(LOGE,
9796 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009797 ret = -EINVAL;
9798 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009799 }
9800 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
9801 }
9802
9803 if (probe_rsp_ie_len[1] == 0 )
9804 {
9805 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9806 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
9807 eANI_BOOLEAN_FALSE) )
9808 {
9809 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009810 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009811 }
9812 }
9813
9814 if (probe_rsp_ie_len[2] == 0 )
9815 {
9816 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9817 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
9818 eANI_BOOLEAN_FALSE) )
9819 {
9820 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009821 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009822 }
9823 }
9824
9825 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9826 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
9827 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9828 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9829 == eHAL_STATUS_FAILURE)
9830 {
9831 hddLog(LOGE,
9832 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009833 ret = -EINVAL;
9834 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009835 }
9836 }
9837 else
9838 {
9839 // Reset WNI_CFG_PROBE_RSP Flags
9840 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
9841
9842 hddLog(VOS_TRACE_LEVEL_INFO,
9843 "%s: No Probe Response IE received in set beacon",
9844 __func__);
9845 }
9846
9847 // Added for AssocResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +05309848 if ((pBeacon->assocresp_ies != NULL) && (pBeacon->assocresp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009849 {
9850 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
Kapil Gupta137ef892016-12-13 19:38:00 +05309851 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)pBeacon->assocresp_ies,
9852 pBeacon->assocresp_ies_len, NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -07009853 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9854 {
9855 hddLog(LOGE,
9856 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009857 ret = -EINVAL;
9858 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009859 }
9860
9861 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9862 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
9863 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9864 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9865 == eHAL_STATUS_FAILURE)
9866 {
9867 hddLog(LOGE,
9868 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009869 ret = -EINVAL;
9870 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009871 }
9872 }
9873 else
9874 {
9875 hddLog(VOS_TRACE_LEVEL_INFO,
9876 "%s: No Assoc Response IE received in set beacon",
9877 __func__);
9878
9879 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9880 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
9881 eANI_BOOLEAN_FALSE) )
9882 {
9883 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009884 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009885 }
9886 }
9887
Jeff Johnsone7245742012-09-05 17:12:55 -07009888done:
Jeff Johnson295189b2012-06-20 16:38:30 -07009889 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309890 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009891}
Jeff Johnson295189b2012-06-20 16:38:30 -07009892
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309893/*
Jeff Johnson295189b2012-06-20 16:38:30 -07009894 * FUNCTION: wlan_hdd_validate_operation_channel
9895 * called by wlan_hdd_cfg80211_start_bss() and
9896 * wlan_hdd_cfg80211_set_channel()
9897 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309898 * channel list.
9899 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07009900VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07009901{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309902
Jeff Johnson295189b2012-06-20 16:38:30 -07009903 v_U32_t num_ch = 0;
9904 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
9905 u32 indx = 0;
9906 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309907 v_U8_t fValidChannel = FALSE, count = 0;
9908 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309909
Jeff Johnson295189b2012-06-20 16:38:30 -07009910 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
9911
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309912 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07009913 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309914 /* Validate the channel */
9915 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07009916 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309917 if ( channel == rfChannels[count].channelNum )
9918 {
9919 fValidChannel = TRUE;
9920 break;
9921 }
9922 }
9923 if (fValidChannel != TRUE)
9924 {
9925 hddLog(VOS_TRACE_LEVEL_ERROR,
9926 "%s: Invalid Channel [%d]", __func__, channel);
9927 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009928 }
9929 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309930 else
Jeff Johnson295189b2012-06-20 16:38:30 -07009931 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309932 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
9933 valid_ch, &num_ch))
9934 {
9935 hddLog(VOS_TRACE_LEVEL_ERROR,
9936 "%s: failed to get valid channel list", __func__);
9937 return VOS_STATUS_E_FAILURE;
9938 }
9939 for (indx = 0; indx < num_ch; indx++)
9940 {
9941 if (channel == valid_ch[indx])
9942 {
9943 break;
9944 }
9945 }
9946
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05309947 if (indx >= num_ch)
9948 {
9949 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
9950 {
9951 eCsrBand band;
9952 unsigned int freq;
9953
9954 sme_GetFreqBand(hHal, &band);
9955
9956 if (eCSR_BAND_5G == band)
9957 {
9958#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
9959 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
9960 {
9961 freq = ieee80211_channel_to_frequency(channel,
9962 IEEE80211_BAND_2GHZ);
9963 }
9964 else
9965 {
9966 freq = ieee80211_channel_to_frequency(channel,
9967 IEEE80211_BAND_5GHZ);
9968 }
9969#else
9970 freq = ieee80211_channel_to_frequency(channel);
9971#endif
9972 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
9973 return VOS_STATUS_SUCCESS;
9974 }
9975 }
9976
9977 hddLog(VOS_TRACE_LEVEL_ERROR,
9978 "%s: Invalid Channel [%d]", __func__, channel);
9979 return VOS_STATUS_E_FAILURE;
9980 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009981 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05309982
Jeff Johnson295189b2012-06-20 16:38:30 -07009983 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309984
Jeff Johnson295189b2012-06-20 16:38:30 -07009985}
9986
Viral Modi3a32cc52013-02-08 11:14:52 -08009987/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309988 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08009989 * This function is used to set the channel number
9990 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309991static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08009992 struct ieee80211_channel *chan,
9993 enum nl80211_channel_type channel_type
9994 )
9995{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309996 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08009997 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07009998 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08009999 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010000 hdd_context_t *pHddCtx;
10001 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010002
10003 ENTER();
10004
10005 if( NULL == dev )
10006 {
10007 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010008 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -080010009 return -ENODEV;
10010 }
10011 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010012
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010013 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10014 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
10015 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -080010016 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010017 "%s: device_mode = %s (%d) freq = %d", __func__,
10018 hdd_device_modetoString(pAdapter->device_mode),
10019 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010020
10021 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10022 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010023 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -080010024 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010025 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010026 }
10027
10028 /*
10029 * Do freq to chan conversion
10030 * TODO: for 11a
10031 */
10032
10033 channel = ieee80211_frequency_to_channel(freq);
10034
10035 /* Check freq range */
10036 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
10037 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
10038 {
10039 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010040 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -080010041 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
10042 WNI_CFG_CURRENT_CHANNEL_STAMAX);
10043 return -EINVAL;
10044 }
10045
10046 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
10047
Gopichand Nakkala6ab19562013-03-07 13:59:42 +053010048 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
10049 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -080010050 {
10051 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
10052 {
10053 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010054 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -080010055 return -EINVAL;
10056 }
10057 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10058 "%s: set channel to [%d] for device mode =%d",
10059 __func__, channel,pAdapter->device_mode);
10060 }
10061 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -080010062 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -080010063 )
10064 {
10065 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10066 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
10067 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10068
10069 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
10070 {
10071 /* Link is up then return cant set channel*/
10072 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010073 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -080010074 return -EINVAL;
10075 }
10076
10077 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
10078 pHddStaCtx->conn_info.operationChannel = channel;
10079 pRoamProfile->ChannelInfo.ChannelList =
10080 &pHddStaCtx->conn_info.operationChannel;
10081 }
10082 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -080010083 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -080010084 )
10085 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010086 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
10087 {
10088 if(VOS_STATUS_SUCCESS !=
10089 wlan_hdd_validate_operation_channel(pAdapter,channel))
10090 {
10091 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010092 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010093 return -EINVAL;
10094 }
10095 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
10096 }
10097 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -080010098 {
10099 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
10100
10101 /* If auto channel selection is configured as enable/ 1 then ignore
10102 channel set by supplicant
10103 */
10104 if ( cfg_param->apAutoChannelSelection )
10105 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010106 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
10107 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -080010108 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010109 "%s: set channel to auto channel (0) for device mode =%s (%d)",
10110 __func__, hdd_device_modetoString(pAdapter->device_mode),
10111 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -080010112 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010113 else
10114 {
10115 if(VOS_STATUS_SUCCESS !=
10116 wlan_hdd_validate_operation_channel(pAdapter,channel))
10117 {
10118 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010119 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010120 return -EINVAL;
10121 }
10122 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
10123 }
Viral Modi3a32cc52013-02-08 11:14:52 -080010124 }
10125 }
10126 else
10127 {
10128 hddLog(VOS_TRACE_LEVEL_FATAL,
10129 "%s: Invalid device mode failed to set valid channel", __func__);
10130 return -EINVAL;
10131 }
10132 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010133 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010134}
10135
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010136static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
10137 struct net_device *dev,
10138 struct ieee80211_channel *chan,
10139 enum nl80211_channel_type channel_type
10140 )
10141{
10142 int ret;
10143
10144 vos_ssr_protect(__func__);
10145 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
10146 vos_ssr_unprotect(__func__);
10147
10148 return ret;
10149}
10150
Anurag Chouhan83026002016-12-13 22:46:21 +053010151#ifdef DHCP_SERVER_OFFLOAD
10152void hdd_dhcp_server_offload_done(void *fw_dhcp_srv_offload_cb_context,
10153 VOS_STATUS status)
10154{
10155 hdd_adapter_t* adapter = (hdd_adapter_t*)fw_dhcp_srv_offload_cb_context;
10156
10157 ENTER();
10158
10159 if (NULL == adapter)
10160 {
10161 hddLog(VOS_TRACE_LEVEL_ERROR,
10162 "%s: adapter is NULL",__func__);
10163 return;
10164 }
10165
10166 adapter->dhcp_status.dhcp_offload_status = status;
10167 vos_event_set(&adapter->dhcp_status.vos_event);
10168 return;
10169}
10170
10171/**
10172 * wlan_hdd_set_dhcp_server_offload() - set dhcp server offload
10173 * @hostapd_adapter: pointer to hostapd adapter.
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010174 * @re_init: flag set if api called post ssr
Anurag Chouhan83026002016-12-13 22:46:21 +053010175 *
10176 * Return: None
10177 */
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010178VOS_STATUS wlan_hdd_set_dhcp_server_offload(hdd_adapter_t *hostapd_adapter,
10179 bool re_init)
Anurag Chouhan83026002016-12-13 22:46:21 +053010180{
10181 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter);
10182 sir_dhcp_srv_offload_info dhcp_srv_info;
10183 tANI_U8 num_entries = 0;
10184 tANI_U8 srv_ip[IPADDR_NUM_ENTRIES];
10185 tANI_U8 num;
10186 tANI_U32 temp;
10187 VOS_STATUS ret;
10188
10189 ENTER();
10190
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010191 if (!re_init) {
10192 ret = wlan_hdd_validate_context(hdd_ctx);
10193 if (0 != ret)
10194 return VOS_STATUS_E_INVAL;
10195 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010196
10197 /* Prepare the request to send to SME */
10198 dhcp_srv_info = vos_mem_malloc(sizeof(*dhcp_srv_info));
10199 if (NULL == dhcp_srv_info) {
10200 hddLog(VOS_TRACE_LEVEL_ERROR,
10201 "%s: could not allocate tDhcpSrvOffloadInfo!", __func__);
10202 return VOS_STATUS_E_NOMEM;
10203 }
10204
10205 vos_mem_zero(dhcp_srv_info, sizeof(*dhcp_srv_info));
10206
10207 dhcp_srv_info->bssidx = hostapd_adapter->sessionId;
10208 dhcp_srv_info->dhcp_srv_offload_enabled = TRUE;
10209 dhcp_srv_info->dhcp_client_num = hdd_ctx->cfg_ini->dhcp_max_num_clients;
10210 dhcp_srv_info->start_lsb = hdd_ctx->cfg_ini->dhcp_start_lsb;
10211 dhcp_srv_info->dhcp_offload_callback = hdd_dhcp_server_offload_done;
10212 dhcp_srv_info->dhcp_server_offload_cb_context = hostapd_adapter;
10213
10214 hdd_string_to_u8_array(hdd_ctx->cfg_ini->dhcp_srv_ip,
10215 srv_ip,
10216 &num_entries,
Yeshwanth Sriram Guntuka8d9b29c2017-12-12 15:44:57 +053010217 IPADDR_NUM_ENTRIES, ".", false);
Anurag Chouhan83026002016-12-13 22:46:21 +053010218 if (num_entries != IPADDR_NUM_ENTRIES) {
10219 hddLog(VOS_TRACE_LEVEL_ERROR,
10220 "%s: incorrect IP address (%s) assigned for DHCP server!",
10221 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10222 vos_mem_free(dhcp_srv_info);
10223 return VOS_STATUS_E_FAILURE;
10224 }
10225
10226 if ((srv_ip[0] >= 224) && (srv_ip[0] <= 239)) {
10227 hddLog(VOS_TRACE_LEVEL_ERROR,
10228 "%s: invalid IP address (%s)! It could NOT be multicast IP address!",
10229 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10230 vos_mem_free(dhcp_srv_info);
10231 return VOS_STATUS_E_FAILURE;
10232 }
10233
10234 if (srv_ip[IPADDR_NUM_ENTRIES-1] >= DHCP_START_POOL_ADDRESS) {
10235 hddLog(VOS_TRACE_LEVEL_ERROR,
10236 "%s: invalid IP address (%s)! The last field must be less than 100!",
10237 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10238 vos_mem_free(dhcp_srv_info);
10239 return VOS_STATUS_E_FAILURE;
10240 }
10241
10242 for (num = 0; num < num_entries; num++) {
10243 temp = srv_ip[num];
10244 dhcp_srv_info->dhcp_srv_ip |= (temp << (8 * num));
10245 }
10246
10247 if (eHAL_STATUS_SUCCESS !=
10248 sme_set_dhcp_srv_offload(hdd_ctx->hHal, dhcp_srv_info)) {
10249 hddLog(VOS_TRACE_LEVEL_ERROR,
10250 "%s: sme_set_dhcp_srv_offload fail!", __func__);
10251 vos_mem_free(dhcp_srv_info);
10252 return VOS_STATUS_E_FAILURE;
10253 }
10254
10255 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10256 "%s: enable DHCP Server offload successfully!", __func__);
10257
10258 vos_mem_free(dhcp_srv_info);
10259 return 0;
10260}
10261#endif /* DHCP_SERVER_OFFLOAD */
10262
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010263/*
10264 * hdd_modify_indoor_channel_state_flags() - modify wiphy flags and cds state
10265 * @wiphy_chan: wiphy channel number
10266 * @rfChannel: channel hw value
10267 * @disable: Disable/enable the flags
10268 *
10269 * Modify wiphy flags and cds state if channel is indoor.
10270 *
10271 * Return: void
10272 */
10273void hdd_modify_indoor_channel_state_flags(struct ieee80211_channel *wiphy_chan,
10274 v_U32_t rfChannel, bool disable)
10275{
10276 v_U32_t channelLoop;
10277 eRfChannels channelEnum = INVALID_RF_CHANNEL;
10278
10279 for (channelLoop = 0; channelLoop <= RF_CHAN_165; channelLoop++) {
10280
10281 if (rfChannels[channelLoop].channelNum == rfChannel) {
10282 channelEnum = (eRfChannels)channelLoop;
10283 break;
10284 }
10285 }
10286
10287 if (INVALID_RF_CHANNEL == channelEnum)
10288 return;
10289
10290 if (disable) {
10291 if (wiphy_chan->flags & IEEE80211_CHAN_INDOOR_ONLY) {
10292 wiphy_chan->flags |=
10293 IEEE80211_CHAN_DISABLED;
10294 regChannels[channelEnum].enabled =
10295 NV_CHANNEL_DISABLE;
10296 }
10297 } else {
10298 if (wiphy_chan->flags & IEEE80211_CHAN_INDOOR_ONLY) {
10299 wiphy_chan->flags &=
10300 ~IEEE80211_CHAN_DISABLED;
10301 /*
10302 * Indoor channels are marked as DFS
10303 * during regulatory processing
10304 */
10305
10306 regChannels[channelEnum].enabled =
10307 NV_CHANNEL_DFS;
10308 }
10309 }
10310
10311}
10312
10313void hdd_update_indoor_channel(hdd_context_t *hdd_ctx,
10314 bool disable)
10315{
10316 int band_num;
10317 int chan_num;
10318 v_U32_t rfChannel;
10319 struct ieee80211_channel *wiphy_chan;
10320 struct wiphy *wiphy;
10321
10322 ENTER();
10323 hddLog(VOS_TRACE_LEVEL_INFO, "disable: %d", disable);
10324
10325 wiphy = hdd_ctx->wiphy;
10326 for (band_num = 0; band_num < IEEE80211_NUM_BANDS; band_num++) {
10327
10328 if (wiphy->bands[band_num] == NULL)
10329 continue;
10330
10331 for (chan_num = 0;
10332 chan_num < wiphy->bands[band_num]->n_channels;
10333 chan_num++) {
10334
10335 wiphy_chan =
10336 &(wiphy->bands[band_num]->channels[chan_num]);
10337 rfChannel = wiphy->bands[band_num]->channels[chan_num].hw_value;
10338
10339 hdd_modify_indoor_channel_state_flags(wiphy_chan, rfChannel,
10340 disable);
10341 }
10342 }
10343 EXIT();
10344}
10345
10346
Jeff Johnson295189b2012-06-20 16:38:30 -070010347#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10348static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
10349 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010350#else
10351static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
10352 struct cfg80211_beacon_data *params,
10353 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010354 enum nl80211_hidden_ssid hidden_ssid,
10355 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010356#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010357{
10358 tsap_Config_t *pConfig;
10359 beacon_data_t *pBeacon = NULL;
10360 struct ieee80211_mgmt *pMgmt_frame;
10361 v_U8_t *pIe=NULL;
10362 v_U16_t capab_info;
10363 eCsrAuthType RSNAuthType;
10364 eCsrEncryptionType RSNEncryptType;
10365 eCsrEncryptionType mcRSNEncryptType;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010366 int status = VOS_STATUS_SUCCESS, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010367 tpWLAN_SAPEventCB pSapEventCallback;
10368 hdd_hostapd_state_t *pHostapdState;
Jeff Johnson295189b2012-06-20 16:38:30 -070010369 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010370 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010371 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010372 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -070010373 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -080010374 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +053010375 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -070010376 v_BOOL_t MFPCapable = VOS_FALSE;
10377 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +053010378 v_BOOL_t sapEnable11AC =
10379 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Kapil Gupta137ef892016-12-13 19:38:00 +053010380 u_int16_t prev_rsn_length = 0;
10381
Jeff Johnson295189b2012-06-20 16:38:30 -070010382 ENTER();
10383
Nitesh Shah9b066282017-06-06 18:05:52 +053010384 wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010385 iniConfig = pHddCtx->cfg_ini;
10386
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010387 /* Mark the indoor channel (passive) to disable */
10388 if (iniConfig->disable_indoor_channel) {
10389 hdd_update_indoor_channel(pHddCtx, true);
10390
10391 if (!VOS_IS_STATUS_SUCCESS(
10392 sme_update_channel_list((tpAniSirGlobal)pHddCtx->hHal))) {
10393 hdd_update_indoor_channel(pHddCtx, false);
10394 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
10395 FL("Can't start BSS: update channel list failed"));
10396 return eHAL_STATUS_FAILURE;
10397 }
10398 }
10399
Jeff Johnson295189b2012-06-20 16:38:30 -070010400 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
10401
10402 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
10403
10404 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
10405
10406 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
10407
10408 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
10409
10410 //channel is already set in the set_channel Call back
10411 //pConfig->channel = pCommitConfig->channel;
10412
10413 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010414 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -070010415 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
10416
10417 pConfig->dtim_period = pBeacon->dtim_period;
10418
Arif Hussain6d2a3322013-11-17 19:50:10 -080010419 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -070010420 pConfig->dtim_period);
10421
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -080010422 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -070010423 {
10424 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070010425 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +053010426 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
10427 {
10428 tANI_BOOLEAN restartNeeded;
10429 pConfig->ieee80211d = 1;
10430 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
10431 sme_setRegInfo(hHal, pConfig->countryCode);
10432 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
10433 }
10434 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -070010435 {
Jeff Johnson32d95a32012-09-10 13:15:23 -070010436 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -070010437 pConfig->ieee80211d = 1;
10438 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
10439 sme_setRegInfo(hHal, pConfig->countryCode);
10440 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -070010441 }
Jeff Johnson32d95a32012-09-10 13:15:23 -070010442 else
10443 {
10444 pConfig->ieee80211d = 0;
10445 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010446 /*
10447 * If auto channel is configured i.e. channel is 0,
10448 * so skip channel validation.
10449 */
10450 if( AUTO_CHANNEL_SELECT != pConfig->channel )
10451 {
10452 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
10453 {
10454 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010455 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010456 return -EINVAL;
10457 }
10458 }
10459 else
10460 {
10461 if(1 != pHddCtx->is_dynamic_channel_range_set)
10462 {
10463 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
10464 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
10465 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
10466 }
10467 pHddCtx->is_dynamic_channel_range_set = 0;
10468 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010469 }
Jeff Johnson32d95a32012-09-10 13:15:23 -070010470 else
Jeff Johnson295189b2012-06-20 16:38:30 -070010471 {
10472 pConfig->ieee80211d = 0;
10473 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010474
10475#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10476 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
10477 pConfig->authType = eSAP_OPEN_SYSTEM;
10478 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
10479 pConfig->authType = eSAP_SHARED_KEY;
10480 else
10481 pConfig->authType = eSAP_AUTO_SWITCH;
10482#else
10483 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
10484 pConfig->authType = eSAP_OPEN_SYSTEM;
10485 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
10486 pConfig->authType = eSAP_SHARED_KEY;
10487 else
10488 pConfig->authType = eSAP_AUTO_SWITCH;
10489#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010490
10491 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010492
10493 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -070010494 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
Agrawal Ashisha8e8a722016-10-18 19:07:45 +053010495#ifdef SAP_AUTH_OFFLOAD
10496 /* In case of sap offload, hostapd.conf is configuted with open mode and
10497 * security is configured from ini file. Due to open mode in hostapd.conf
10498 * privacy bit is set to false which will result in not sending,
10499 * data packets as encrypted.
10500 * If enable_sap_auth_offload is enabled in ini and
10501 * sap_auth_offload_sec_type is type of WPA2-PSK,
10502 * driver will set privacy bit to 1.
10503 */
10504 if (pHddCtx->cfg_ini->enable_sap_auth_offload &&
10505 pHddCtx->cfg_ini->sap_auth_offload_sec_type)
10506 pConfig->privacy = VOS_TRUE;
10507#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010508
10509 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
10510
10511 /*Set wps station to configured*/
10512 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
10513
10514 if(pIe)
10515 {
10516 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
10517 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010518 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -070010519 return -EINVAL;
10520 }
10521 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
10522 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -070010523 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -070010524 /* Check 15 bit of WPS IE as it contain information for wps state
10525 * WPS state
10526 */
10527 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
10528 {
10529 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
10530 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
10531 {
10532 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
10533 }
10534 }
10535 }
10536 else
10537 {
10538 pConfig->wps_state = SAP_WPS_DISABLED;
10539 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010540 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -070010541
c_hpothufe599e92014-06-16 11:38:55 +053010542 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
10543 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
10544 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
10545 eCSR_ENCRYPT_TYPE_NONE;
10546
Jeff Johnson295189b2012-06-20 16:38:30 -070010547 pConfig->RSNWPAReqIELength = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +053010548 memset(&pConfig->RSNWPAReqIE[0], 0, sizeof(pConfig->RSNWPAReqIE));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010549 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070010550 WLAN_EID_RSN);
10551 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010552 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010553 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053010554 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
10555 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
10556 pConfig->RSNWPAReqIELength);
10557 else
10558 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
10559 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010560 /* The actual processing may eventually be more extensive than
10561 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -070010562 * by the app.
10563 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010564 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070010565 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
10566 &RSNEncryptType,
10567 &mcRSNEncryptType,
10568 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080010569 &MFPCapable,
10570 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053010571 pConfig->RSNWPAReqIE[1]+2,
10572 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010573
10574 if( VOS_STATUS_SUCCESS == status )
10575 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010576 /* Now copy over all the security attributes you have
10577 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070010578 * */
10579 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
10580 pConfig->mcRSNEncryptType = mcRSNEncryptType;
10581 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
10582 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010583 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080010584 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070010585 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
10586 }
10587 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010588
Jeff Johnson295189b2012-06-20 16:38:30 -070010589 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
10590 pBeacon->tail, pBeacon->tail_len);
10591
10592 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
10593 {
Kapil Gupta137ef892016-12-13 19:38:00 +053010594 if (pConfig->RSNWPAReqIE[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070010595 {
10596 /*Mixed mode WPA/WPA2*/
Kapil Gupta137ef892016-12-13 19:38:00 +053010597 prev_rsn_length = pConfig->RSNWPAReqIELength;
Jeff Johnson295189b2012-06-20 16:38:30 -070010598 pConfig->RSNWPAReqIELength += pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053010599 if (pConfig->RSNWPAReqIELength <=
10600 (sizeof(pConfig->RSNWPAReqIE) - prev_rsn_length))
10601 memcpy(&pConfig->RSNWPAReqIE[0] + prev_rsn_length, pIe,
10602 pIe[1] + 2);
10603 else
10604 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
10605 pConfig->RSNWPAReqIELength);
10606
Jeff Johnson295189b2012-06-20 16:38:30 -070010607 }
10608 else
10609 {
10610 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053010611 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
10612 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
10613 pConfig->RSNWPAReqIELength);
10614 else
10615 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
10616 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010617 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070010618 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
10619 &RSNEncryptType,
10620 &mcRSNEncryptType,
10621 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080010622 &MFPCapable,
10623 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053010624 pConfig->RSNWPAReqIE[1]+2,
10625 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010626
10627 if( VOS_STATUS_SUCCESS == status )
10628 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010629 /* Now copy over all the security attributes you have
10630 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070010631 * */
10632 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
10633 pConfig->mcRSNEncryptType = mcRSNEncryptType;
10634 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
10635 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010636 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080010637 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070010638 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
10639 }
10640 }
10641 }
10642
Kapil Gupta137ef892016-12-13 19:38:00 +053010643 if (pConfig->RSNWPAReqIELength > sizeof(pConfig->RSNWPAReqIE)) {
Jeff Johnson4416a782013-03-25 14:17:50 -070010644 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
10645 return -EINVAL;
10646 }
10647
Jeff Johnson295189b2012-06-20 16:38:30 -070010648 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
10649
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010650#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010651 if (params->ssid != NULL)
10652 {
10653 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
10654 pConfig->SSIDinfo.ssid.length = params->ssid_len;
10655 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
10656 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
10657 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010658#else
10659 if (ssid != NULL)
10660 {
10661 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
10662 pConfig->SSIDinfo.ssid.length = ssid_len;
10663 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
10664 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
10665 }
10666#endif
10667
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010668 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -070010669 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010670
Jeff Johnson295189b2012-06-20 16:38:30 -070010671 /* default value */
10672 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
10673 pConfig->num_accept_mac = 0;
10674 pConfig->num_deny_mac = 0;
10675
10676 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
10677 pBeacon->tail, pBeacon->tail_len);
10678
10679 /* pIe for black list is following form:
10680 type : 1 byte
10681 length : 1 byte
10682 OUI : 4 bytes
10683 acl type : 1 byte
10684 no of mac addr in black list: 1 byte
10685 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010686 */
10687 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010688 {
10689 pConfig->SapMacaddr_acl = pIe[6];
10690 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080010691 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010692 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053010693 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
10694 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010695 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
10696 for (i = 0; i < pConfig->num_deny_mac; i++)
10697 {
10698 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
10699 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010700 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010701 }
10702 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
10703 pBeacon->tail, pBeacon->tail_len);
10704
10705 /* pIe for white list is following form:
10706 type : 1 byte
10707 length : 1 byte
10708 OUI : 4 bytes
10709 acl type : 1 byte
10710 no of mac addr in white list: 1 byte
10711 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010712 */
10713 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010714 {
10715 pConfig->SapMacaddr_acl = pIe[6];
10716 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080010717 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010718 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053010719 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
10720 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010721 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
10722 for (i = 0; i < pConfig->num_accept_mac; i++)
10723 {
10724 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
10725 acl_entry++;
10726 }
10727 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053010728
Jeff Johnson295189b2012-06-20 16:38:30 -070010729 wlan_hdd_set_sapHwmode(pHostapdAdapter);
10730
Jeff Johnsone7245742012-09-05 17:12:55 -070010731#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080010732 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +053010733 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
10734 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +053010735 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
10736 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080010737 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
10738 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +053010739 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
10740 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -070010741 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053010742 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -070010743 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +053010744 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070010745
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010746 /* If ACS disable and selected channel <= 14
10747 * OR
10748 * ACS enabled and ACS operating band is choosen as 2.4
10749 * AND
10750 * VHT in 2.4G Disabled
10751 * THEN
10752 * Fallback to 11N mode
10753 */
10754 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
10755 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +053010756 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010757 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -070010758 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053010759 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
10760 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070010761 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
10762 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010763 }
10764#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010765
Jeff Johnson295189b2012-06-20 16:38:30 -070010766 // ht_capab is not what the name conveys,this is used for protection bitmap
10767 pConfig->ht_capab =
10768 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
10769
Kapil Gupta137ef892016-12-13 19:38:00 +053010770 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -070010771 {
10772 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
10773 return -EINVAL;
10774 }
10775
10776 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010777 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -070010778 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
10779 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010780 pConfig->obssProtEnabled =
10781 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -070010782
Chet Lanctot8cecea22014-02-11 19:09:36 -080010783#ifdef WLAN_FEATURE_11W
10784 pConfig->mfpCapable = MFPCapable;
10785 pConfig->mfpRequired = MFPRequired;
10786 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
10787 pConfig->mfpCapable, pConfig->mfpRequired);
10788#endif
10789
Arif Hussain6d2a3322013-11-17 19:50:10 -080010790 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -070010791 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -080010792 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
10793 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
10794 (int)pConfig->channel);
10795 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
10796 pConfig->SapHw_mode, pConfig->privacy,
10797 pConfig->authType);
10798 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
10799 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
10800 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
10801 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -070010802
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010803 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -070010804 {
10805 //Bss already started. just return.
10806 //TODO Probably it should update some beacon params.
10807 hddLog( LOGE, "Bss Already started...Ignore the request");
10808 EXIT();
10809 return 0;
10810 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010811
Agarwal Ashish51325b52014-06-16 16:50:49 +053010812 if (vos_max_concurrent_connections_reached()) {
10813 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10814 return -EINVAL;
10815 }
10816
Jeff Johnson295189b2012-06-20 16:38:30 -070010817 pConfig->persona = pHostapdAdapter->device_mode;
10818
Peng Xu2446a892014-09-05 17:21:18 +053010819 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
10820 if ( NULL != psmeConfig)
10821 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053010822 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +053010823 sme_GetConfigParam(hHal, psmeConfig);
10824 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053010825#ifdef WLAN_FEATURE_AP_HT40_24G
10826 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
10827 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
10828 && pHddCtx->cfg_ini->apHT40_24GEnabled)
10829 {
10830 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
10831 sme_UpdateConfig (hHal, psmeConfig);
10832 }
10833#endif
Peng Xu2446a892014-09-05 17:21:18 +053010834 vos_mem_free(psmeConfig);
10835 }
Peng Xuafc34e32014-09-25 13:23:55 +053010836 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +053010837
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010838 set_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
10839
Jeff Johnson295189b2012-06-20 16:38:30 -070010840 pSapEventCallback = hdd_hostapd_SAPEventCB;
10841 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
10842 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
10843 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010844 hddLog(LOGE,FL("SAP Start Bss fail"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010845 ret = -EINVAL;
10846 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070010847 }
10848
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010849 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -070010850 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
10851
10852 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010853
Jeff Johnson295189b2012-06-20 16:38:30 -070010854 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010855 {
10856 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010857 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -070010858 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070010859 VOS_ASSERT(0);
10860 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010861
Jeff Johnson295189b2012-06-20 16:38:30 -070010862 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053010863 if (WLANSAP_get_sessionId(pVosContext, &pHostapdAdapter->sessionId) !=
10864 VOS_STATUS_SUCCESS)
10865 {
10866 hddLog(LOGE,FL("Fail to get Softap sessionID"));
10867 VOS_ASSERT(0);
10868 }
Kaushik, Sushantf6070802014-10-15 15:09:23 +053010869 /* Initialize WMM configuation */
10870 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010871 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010872
Anurag Chouhan83026002016-12-13 22:46:21 +053010873#ifdef DHCP_SERVER_OFFLOAD
10874 /* set dhcp server offload */
10875 if (iniConfig->enable_dhcp_srv_offload &&
10876 sme_IsFeatureSupportedByFW(SAP_OFFLOADS)) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010877 vos_event_reset(&pHostapdAdapter->dhcp_status.vos_event);
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010878 status = wlan_hdd_set_dhcp_server_offload(pHostapdAdapter, false);
Anurag Chouhan83026002016-12-13 22:46:21 +053010879 if (!VOS_IS_STATUS_SUCCESS(status))
10880 {
10881 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10882 ("HDD DHCP Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010883 vos_event_reset(&pHostapdState->vosEvent);
10884 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
10885 status = vos_wait_single_event(&pHostapdState->vosEvent,
10886 10000);
10887 if (!VOS_IS_STATUS_SUCCESS(status)) {
10888 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010889 ret = -EINVAL;
10890 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010891 }
10892 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010893 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010894 status = vos_wait_single_event(&pHostapdAdapter->dhcp_status.vos_event, 2000);
10895 if (!VOS_IS_STATUS_SUCCESS(status) || pHostapdAdapter->dhcp_status.dhcp_offload_status)
10896 {
10897 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10898 ("ERROR: DHCP HDD vos wait for single_event failed!! %d"),
10899 pHostapdAdapter->dhcp_status.dhcp_offload_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010900 vos_event_reset(&pHostapdState->vosEvent);
10901 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
10902 status = vos_wait_single_event(&pHostapdState->vosEvent,
10903 10000);
10904 if (!VOS_IS_STATUS_SUCCESS(status)) {
10905 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010906 ret = -EINVAL;
10907 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010908 }
10909 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010910 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010911#ifdef MDNS_OFFLOAD
10912 if (iniConfig->enable_mdns_offload) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010913 vos_event_reset(&pHostapdAdapter->mdns_status.vos_event);
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010914 status = wlan_hdd_set_mdns_offload(pHostapdAdapter);
10915 if (VOS_IS_STATUS_SUCCESS(status))
10916 {
10917 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10918 ("HDD MDNS Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010919 vos_event_reset(&pHostapdState->vosEvent);
10920 if (VOS_STATUS_SUCCESS ==
10921 WLANSAP_StopBss(pHddCtx->pvosContext)) {
10922 status = vos_wait_single_event(&pHostapdState->vosEvent,
10923 10000);
10924 if (!VOS_IS_STATUS_SUCCESS(status)) {
10925 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010926 ret = -EINVAL;
10927 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010928 }
10929 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010930 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010931 status = vos_wait_single_event(&pHostapdAdapter->
10932 mdns_status.vos_event, 2000);
10933 if (!VOS_IS_STATUS_SUCCESS(status) ||
10934 pHostapdAdapter->mdns_status.mdns_enable_status ||
10935 pHostapdAdapter->mdns_status.mdns_fqdn_status ||
10936 pHostapdAdapter->mdns_status.mdns_resp_status)
10937 {
10938 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10939 ("MDNS HDD vos wait for single_event failed!! enable %d fqdn %d resp %d"),
10940 pHostapdAdapter->mdns_status.mdns_enable_status,
10941 pHostapdAdapter->mdns_status.mdns_fqdn_status,
10942 pHostapdAdapter->mdns_status.mdns_resp_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010943 vos_event_reset(&pHostapdState->vosEvent);
10944 if (VOS_STATUS_SUCCESS ==
10945 WLANSAP_StopBss(pHddCtx->pvosContext)) {
10946 status = vos_wait_single_event(&pHostapdState->vosEvent,
10947 10000);
10948 if (!VOS_IS_STATUS_SUCCESS(status)) {
10949 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010950 ret = -EINVAL;
10951 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010952 }
10953 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010954 }
10955 }
10956#endif /* MDNS_OFFLOAD */
10957 } else {
10958 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10959 ("DHCP Disabled ini %d, FW %d"),
10960 iniConfig->enable_dhcp_srv_offload,
10961 sme_IsFeatureSupportedByFW(SAP_OFFLOADS));
Anurag Chouhan83026002016-12-13 22:46:21 +053010962 }
10963#endif /* DHCP_SERVER_OFFLOAD */
10964
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010965#ifdef WLAN_FEATURE_P2P_DEBUG
10966 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
10967 {
10968 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
10969 {
10970 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
10971 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -080010972 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010973 }
10974 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
10975 {
10976 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
10977 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -080010978 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010979 }
10980 }
10981#endif
Ashish Kumar Dhanotiya42aa5152017-01-03 20:25:57 +053010982 /* Check and restart SAP if it is on Unsafe channel */
10983 hdd_check_for_unsafe_ch(pHostapdAdapter, pHddCtx);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010984
Jeff Johnson295189b2012-06-20 16:38:30 -070010985 pHostapdState->bCommit = TRUE;
10986 EXIT();
10987
10988 return 0;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010989error:
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010990 /* Revert the indoor to passive marking if START BSS fails */
10991 if (iniConfig->disable_indoor_channel) {
10992 hdd_update_indoor_channel(pHddCtx, false);
10993 sme_update_channel_list((tpAniSirGlobal)pHddCtx->hHal);
10994 }
10995
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010996 clear_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
10997 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010998}
10999
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011000#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011001static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011002 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070011003 struct beacon_parameters *params)
11004{
11005 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011006 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011007 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011008
11009 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011010
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011011 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11012 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
11013 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011014 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
11015 hdd_device_modetoString(pAdapter->device_mode),
11016 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011017
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011018 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11019 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011020 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011021 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011022 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011023 }
11024
Agarwal Ashish51325b52014-06-16 16:50:49 +053011025 if (vos_max_concurrent_connections_reached()) {
11026 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11027 return -EINVAL;
11028 }
11029
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011030 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011031 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011032 )
11033 {
11034 beacon_data_t *old,*new;
11035
11036 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011037
Jeff Johnson295189b2012-06-20 16:38:30 -070011038 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011039 {
11040 hddLog(VOS_TRACE_LEVEL_WARN,
11041 FL("already beacon info added to session(%d)"),
11042 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011043 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011044 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011045
11046 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
11047
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011048 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -070011049 {
11050 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011051 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011052 return -EINVAL;
11053 }
11054
11055 pAdapter->sessionCtx.ap.beacon = new;
11056
11057 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
11058 }
11059
11060 EXIT();
11061 return status;
11062}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011063
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011064static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
11065 struct net_device *dev,
11066 struct beacon_parameters *params)
11067{
11068 int ret;
11069
11070 vos_ssr_protect(__func__);
11071 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
11072 vos_ssr_unprotect(__func__);
11073
11074 return ret;
11075}
11076
11077static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011078 struct net_device *dev,
11079 struct beacon_parameters *params)
11080{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011081 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011082 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11083 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011084 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011085
11086 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011087
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011088 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11089 TRACE_CODE_HDD_CFG80211_SET_BEACON,
11090 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
11091 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11092 __func__, hdd_device_modetoString(pAdapter->device_mode),
11093 pAdapter->device_mode);
11094
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011095 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11096 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011097 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011098 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011099 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011100 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011101
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011102 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011103 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011104 )
Jeff Johnson295189b2012-06-20 16:38:30 -070011105 {
11106 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011107
Jeff Johnson295189b2012-06-20 16:38:30 -070011108 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011109
Jeff Johnson295189b2012-06-20 16:38:30 -070011110 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011111 {
11112 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11113 FL("session(%d) old and new heads points to NULL"),
11114 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011115 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011116 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011117
11118 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
11119
11120 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011121 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011122 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011123 return -EINVAL;
11124 }
11125
11126 pAdapter->sessionCtx.ap.beacon = new;
11127
11128 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
11129 }
11130
11131 EXIT();
11132 return status;
11133}
11134
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011135static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
11136 struct net_device *dev,
11137 struct beacon_parameters *params)
11138{
11139 int ret;
11140
11141 vos_ssr_protect(__func__);
11142 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
11143 vos_ssr_unprotect(__func__);
11144
11145 return ret;
11146}
11147
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011148#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11149
11150#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011151static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011152 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011153#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011154static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011155 struct net_device *dev)
11156#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011157{
11158 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -070011159 hdd_context_t *pHddCtx = NULL;
11160 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011161 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011162 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011163
11164 ENTER();
11165
11166 if (NULL == pAdapter)
11167 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011168 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011169 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011170 return -ENODEV;
11171 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011172
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011173 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11174 TRACE_CODE_HDD_CFG80211_STOP_AP,
11175 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011176 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11177 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011178 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011179 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011180 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -070011181 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011182
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011183 pScanInfo = &pHddCtx->scan_info;
11184
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011185 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11186 __func__, hdd_device_modetoString(pAdapter->device_mode),
11187 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011188
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011189 ret = wlan_hdd_scan_abort(pAdapter);
11190
Girish Gowli4bf7a632014-06-12 13:42:11 +053011191 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -070011192 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011193 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11194 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011195
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011196 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -070011197 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011198 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11199 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -080011200
Jeff Johnsone7245742012-09-05 17:12:55 -070011201 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011202 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -070011203 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011204 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070011205 }
11206
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053011207 /* Delete all associated STAs before stopping AP/P2P GO */
11208 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +053011209 hdd_hostapd_stop(dev);
11210
Jeff Johnson295189b2012-06-20 16:38:30 -070011211 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011212 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011213 )
11214 {
11215 beacon_data_t *old;
11216
11217 old = pAdapter->sessionCtx.ap.beacon;
11218
11219 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011220 {
11221 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11222 FL("session(%d) beacon data points to NULL"),
11223 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011224 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011225 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011226
Jeff Johnson295189b2012-06-20 16:38:30 -070011227 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011228
11229 mutex_lock(&pHddCtx->sap_lock);
11230 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
11231 {
Jeff Johnson4416a782013-03-25 14:17:50 -070011232 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011233 {
11234 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11235
11236 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
11237
11238 if (!VOS_IS_STATUS_SUCCESS(status))
11239 {
11240 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011241 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -070011242 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011243 }
11244 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011245 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011246 /* BSS stopped, clear the active sessions for this device mode */
11247 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011248 }
11249 mutex_unlock(&pHddCtx->sap_lock);
11250
11251 if(status != VOS_STATUS_SUCCESS)
11252 {
11253 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011254 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011255 return -EINVAL;
11256 }
11257
Jeff Johnson4416a782013-03-25 14:17:50 -070011258 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070011259 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
11260 ==eHAL_STATUS_FAILURE)
11261 {
11262 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011263 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070011264 }
11265
Jeff Johnson4416a782013-03-25 14:17:50 -070011266 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070011267 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
11268 eANI_BOOLEAN_FALSE) )
11269 {
11270 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011271 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070011272 }
11273
11274 // Reset WNI_CFG_PROBE_RSP Flags
11275 wlan_hdd_reset_prob_rspies(pAdapter);
11276
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011277 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
11278
Jeff Johnson295189b2012-06-20 16:38:30 -070011279 pAdapter->sessionCtx.ap.beacon = NULL;
11280 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011281#ifdef WLAN_FEATURE_P2P_DEBUG
11282 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
11283 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
11284 {
11285 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
11286 "GO got removed");
11287 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
11288 }
11289#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011290 }
11291 EXIT();
11292 return status;
11293}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011294
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011295#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11296static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
11297 struct net_device *dev)
11298{
11299 int ret;
11300
11301 vos_ssr_protect(__func__);
11302 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
11303 vos_ssr_unprotect(__func__);
11304
11305 return ret;
11306}
11307#else
11308static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
11309 struct net_device *dev)
11310{
11311 int ret;
11312
11313 vos_ssr_protect(__func__);
11314 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
11315 vos_ssr_unprotect(__func__);
11316
11317 return ret;
11318}
11319#endif
11320
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011321#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
11322
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011323static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011324 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011325 struct cfg80211_ap_settings *params)
11326{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011327 hdd_adapter_t *pAdapter;
11328 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011329 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011330
11331 ENTER();
11332
Girish Gowlib143d7a2015-02-18 19:39:55 +053011333 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070011334 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011335 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +053011336 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011337 return -ENODEV;
11338 }
11339
11340 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
11341 if (NULL == pAdapter)
11342 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011343 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011344 "%s: HDD adapter is Null", __func__);
11345 return -ENODEV;
11346 }
11347
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011348 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11349 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
11350 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011351 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
11352 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011353 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011354 "%s: HDD adapter magic is invalid", __func__);
11355 return -ENODEV;
11356 }
11357
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011358 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
11359
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011360 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011361 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011362 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011363 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011364 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011365 }
11366
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011367 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
11368 __func__, hdd_device_modetoString(pAdapter->device_mode),
11369 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011370
11371 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011372 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011373 )
11374 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011375 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011376
11377 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011378
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011379 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011380 {
11381 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
11382 FL("already beacon info added to session(%d)"),
11383 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011384 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011385 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011386
Girish Gowlib143d7a2015-02-18 19:39:55 +053011387#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11388 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
11389 &new,
11390 &params->beacon);
11391#else
11392 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
11393 &new,
11394 &params->beacon,
11395 params->dtim_period);
11396#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011397
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011398 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011399 {
11400 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011401 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011402 return -EINVAL;
11403 }
11404 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -080011405#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -070011406 wlan_hdd_cfg80211_set_channel(wiphy, dev,
11407#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
11408 params->channel, params->channel_type);
11409#else
11410 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
11411#endif
Viral Modi3a32cc52013-02-08 11:14:52 -080011412#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011413 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053011414 params->ssid_len, params->hidden_ssid,
11415 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011416 }
11417
11418 EXIT();
11419 return status;
11420}
11421
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011422static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
11423 struct net_device *dev,
11424 struct cfg80211_ap_settings *params)
11425{
11426 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011427
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011428 vos_ssr_protect(__func__);
11429 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
11430 vos_ssr_unprotect(__func__);
11431
11432 return ret;
11433}
11434
11435static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011436 struct net_device *dev,
11437 struct cfg80211_beacon_data *params)
11438{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011439 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011440 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011441 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011442
11443 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011444
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011445 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11446 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
11447 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -080011448 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011449 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011450
11451 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11452 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011453 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070011454 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011455 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070011456 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011457
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011458 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011459 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011460 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011461 {
11462 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011463
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011464 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011465
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011466 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011467 {
11468 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11469 FL("session(%d) beacon data points to NULL"),
11470 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011471 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011472 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011473
11474 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
11475
11476 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011477 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011478 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011479 return -EINVAL;
11480 }
11481
11482 pAdapter->sessionCtx.ap.beacon = new;
11483
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053011484 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
11485 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011486 }
11487
11488 EXIT();
11489 return status;
11490}
11491
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011492static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
11493 struct net_device *dev,
11494 struct cfg80211_beacon_data *params)
11495{
11496 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011497
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011498 vos_ssr_protect(__func__);
11499 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
11500 vos_ssr_unprotect(__func__);
11501
11502 return ret;
11503}
11504
11505#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011506
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011507static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011508 struct net_device *dev,
11509 struct bss_parameters *params)
11510{
11511 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011512 hdd_context_t *pHddCtx;
11513 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011514
11515 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011516
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011517 if (NULL == pAdapter)
11518 {
11519 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11520 "%s: HDD adapter is Null", __func__);
11521 return -ENODEV;
11522 }
11523 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011524 ret = wlan_hdd_validate_context(pHddCtx);
11525 if (0 != ret)
11526 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011527 return ret;
11528 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011529 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11530 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
11531 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011532 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11533 __func__, hdd_device_modetoString(pAdapter->device_mode),
11534 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011535
11536 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011537 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011538 )
Jeff Johnson295189b2012-06-20 16:38:30 -070011539 {
11540 /* ap_isolate == -1 means that in change bss, upper layer doesn't
11541 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011542 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -070011543 {
11544 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011545 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011546 }
11547
11548 EXIT();
11549 return 0;
11550}
11551
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011552static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
11553 struct net_device *dev,
11554 struct bss_parameters *params)
11555{
11556 int ret;
11557
11558 vos_ssr_protect(__func__);
11559 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
11560 vos_ssr_unprotect(__func__);
11561
11562 return ret;
11563}
Kiet Lam10841362013-11-01 11:36:50 +053011564/* FUNCTION: wlan_hdd_change_country_code_cd
11565* to wait for contry code completion
11566*/
11567void* wlan_hdd_change_country_code_cb(void *pAdapter)
11568{
11569 hdd_adapter_t *call_back_pAdapter = pAdapter;
11570 complete(&call_back_pAdapter->change_country_code);
11571 return NULL;
11572}
11573
Jeff Johnson295189b2012-06-20 16:38:30 -070011574/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053011575 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -070011576 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
11577 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053011578int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011579 struct net_device *ndev,
11580 enum nl80211_iftype type,
11581 u32 *flags,
11582 struct vif_params *params
11583 )
11584{
11585 struct wireless_dev *wdev;
11586 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011587 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -070011588 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011589 tCsrRoamProfile *pRoamProfile = NULL;
11590 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011591 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011592 eMib_dot11DesiredBssType connectedBssType;
11593 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011594 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011595
11596 ENTER();
11597
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011598 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011599 {
11600 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11601 "%s: Adapter context is null", __func__);
11602 return VOS_STATUS_E_FAILURE;
11603 }
11604
11605 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11606 if (!pHddCtx)
11607 {
11608 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11609 "%s: HDD context is null", __func__);
11610 return VOS_STATUS_E_FAILURE;
11611 }
11612
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011613 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11614 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
11615 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011616 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011617 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011618 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011619 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011620 }
11621
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011622 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11623 __func__, hdd_device_modetoString(pAdapter->device_mode),
11624 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011625
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053011626 if (pHddCtx->concurrency_mode == VOS_STA_MON) {
11627 hddLog(VOS_TRACE_LEVEL_FATAL,
11628 "%s: STA + MON is in progress, cannot change interface",
11629 __func__);
11630 }
11631
Agarwal Ashish51325b52014-06-16 16:50:49 +053011632 if (vos_max_concurrent_connections_reached()) {
11633 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11634 return -EINVAL;
11635 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011636 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070011637 wdev = ndev->ieee80211_ptr;
11638
11639#ifdef WLAN_BTAMP_FEATURE
11640 if((NL80211_IFTYPE_P2P_CLIENT == type)||
11641 (NL80211_IFTYPE_ADHOC == type)||
11642 (NL80211_IFTYPE_AP == type)||
11643 (NL80211_IFTYPE_P2P_GO == type))
11644 {
11645 pHddCtx->isAmpAllowed = VOS_FALSE;
11646 // stop AMP traffic
11647 status = WLANBAP_StopAmp();
11648 if(VOS_STATUS_SUCCESS != status )
11649 {
11650 pHddCtx->isAmpAllowed = VOS_TRUE;
11651 hddLog(VOS_TRACE_LEVEL_FATAL,
11652 "%s: Failed to stop AMP", __func__);
11653 return -EINVAL;
11654 }
11655 }
11656#endif //WLAN_BTAMP_FEATURE
11657 /* Reset the current device mode bit mask*/
11658 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
11659
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +053011660 if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
11661 ((type == NL80211_IFTYPE_P2P_CLIENT) ||
11662 (type == NL80211_IFTYPE_P2P_GO)))
11663 {
11664 /* Notify Mode change in case of concurrency.
11665 * Below function invokes TDLS teardown Functionality Since TDLS is
11666 * not Supported in case of concurrency i.e Once P2P session
11667 * is detected disable offchannel and teardown TDLS links
11668 */
11669 hddLog(LOG1,
11670 FL("Device mode = %d Interface type = %d"),
11671 pAdapter->device_mode, type);
11672 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
11673 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +053011674
Jeff Johnson295189b2012-06-20 16:38:30 -070011675 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070011676 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -070011677 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -070011678 )
11679 {
11680 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011681 if (!pWextState)
11682 {
11683 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11684 "%s: pWextState is null", __func__);
11685 return VOS_STATUS_E_FAILURE;
11686 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011687 pRoamProfile = &pWextState->roamProfile;
11688 LastBSSType = pRoamProfile->BSSType;
11689
11690 switch (type)
11691 {
11692 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070011693 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070011694 hddLog(VOS_TRACE_LEVEL_INFO,
11695 "%s: setting interface Type to INFRASTRUCTURE", __func__);
11696 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -070011697#ifdef WLAN_FEATURE_11AC
11698 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
11699 {
11700 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
11701 }
11702#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011703 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -070011704 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011705 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080011706 //Check for sub-string p2p to confirm its a p2p interface
11707 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011708 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +053011709#ifdef FEATURE_WLAN_TDLS
11710 mutex_lock(&pHddCtx->tdls_lock);
11711 wlan_hdd_tdls_exit(pAdapter, TRUE);
11712 mutex_unlock(&pHddCtx->tdls_lock);
11713#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -080011714 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
11715 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
11716 }
11717 else
11718 {
11719 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070011720 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080011721 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011722 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +053011723
Jeff Johnson295189b2012-06-20 16:38:30 -070011724 case NL80211_IFTYPE_ADHOC:
11725 hddLog(VOS_TRACE_LEVEL_INFO,
11726 "%s: setting interface Type to ADHOC", __func__);
11727 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
11728 pRoamProfile->phyMode =
11729 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -070011730 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011731 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +053011732 hdd_set_ibss_ops( pAdapter );
11733 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +053011734
11735 status = hdd_sta_id_hash_attach(pAdapter);
11736 if (VOS_STATUS_SUCCESS != status) {
11737 hddLog(VOS_TRACE_LEVEL_ERROR,
11738 FL("Failed to initialize hash for IBSS"));
11739 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011740 break;
11741
11742 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070011743 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070011744 {
11745 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
11746 "%s: setting interface Type to %s", __func__,
11747 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
11748
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080011749 //Cancel any remain on channel for GO mode
11750 if (NL80211_IFTYPE_P2P_GO == type)
11751 {
11752 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
11753 }
Mohit Khanna0f232092012-09-11 14:46:08 -070011754 if (NL80211_IFTYPE_AP == type)
11755 {
11756 /* As Loading WLAN Driver one interface being created for p2p device
11757 * address. This will take one HW STA and the max number of clients
11758 * that can connect to softAP will be reduced by one. so while changing
11759 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
11760 * interface as it is not required in SoftAP mode.
11761 */
11762
11763 // Get P2P Adapter
11764 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
11765
11766 if (pP2pAdapter)
11767 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053011768 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +053011769 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -070011770 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
11771 }
11772 }
Swaroop Goltia2e32212014-04-09 23:37:33 +053011773 //Disable IMPS & BMPS for SAP/GO
11774 if(VOS_STATUS_E_FAILURE ==
11775 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
11776 {
11777 //Fail to Exit BMPS
11778 VOS_ASSERT(0);
11779 }
Deepthi Gowri500fc472014-08-11 19:53:10 +053011780
11781 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
11782
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011783#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -070011784
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011785 /* A Mutex Lock is introduced while changing the mode to
11786 * protect the concurrent access for the Adapters by TDLS
11787 * module.
11788 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011789 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011790#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011791 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +053011792 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011793 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -070011794 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
11795 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011796#ifdef FEATURE_WLAN_TDLS
11797 mutex_unlock(&pHddCtx->tdls_lock);
11798#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070011799 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
11800 (pConfig->apRandomBssidEnabled))
11801 {
11802 /* To meet Android requirements create a randomized
11803 MAC address of the form 02:1A:11:Fx:xx:xx */
11804 get_random_bytes(&ndev->dev_addr[3], 3);
11805 ndev->dev_addr[0] = 0x02;
11806 ndev->dev_addr[1] = 0x1A;
11807 ndev->dev_addr[2] = 0x11;
11808 ndev->dev_addr[3] |= 0xF0;
11809 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
11810 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -080011811 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
11812 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070011813 }
11814
Jeff Johnson295189b2012-06-20 16:38:30 -070011815 hdd_set_ap_ops( pAdapter->dev );
11816
Kiet Lam10841362013-11-01 11:36:50 +053011817 /* This is for only SAP mode where users can
11818 * control country through ini.
11819 * P2P GO follows station country code
11820 * acquired during the STA scanning. */
11821 if((NL80211_IFTYPE_AP == type) &&
11822 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
11823 {
11824 int status = 0;
11825 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
11826 "%s: setting country code from INI ", __func__);
11827 init_completion(&pAdapter->change_country_code);
11828 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
11829 (void *)(tSmeChangeCountryCallback)
11830 wlan_hdd_change_country_code_cb,
11831 pConfig->apCntryCode, pAdapter,
11832 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053011833 eSIR_FALSE,
11834 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +053011835 if (eHAL_STATUS_SUCCESS == status)
11836 {
11837 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011838 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +053011839 &pAdapter->change_country_code,
11840 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011841 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +053011842 {
11843 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011844 FL("SME Timed out while setting country code %ld"),
11845 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -080011846
11847 if (pHddCtx->isLogpInProgress)
11848 {
11849 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11850 "%s: LOGP in Progress. Ignore!!!", __func__);
11851 return -EAGAIN;
11852 }
Kiet Lam10841362013-11-01 11:36:50 +053011853 }
11854 }
11855 else
11856 {
11857 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011858 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +053011859 return -EINVAL;
11860 }
11861 }
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +053011862 status = hdd_init_ap_mode(pAdapter, false);
Jeff Johnson295189b2012-06-20 16:38:30 -070011863 if(status != VOS_STATUS_SUCCESS)
11864 {
11865 hddLog(VOS_TRACE_LEVEL_FATAL,
11866 "%s: Error initializing the ap mode", __func__);
11867 return -EINVAL;
11868 }
11869 hdd_set_conparam(1);
11870
Nirav Shah7e3c8132015-06-22 23:51:42 +053011871 status = hdd_sta_id_hash_attach(pAdapter);
11872 if (VOS_STATUS_SUCCESS != status)
11873 {
11874 hddLog(VOS_TRACE_LEVEL_ERROR,
11875 FL("Failed to initialize hash for AP"));
11876 return -EINVAL;
11877 }
11878
Jeff Johnson295189b2012-06-20 16:38:30 -070011879 /*interface type changed update in wiphy structure*/
11880 if(wdev)
11881 {
11882 wdev->iftype = type;
11883 pHddCtx->change_iface = type;
11884 }
11885 else
11886 {
11887 hddLog(VOS_TRACE_LEVEL_ERROR,
11888 "%s: ERROR !!!! Wireless dev is NULL", __func__);
11889 return -EINVAL;
11890 }
11891 goto done;
11892 }
11893
11894 default:
11895 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
11896 __func__);
11897 return -EOPNOTSUPP;
11898 }
11899 }
11900 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011901 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011902 )
11903 {
11904 switch(type)
11905 {
11906 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070011907 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070011908 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +053011909
11910 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011911#ifdef FEATURE_WLAN_TDLS
11912
11913 /* A Mutex Lock is introduced while changing the mode to
11914 * protect the concurrent access for the Adapters by TDLS
11915 * module.
11916 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011917 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011918#endif
c_hpothu002231a2015-02-05 14:58:51 +053011919 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011920 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080011921 //Check for sub-string p2p to confirm its a p2p interface
11922 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -080011923 {
11924 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
11925 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
11926 }
11927 else
11928 {
11929 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070011930 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080011931 }
Agrawal Ashishcfe83282016-09-29 13:03:45 +053011932
11933 /* set con_mode to STA only when no SAP concurrency mode */
11934 if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO)))
11935 hdd_set_conparam(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070011936 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070011937 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
11938 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011939#ifdef FEATURE_WLAN_TDLS
11940 mutex_unlock(&pHddCtx->tdls_lock);
11941#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +053011942 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -070011943 if( VOS_STATUS_SUCCESS != status )
11944 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -070011945 /* In case of JB, for P2P-GO, only change interface will be called,
11946 * This is the right place to enable back bmps_imps()
11947 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053011948 if (pHddCtx->hdd_wlan_suspended)
11949 {
11950 hdd_set_pwrparams(pHddCtx);
11951 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011952 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070011953 goto done;
11954 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070011955 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070011956 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070011957 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
11958 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -070011959 goto done;
11960 default:
11961 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
11962 __func__);
11963 return -EOPNOTSUPP;
11964
11965 }
11966
11967 }
11968 else
11969 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011970 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
11971 __func__, hdd_device_modetoString(pAdapter->device_mode),
11972 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011973 return -EOPNOTSUPP;
11974 }
11975
11976
11977 if(pRoamProfile)
11978 {
11979 if ( LastBSSType != pRoamProfile->BSSType )
11980 {
11981 /*interface type changed update in wiphy structure*/
11982 wdev->iftype = type;
11983
11984 /*the BSS mode changed, We need to issue disconnect
11985 if connected or in IBSS disconnect state*/
11986 if ( hdd_connGetConnectedBssType(
11987 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
11988 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
11989 {
11990 /*need to issue a disconnect to CSR.*/
11991 INIT_COMPLETION(pAdapter->disconnect_comp_var);
11992 if( eHAL_STATUS_SUCCESS ==
11993 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
11994 pAdapter->sessionId,
11995 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
11996 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011997 ret = wait_for_completion_interruptible_timeout(
11998 &pAdapter->disconnect_comp_var,
11999 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12000 if (ret <= 0)
12001 {
12002 hddLog(VOS_TRACE_LEVEL_ERROR,
12003 FL("wait on disconnect_comp_var failed %ld"), ret);
12004 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012005 }
12006 }
12007 }
12008 }
12009
12010done:
12011 /*set bitmask based on updated value*/
12012 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -070012013
12014 /* Only STA mode support TM now
12015 * all other mode, TM feature should be disabled */
12016 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
12017 (~VOS_STA & pHddCtx->concurrency_mode) )
12018 {
12019 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
12020 }
12021
Jeff Johnson295189b2012-06-20 16:38:30 -070012022#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012023 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053012024 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -070012025 {
12026 //we are ok to do AMP
12027 pHddCtx->isAmpAllowed = VOS_TRUE;
12028 }
12029#endif //WLAN_BTAMP_FEATURE
12030 EXIT();
12031 return 0;
12032}
12033
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012034/*
12035 * FUNCTION: wlan_hdd_cfg80211_change_iface
12036 * wrapper function to protect the actual implementation from SSR.
12037 */
12038int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
12039 struct net_device *ndev,
12040 enum nl80211_iftype type,
12041 u32 *flags,
12042 struct vif_params *params
12043 )
12044{
12045 int ret;
12046
12047 vos_ssr_protect(__func__);
12048 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
12049 vos_ssr_unprotect(__func__);
12050
12051 return ret;
12052}
12053
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012054#ifdef FEATURE_WLAN_TDLS
12055static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012056 struct net_device *dev,
12057#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12058 const u8 *mac,
12059#else
12060 u8 *mac,
12061#endif
12062 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012063{
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012064 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012065 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012066 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012067 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012068 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012069 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012070
12071 ENTER();
12072
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012073 if (!dev) {
12074 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
12075 return -EINVAL;
12076 }
12077
12078 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12079 if (!pAdapter) {
12080 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
12081 return -EINVAL;
12082 }
12083
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012084 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012085 {
12086 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12087 "Invalid arguments");
12088 return -EINVAL;
12089 }
Hoonki Lee27511902013-03-14 18:19:06 -070012090
12091 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
12092 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
12093 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012094 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070012095 "%s: TDLS mode is disabled OR not enabled in FW."
12096 MAC_ADDRESS_STR " Request declined.",
12097 __func__, MAC_ADDR_ARRAY(mac));
12098 return -ENOTSUPP;
12099 }
12100
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012101 if (pHddCtx->isLogpInProgress)
12102 {
12103 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12104 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053012105 wlan_hdd_tdls_set_link_status(pAdapter,
12106 mac,
12107 eTDLS_LINK_IDLE,
12108 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012109 return -EBUSY;
12110 }
12111
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053012112 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +053012113 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012114
12115 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012116 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012117 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
12118 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053012119 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012120 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012121 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012122
12123 /* in add station, we accept existing valid staId if there is */
12124 if ((0 == update) &&
12125 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
12126 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012127 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012128 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012129 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012130 " link_status %d. staId %d. add station ignored.",
12131 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012132 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012133 return 0;
12134 }
12135 /* in change station, we accept only when staId is valid */
12136 if ((1 == update) &&
12137 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
12138 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
12139 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012140 tANI_U16 staId = pTdlsPeer->staId;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012141 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012142 "%s: " MAC_ADDRESS_STR
12143 " link status %d. staId %d. change station %s.",
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012144 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, staId,
12145 (TDLS_STA_INDEX_VALID(staId)) ? "ignored" : "declined");
12146 mutex_unlock(&pHddCtx->tdls_lock);
12147 return (TDLS_STA_INDEX_VALID(staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012148 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012149 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012150
12151 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053012152 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012153 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012154 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12155 "%s: " MAC_ADDRESS_STR
12156 " TDLS setup is ongoing. Request declined.",
12157 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -070012158 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012159 }
12160
12161 /* first to check if we reached to maximum supported TDLS peer.
12162 TODO: for now, return -EPERM looks working fine,
12163 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012164 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
12165 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012166 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012167 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12168 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012169 " TDLS Max peer already connected. Request declined."
12170 " Num of peers (%d), Max allowed (%d).",
12171 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
12172 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012173 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012174 }
12175 else
12176 {
12177 hddTdlsPeer_t *pTdlsPeer;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012178 mutex_lock(&pHddCtx->tdls_lock);
12179 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012180 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012181 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012182 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012183 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12184 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
12185 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012186 return -EPERM;
12187 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012188 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012189 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012190 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +053012191 wlan_hdd_tdls_set_link_status(pAdapter,
12192 mac,
12193 eTDLS_LINK_CONNECTING,
12194 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012195
Jeff Johnsond75fe012013-04-06 10:53:06 -070012196 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012197 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012198 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012199 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012200 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -070012201 if(StaParams->htcap_present)
12202 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012203 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012204 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012205 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012206 "ht_capa->extended_capabilities: %0x",
12207 StaParams->HTCap.extendedHtCapInfo);
12208 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012209 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012210 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012211 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012212 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -070012213 if(StaParams->vhtcap_present)
12214 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012215 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012216 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
12217 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
12218 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
12219 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012220 {
12221 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012222 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012223 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012224 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012225 "[%d]: %x ", i, StaParams->supported_rates[i]);
12226 }
Jeff Johnsond75fe012013-04-06 10:53:06 -070012227 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012228 else if ((1 == update) && (NULL == StaParams))
12229 {
12230 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12231 "%s : update is true, but staParams is NULL. Error!", __func__);
12232 return -EPERM;
12233 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012234
12235 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
12236
12237 if (!update)
12238 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012239 /*Before adding sta make sure that device exited from BMPS*/
12240 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
12241 {
12242 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12243 "%s: Adding tdls peer sta. Disable BMPS", __func__);
12244 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
12245 if (status != VOS_STATUS_SUCCESS) {
12246 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
12247 }
12248 }
12249
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012250 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012251 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012252 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012253 hddLog(VOS_TRACE_LEVEL_ERROR,
12254 FL("Failed to add TDLS peer STA. Enable Bmps"));
12255 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012256 return -EPERM;
12257 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012258 }
12259 else
12260 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012261 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012262 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012263 if (ret != eHAL_STATUS_SUCCESS) {
12264 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
12265 return -EPERM;
12266 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012267 }
12268
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012269 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012270 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
12271
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053012272 mutex_lock(&pHddCtx->tdls_lock);
12273 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
12274
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012275 if ((pTdlsPeer != NULL) &&
12276 (pTdlsPeer->link_status == eTDLS_LINK_TEARING))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012277 {
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012278 hddLog(VOS_TRACE_LEVEL_ERROR,
12279 FL("peer link status %u"), pTdlsPeer->link_status);
12280 mutex_unlock(&pHddCtx->tdls_lock);
12281 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012282 }
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053012283 mutex_unlock(&pHddCtx->tdls_lock);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012284
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012285 if (ret <= 0)
12286 {
12287 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12288 "%s: timeout waiting for tdls add station indication %ld",
12289 __func__, ret);
12290 goto error;
12291 }
12292
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012293 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
12294 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012295 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012296 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012297 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012298 }
12299
12300 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -070012301
12302error:
Atul Mittal115287b2014-07-08 13:26:33 +053012303 wlan_hdd_tdls_set_link_status(pAdapter,
12304 mac,
12305 eTDLS_LINK_IDLE,
12306 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012307 return -EPERM;
12308
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012309}
12310#endif
12311
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012312static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012313 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012314#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12315 const u8 *mac,
12316#else
Jeff Johnson295189b2012-06-20 16:38:30 -070012317 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012318#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012319 struct station_parameters *params)
12320{
12321 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053012322 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +053012323 hdd_context_t *pHddCtx;
12324 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012325 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012326 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070012327#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012328 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012329 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012330 tANI_U8 isOffChannelSupported = 0;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053012331 tANI_U8 isQosWmmSta = FALSE;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070012332#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070012333
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053012334 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012335
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053012336 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +053012337 if ((NULL == pAdapter))
12338 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012339 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053012340 "invalid adapter ");
12341 return -EINVAL;
12342 }
12343
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012344 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12345 TRACE_CODE_HDD_CHANGE_STATION,
12346 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +053012347 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +053012348
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012349 ret = wlan_hdd_validate_context(pHddCtx);
12350 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +053012351 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012352 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +053012353 }
12354
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012355 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12356
12357 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012358 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012359 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12360 "invalid HDD station context");
12361 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012362 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012363 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
12364
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012365 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
12366 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -070012367 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012368 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -070012369 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012370 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -070012371 WLANTL_STA_AUTHENTICATED);
12372
Gopichand Nakkala29149562013-05-10 21:43:41 +053012373 if (status != VOS_STATUS_SUCCESS)
12374 {
12375 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12376 "%s: Not able to change TL state to AUTHENTICATED", __func__);
12377 return -EINVAL;
12378 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012379 }
12380 }
Hoonki Leea6d49be2013-04-05 09:43:25 -070012381 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
12382 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +053012383#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012384 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
12385 StaParams.capability = params->capability;
12386 StaParams.uapsd_queues = params->uapsd_queues;
12387 StaParams.max_sp = params->max_sp;
12388
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012389 /* Convert (first channel , number of channels) tuple to
12390 * the total list of channels. This goes with the assumption
12391 * that if the first channel is < 14, then the next channels
12392 * are an incremental of 1 else an incremental of 4 till the number
12393 * of channels.
12394 */
12395 if (0 != params->supported_channels_len) {
12396 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
12397 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
12398 {
12399 int wifi_chan_index;
12400 StaParams.supported_channels[j] = params->supported_channels[i];
12401 wifi_chan_index =
12402 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
12403 no_of_channels = params->supported_channels[i+1];
12404 for(k=1; k <= no_of_channels; k++)
12405 {
12406 StaParams.supported_channels[j+1] =
12407 StaParams.supported_channels[j] + wifi_chan_index;
12408 j+=1;
12409 }
12410 }
12411 StaParams.supported_channels_len = j;
12412 }
SaidiReddy Yenuga0f1a1592017-04-05 13:18:26 +053012413 if (params->supported_oper_classes_len >
12414 SIR_MAC_MAX_SUPP_OPER_CLASSES) {
12415 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12416 "received oper classes:%d, resetting it to max supported %d",
12417 params->supported_oper_classes_len,
12418 SIR_MAC_MAX_SUPP_OPER_CLASSES);
12419 params->supported_oper_classes_len =
12420 SIR_MAC_MAX_SUPP_OPER_CLASSES;
12421 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012422 vos_mem_copy(StaParams.supported_oper_classes,
12423 params->supported_oper_classes,
12424 params->supported_oper_classes_len);
12425 StaParams.supported_oper_classes_len =
12426 params->supported_oper_classes_len;
12427
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053012428 if (params->ext_capab_len > sizeof(StaParams.extn_capability)) {
12429 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12430 "received extn capabilities:%d, resetting it to max supported",
12431 params->ext_capab_len);
12432 params->ext_capab_len = sizeof(StaParams.extn_capability);
12433 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012434 if (0 != params->ext_capab_len)
12435 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053012436 params->ext_capab_len);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012437
12438 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070012439 {
12440 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012441 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070012442 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012443
12444 StaParams.supported_rates_len = params->supported_rates_len;
12445
12446 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
12447 * The supported_rates array , for all the structures propogating till Add Sta
12448 * to the firmware has to be modified , if the supplicant (ieee80211) is
12449 * modified to send more rates.
12450 */
12451
12452 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
12453 */
12454 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
12455 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
12456
12457 if (0 != StaParams.supported_rates_len) {
12458 int i = 0;
12459 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
12460 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012461 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012462 "Supported Rates with Length %d", StaParams.supported_rates_len);
12463 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012464 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012465 "[%d]: %0x", i, StaParams.supported_rates[i]);
12466 }
12467
12468 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070012469 {
12470 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012471 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070012472 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012473
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012474 if (0 != params->ext_capab_len ) {
12475 /*Define A Macro : TODO Sunil*/
12476 if ((1<<4) & StaParams.extn_capability[3]) {
12477 isBufSta = 1;
12478 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012479 /* TDLS Channel Switching Support */
12480 if ((1<<6) & StaParams.extn_capability[3]) {
12481 isOffChannelSupported = 1;
12482 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012483 }
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053012484
12485 if (pHddCtx->cfg_ini->fEnableTDLSWmmMode &&
Nitesh Shah48df4c02016-08-12 16:27:33 +053012486 (params->ht_capa || params->vht_capa ||
12487 (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME))))
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053012488 /* TDLS Peer is WME/QoS capable */
12489 isQosWmmSta = TRUE;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053012490
12491 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12492 "%s: TDLS Peer is QOS capable isQosWmmSta= %d HTcapPresent= %d",
12493 __func__, isQosWmmSta, StaParams.htcap_present);
12494
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012495 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
12496 &StaParams, isBufSta,
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053012497 isOffChannelSupported,
12498 isQosWmmSta);
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012499
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053012500 if (VOS_STATUS_SUCCESS != status) {
12501 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12502 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
12503 return -EINVAL;
12504 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012505 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
12506
12507 if (VOS_STATUS_SUCCESS != status) {
12508 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12509 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
12510 return -EINVAL;
12511 }
12512 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -070012513#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +053012514 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012515 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012516 return status;
12517}
12518
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012519#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
12520static int wlan_hdd_change_station(struct wiphy *wiphy,
12521 struct net_device *dev,
12522 const u8 *mac,
12523 struct station_parameters *params)
12524#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012525static int wlan_hdd_change_station(struct wiphy *wiphy,
12526 struct net_device *dev,
12527 u8 *mac,
12528 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012529#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012530{
12531 int ret;
12532
12533 vos_ssr_protect(__func__);
12534 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
12535 vos_ssr_unprotect(__func__);
12536
12537 return ret;
12538}
12539
Jeff Johnson295189b2012-06-20 16:38:30 -070012540/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012541 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -070012542 * This function is used to initialize the key information
12543 */
12544#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012545static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012546 struct net_device *ndev,
12547 u8 key_index, bool pairwise,
12548 const u8 *mac_addr,
12549 struct key_params *params
12550 )
12551#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012552static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012553 struct net_device *ndev,
12554 u8 key_index, const u8 *mac_addr,
12555 struct key_params *params
12556 )
12557#endif
12558{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012559 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070012560 tCsrRoamSetKey setKey;
12561 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012562 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012563 v_U32_t roamId= 0xFF;
12564 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070012565 hdd_hostapd_state_t *pHostapdState;
12566 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012567 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012568 hdd_context_t *pHddCtx;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053012569 uint8_t i;
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053012570 v_MACADDR_t *peerMacAddr;
12571 u64 rsc_counter = 0;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053012572 uint8_t staid = HDD_MAX_STA_COUNT;
12573 bool pairwise_set_key = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070012574
12575 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012576
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012577 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12578 TRACE_CODE_HDD_CFG80211_ADD_KEY,
12579 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012580 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12581 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012582 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012583 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012584 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012585 }
12586
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012587 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12588 __func__, hdd_device_modetoString(pAdapter->device_mode),
12589 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012590
12591 if (CSR_MAX_NUM_KEY <= key_index)
12592 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012593 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012594 key_index);
12595
12596 return -EINVAL;
12597 }
12598
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012599 if (CSR_MAX_KEY_LEN < params->key_len)
12600 {
12601 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
12602 params->key_len);
12603
12604 return -EINVAL;
12605 }
12606
Jingxiang Gec438aea2017-10-26 16:44:00 +080012607 if (CSR_MAX_RSC_LEN < params->seq_len)
12608 {
12609 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Invalid seq length %d", __func__,
12610 params->seq_len);
Ashish Kumar Dhanotiya9783b182017-12-08 14:50:46 +053012611
12612 return -EINVAL;
Jingxiang Gec438aea2017-10-26 16:44:00 +080012613 }
12614
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012615 hddLog(VOS_TRACE_LEVEL_INFO,
Jingxiang Gec438aea2017-10-26 16:44:00 +080012616 "%s: called with key index = %d & key length %d & seq length %d",
12617 __func__, key_index, params->key_len, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070012618
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053012619 peerMacAddr = (v_MACADDR_t *)mac_addr;
12620
Jeff Johnson295189b2012-06-20 16:38:30 -070012621 /*extract key idx, key len and key*/
12622 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
12623 setKey.keyId = key_index;
12624 setKey.keyLength = params->key_len;
12625 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
Jingxiang Gec438aea2017-10-26 16:44:00 +080012626 vos_mem_copy(&setKey.keyRsc[0], params->seq, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070012627
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012628 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070012629 {
12630 case WLAN_CIPHER_SUITE_WEP40:
12631 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
12632 break;
12633
12634 case WLAN_CIPHER_SUITE_WEP104:
12635 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
12636 break;
12637
12638 case WLAN_CIPHER_SUITE_TKIP:
12639 {
12640 u8 *pKey = &setKey.Key[0];
12641 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
12642
12643 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
12644
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012645 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -070012646
12647 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012648 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070012649 |--------------|----------|----------|
12650 <---16bytes---><--8bytes--><--8bytes-->
12651
12652 */
12653 /*Sme expects the 32 bytes key to be in the below order
12654
12655 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012656 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070012657 |--------------|----------|----------|
12658 <---16bytes---><--8bytes--><--8bytes-->
12659 */
12660 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012661 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -070012662
12663 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012664 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070012665
12666 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012667 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070012668
12669
12670 break;
12671 }
12672
12673 case WLAN_CIPHER_SUITE_CCMP:
12674 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
12675 break;
12676
12677#ifdef FEATURE_WLAN_WAPI
12678 case WLAN_CIPHER_SUITE_SMS4:
12679 {
12680 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
12681 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
12682 params->key, params->key_len);
12683 return 0;
12684 }
12685#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070012686
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080012687#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070012688 case WLAN_CIPHER_SUITE_KRK:
12689 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
12690 break;
12691#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070012692
12693#ifdef WLAN_FEATURE_11W
12694 case WLAN_CIPHER_SUITE_AES_CMAC:
12695 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -070012696 break;
Chet Lanctot186b5732013-03-18 10:26:30 -070012697#endif
12698
Jeff Johnson295189b2012-06-20 16:38:30 -070012699 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012700 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070012701 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012702 status = -EOPNOTSUPP;
12703 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012704 }
12705
12706 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
12707 __func__, setKey.encType);
12708
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012709 if (
Jeff Johnson295189b2012-06-20 16:38:30 -070012710#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12711 (!pairwise)
12712#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012713 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -070012714#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012715 )
12716 {
12717 /* set group key*/
12718 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12719 "%s- %d: setting Broadcast key",
12720 __func__, __LINE__);
12721 setKey.keyDirection = eSIR_RX_ONLY;
12722 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
12723 }
12724 else
12725 {
12726 /* set pairwise key*/
12727 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12728 "%s- %d: setting pairwise key",
12729 __func__, __LINE__);
12730 setKey.keyDirection = eSIR_TX_RX;
12731 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053012732 pairwise_set_key = true;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012733 }
12734 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
12735 {
12736 setKey.keyDirection = eSIR_TX_RX;
12737 /*Set the group key*/
12738 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
12739 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -070012740
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012741 if ( 0 != status )
12742 {
12743 hddLog(VOS_TRACE_LEVEL_ERROR,
12744 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012745 status = -EINVAL;
12746 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012747 }
12748 /*Save the keys here and call sme_RoamSetKey for setting
12749 the PTK after peer joins the IBSS network*/
12750 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
12751 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012752 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012753 }
Gopichand Nakkala29149562013-05-10 21:43:41 +053012754 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
12755 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
12756 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012757 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012758 if( pHostapdState->bssState == BSS_START )
12759 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012760 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12761 vos_status = wlan_hdd_check_ula_done(pAdapter);
12762
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053012763 if (peerMacAddr && (pairwise_set_key == true))
12764 staid = hdd_sta_id_find_from_mac_addr(pAdapter, peerMacAddr);
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053012765
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012766 if ( vos_status != VOS_STATUS_SUCCESS )
12767 {
12768 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12769 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
12770 __LINE__, vos_status );
12771
12772 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
12773
12774 status = -EINVAL;
12775 goto end;
12776 }
12777
Jeff Johnson295189b2012-06-20 16:38:30 -070012778 status = WLANSAP_SetKeySta( pVosContext, &setKey);
12779
12780 if ( status != eHAL_STATUS_SUCCESS )
12781 {
12782 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12783 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
12784 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012785 status = -EINVAL;
12786 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012787 }
12788 }
12789
12790 /* Saving WEP keys */
12791 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
12792 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
12793 {
12794 //Save the wep key in ap context. Issue setkey after the BSS is started.
12795 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
12796 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
12797 }
12798 else
12799 {
12800 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012801 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012802 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
12803 }
12804 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012805 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
12806 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012807 {
12808 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12809 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12810
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012811#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12812 if (!pairwise)
12813#else
12814 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
12815#endif
12816 {
12817 /* set group key*/
12818 if (pHddStaCtx->roam_info.deferKeyComplete)
12819 {
12820 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12821 "%s- %d: Perform Set key Complete",
12822 __func__, __LINE__);
12823 hdd_PerformRoamSetKeyComplete(pAdapter);
12824 }
12825 }
12826
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053012827 if (pairwise_set_key == true)
12828 staid = pHddStaCtx->conn_info.staId[0];
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053012829
Jeff Johnson295189b2012-06-20 16:38:30 -070012830 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
12831
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -080012832 pWextState->roamProfile.Keys.defaultIndex = key_index;
12833
12834
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012835 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070012836 params->key, params->key_len);
12837
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012838
Jeff Johnson295189b2012-06-20 16:38:30 -070012839 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
12840
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012841 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070012842 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012843 __func__, setKey.peerMac[0], setKey.peerMac[1],
12844 setKey.peerMac[2], setKey.peerMac[3],
12845 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070012846 setKey.keyDirection);
12847
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012848 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +053012849
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012850 if ( vos_status != VOS_STATUS_SUCCESS )
12851 {
12852 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012853 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
12854 __LINE__, vos_status );
12855
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012856 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012857
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012858 status = -EINVAL;
12859 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012860
12861 }
12862
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012863#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012864 /* The supplicant may attempt to set the PTK once pre-authentication
12865 is done. Save the key in the UMAC and include it in the ADD BSS
12866 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012867 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012868 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012869 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012870 hddLog(VOS_TRACE_LEVEL_INFO_MED,
12871 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012872 status = 0;
12873 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012874 }
12875 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
12876 {
12877 hddLog(VOS_TRACE_LEVEL_ERROR,
12878 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012879 status = -EINVAL;
12880 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012881 }
12882#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070012883
12884 /* issue set key request to SME*/
12885 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
12886 pAdapter->sessionId, &setKey, &roamId );
12887
12888 if ( 0 != status )
12889 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012890 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012891 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
12892 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012893 status = -EINVAL;
12894 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012895 }
12896
12897
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012898 /* in case of IBSS as there was no information available about WEP keys during
12899 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070012900 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012901 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
12902 !( ( IW_AUTH_KEY_MGMT_802_1X
12903 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070012904 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
12905 )
12906 &&
12907 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
12908 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
12909 )
12910 )
12911 {
12912 setKey.keyDirection = eSIR_RX_ONLY;
12913 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
12914
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012915 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070012916 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012917 __func__, setKey.peerMac[0], setKey.peerMac[1],
12918 setKey.peerMac[2], setKey.peerMac[3],
12919 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070012920 setKey.keyDirection);
12921
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012922 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070012923 pAdapter->sessionId, &setKey, &roamId );
12924
12925 if ( 0 != status )
12926 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012927 hddLog(VOS_TRACE_LEVEL_ERROR,
12928 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012929 __func__, status);
12930 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012931 status = -EINVAL;
12932 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012933 }
12934 }
12935 }
12936
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053012937 if (pairwise_set_key == true) {
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053012938 for (i = 0; i < params->seq_len; i++) {
12939 rsc_counter |= (params->seq[i] << i*8);
12940 }
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053012941 WLANTL_SetKeySeqCounter(pVosContext, rsc_counter, staid);
12942 }
12943
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012944end:
12945 /* Need to clear any trace of key value in the memory.
12946 * Thus zero out the memory even though it is local
12947 * variable.
12948 */
12949 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012950 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012951 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012952}
12953
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012954#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12955static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
12956 struct net_device *ndev,
12957 u8 key_index, bool pairwise,
12958 const u8 *mac_addr,
12959 struct key_params *params
12960 )
12961#else
12962static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
12963 struct net_device *ndev,
12964 u8 key_index, const u8 *mac_addr,
12965 struct key_params *params
12966 )
12967#endif
12968{
12969 int ret;
12970 vos_ssr_protect(__func__);
12971#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12972 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
12973 mac_addr, params);
12974#else
12975 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
12976 params);
12977#endif
12978 vos_ssr_unprotect(__func__);
12979
12980 return ret;
12981}
12982
Jeff Johnson295189b2012-06-20 16:38:30 -070012983/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012984 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070012985 * This function is used to get the key information
12986 */
12987#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012988static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012989 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012990 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012991 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070012992 const u8 *mac_addr, void *cookie,
12993 void (*callback)(void *cookie, struct key_params*)
12994 )
12995#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012996static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012997 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012998 struct net_device *ndev,
12999 u8 key_index, const u8 *mac_addr, void *cookie,
13000 void (*callback)(void *cookie, struct key_params*)
13001 )
13002#endif
13003{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013004 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013005 hdd_wext_state_t *pWextState = NULL;
13006 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013007 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013008 hdd_context_t *pHddCtx;
13009 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013010
13011 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013012
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013013 if (NULL == pAdapter)
13014 {
13015 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13016 "%s: HDD adapter is Null", __func__);
13017 return -ENODEV;
13018 }
13019
13020 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13021 ret = wlan_hdd_validate_context(pHddCtx);
13022 if (0 != ret)
13023 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013024 return ret;
13025 }
13026
13027 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13028 pRoamProfile = &(pWextState->roamProfile);
13029
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013030 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13031 __func__, hdd_device_modetoString(pAdapter->device_mode),
13032 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013033
Jeff Johnson295189b2012-06-20 16:38:30 -070013034 memset(&params, 0, sizeof(params));
13035
13036 if (CSR_MAX_NUM_KEY <= key_index)
13037 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013038 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070013039 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013040 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013041
13042 switch(pRoamProfile->EncryptionType.encryptionType[0])
13043 {
13044 case eCSR_ENCRYPT_TYPE_NONE:
13045 params.cipher = IW_AUTH_CIPHER_NONE;
13046 break;
13047
13048 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
13049 case eCSR_ENCRYPT_TYPE_WEP40:
13050 params.cipher = WLAN_CIPHER_SUITE_WEP40;
13051 break;
13052
13053 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
13054 case eCSR_ENCRYPT_TYPE_WEP104:
13055 params.cipher = WLAN_CIPHER_SUITE_WEP104;
13056 break;
13057
13058 case eCSR_ENCRYPT_TYPE_TKIP:
13059 params.cipher = WLAN_CIPHER_SUITE_TKIP;
13060 break;
13061
13062 case eCSR_ENCRYPT_TYPE_AES:
13063 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
13064 break;
13065
13066 default:
13067 params.cipher = IW_AUTH_CIPHER_NONE;
13068 break;
13069 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013070
c_hpothuaaf19692014-05-17 17:01:48 +053013071 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13072 TRACE_CODE_HDD_CFG80211_GET_KEY,
13073 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013074
Jeff Johnson295189b2012-06-20 16:38:30 -070013075 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
13076 params.seq_len = 0;
13077 params.seq = NULL;
13078 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
13079 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013080 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013081 return 0;
13082}
13083
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013084#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13085static int wlan_hdd_cfg80211_get_key(
13086 struct wiphy *wiphy,
13087 struct net_device *ndev,
13088 u8 key_index, bool pairwise,
13089 const u8 *mac_addr, void *cookie,
13090 void (*callback)(void *cookie, struct key_params*)
13091 )
13092#else
13093static int wlan_hdd_cfg80211_get_key(
13094 struct wiphy *wiphy,
13095 struct net_device *ndev,
13096 u8 key_index, const u8 *mac_addr, void *cookie,
13097 void (*callback)(void *cookie, struct key_params*)
13098 )
13099#endif
13100{
13101 int ret;
13102
13103 vos_ssr_protect(__func__);
13104#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13105 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
13106 mac_addr, cookie, callback);
13107#else
13108 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
13109 callback);
13110#endif
13111 vos_ssr_unprotect(__func__);
13112
13113 return ret;
13114}
13115
Jeff Johnson295189b2012-06-20 16:38:30 -070013116/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013117 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013118 * This function is used to delete the key information
13119 */
13120#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013121static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013122 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013123 u8 key_index,
13124 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070013125 const u8 *mac_addr
13126 )
13127#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013128static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013129 struct net_device *ndev,
13130 u8 key_index,
13131 const u8 *mac_addr
13132 )
13133#endif
13134{
13135 int status = 0;
13136
13137 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013138 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070013139 //it is observed that this is invalidating peer
13140 //key index whenever re-key is done. This is affecting data link.
13141 //It should be ok to ignore del_key.
13142#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013143 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
13144 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070013145 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
13146 tCsrRoamSetKey setKey;
13147 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013148
Jeff Johnson295189b2012-06-20 16:38:30 -070013149 ENTER();
13150
13151 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
13152 __func__,pAdapter->device_mode);
13153
13154 if (CSR_MAX_NUM_KEY <= key_index)
13155 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013156 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013157 key_index);
13158
13159 return -EINVAL;
13160 }
13161
13162 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13163 setKey.keyId = key_index;
13164
13165 if (mac_addr)
13166 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
13167 else
13168 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
13169
13170 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
13171
13172 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070013173 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013174 )
13175 {
13176
13177 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070013178 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
13179 if( pHostapdState->bssState == BSS_START)
13180 {
13181 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013182
Jeff Johnson295189b2012-06-20 16:38:30 -070013183 if ( status != eHAL_STATUS_SUCCESS )
13184 {
13185 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13186 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
13187 __LINE__, status );
13188 }
13189 }
13190 }
13191 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013192 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070013193 )
13194 {
13195 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13196
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013197 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
13198
13199 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013200 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013201 __func__, setKey.peerMac[0], setKey.peerMac[1],
13202 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070013203 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013204 if(pAdapter->sessionCtx.station.conn_info.connState ==
13205 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070013206 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013207 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013208 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013209
Jeff Johnson295189b2012-06-20 16:38:30 -070013210 if ( 0 != status )
13211 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013212 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013213 "%s: sme_RoamSetKey failure, returned %d",
13214 __func__, status);
13215 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
13216 return -EINVAL;
13217 }
13218 }
13219 }
13220#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070013221 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013222 return status;
13223}
13224
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013225#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13226static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
13227 struct net_device *ndev,
13228 u8 key_index,
13229 bool pairwise,
13230 const u8 *mac_addr
13231 )
13232#else
13233static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
13234 struct net_device *ndev,
13235 u8 key_index,
13236 const u8 *mac_addr
13237 )
13238#endif
13239{
13240 int ret;
13241
13242 vos_ssr_protect(__func__);
13243#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13244 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
13245 mac_addr);
13246#else
13247 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
13248#endif
13249 vos_ssr_unprotect(__func__);
13250
13251 return ret;
13252}
13253
Jeff Johnson295189b2012-06-20 16:38:30 -070013254/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013255 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013256 * This function is used to set the default tx key index
13257 */
13258#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013259static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013260 struct net_device *ndev,
13261 u8 key_index,
13262 bool unicast, bool multicast)
13263#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013264static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013265 struct net_device *ndev,
13266 u8 key_index)
13267#endif
13268{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013269 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013270 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053013271 hdd_wext_state_t *pWextState;
13272 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013273 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013274
13275 ENTER();
13276
Gopichand Nakkala29149562013-05-10 21:43:41 +053013277 if ((NULL == pAdapter))
13278 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013279 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053013280 "invalid adapter");
13281 return -EINVAL;
13282 }
13283
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013284 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13285 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
13286 pAdapter->sessionId, key_index));
13287
Gopichand Nakkala29149562013-05-10 21:43:41 +053013288 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13289 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13290
13291 if ((NULL == pWextState) || (NULL == pHddStaCtx))
13292 {
13293 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13294 "invalid Wext state or HDD context");
13295 return -EINVAL;
13296 }
13297
Arif Hussain6d2a3322013-11-17 19:50:10 -080013298 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013299 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013300
Jeff Johnson295189b2012-06-20 16:38:30 -070013301 if (CSR_MAX_NUM_KEY <= key_index)
13302 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013303 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013304 key_index);
13305
13306 return -EINVAL;
13307 }
13308
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013309 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13310 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013311 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013312 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013313 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013314 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013315
Jeff Johnson295189b2012-06-20 16:38:30 -070013316 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070013317 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013318 )
Jeff Johnson295189b2012-06-20 16:38:30 -070013319 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053013320 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080013321 pHddStaCtx->conn_info.ucEncryptionType) &&
Hu Wangb1f68cb2017-08-23 20:01:49 +080013322#ifdef FEATURE_WLAN_WAPI
13323 (eCSR_ENCRYPT_TYPE_WPI !=
13324 pHddStaCtx->conn_info.ucEncryptionType) &&
13325#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013326 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080013327 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070013328 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013329 {
13330 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070013331 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013332
Jeff Johnson295189b2012-06-20 16:38:30 -070013333 tCsrRoamSetKey setKey;
13334 v_U32_t roamId= 0xFF;
13335 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013336
13337 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013338 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013339
Jeff Johnson295189b2012-06-20 16:38:30 -070013340 Keys->defaultIndex = (u8)key_index;
13341 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13342 setKey.keyId = key_index;
13343 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013344
13345 vos_mem_copy(&setKey.Key[0],
13346 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070013347 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013348
Gopichand Nakkala29149562013-05-10 21:43:41 +053013349 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013350
13351 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070013352 &pHddStaCtx->conn_info.bssId[0],
13353 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013354
Gopichand Nakkala29149562013-05-10 21:43:41 +053013355 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
13356 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
13357 eCSR_ENCRYPT_TYPE_WEP104)
13358 {
13359 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
13360 even though ap is configured for WEP-40 encryption. In this canse the key length
13361 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
13362 type(104) and switching encryption type to 40*/
13363 pWextState->roamProfile.EncryptionType.encryptionType[0] =
13364 eCSR_ENCRYPT_TYPE_WEP40;
13365 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
13366 eCSR_ENCRYPT_TYPE_WEP40;
13367 }
13368
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013369 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070013370 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013371
Jeff Johnson295189b2012-06-20 16:38:30 -070013372 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013373 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013374 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013375
Jeff Johnson295189b2012-06-20 16:38:30 -070013376 if ( 0 != status )
13377 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013378 hddLog(VOS_TRACE_LEVEL_ERROR,
13379 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013380 status);
13381 return -EINVAL;
13382 }
13383 }
13384 }
13385
13386 /* In SoftAp mode setting key direction for default mode */
13387 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
13388 {
13389 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
13390 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
13391 (eCSR_ENCRYPT_TYPE_AES !=
13392 pWextState->roamProfile.EncryptionType.encryptionType[0])
13393 )
13394 {
13395 /* Saving key direction for default key index to TX default */
13396 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
13397 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
13398 }
13399 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013400 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013401 return status;
13402}
13403
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013404#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13405static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
13406 struct net_device *ndev,
13407 u8 key_index,
13408 bool unicast, bool multicast)
13409#else
13410static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
13411 struct net_device *ndev,
13412 u8 key_index)
13413#endif
13414{
13415 int ret;
13416 vos_ssr_protect(__func__);
13417#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13418 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
13419 multicast);
13420#else
13421 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
13422#endif
13423 vos_ssr_unprotect(__func__);
13424
13425 return ret;
13426}
13427
Jeff Johnson295189b2012-06-20 16:38:30 -070013428/*
13429 * FUNCTION: wlan_hdd_cfg80211_inform_bss
13430 * This function is used to inform the BSS details to nl80211 interface.
13431 */
13432static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
13433 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
13434{
13435 struct net_device *dev = pAdapter->dev;
13436 struct wireless_dev *wdev = dev->ieee80211_ptr;
13437 struct wiphy *wiphy = wdev->wiphy;
13438 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
13439 int chan_no;
13440 int ie_length;
13441 const char *ie;
13442 unsigned int freq;
13443 struct ieee80211_channel *chan;
13444 int rssi = 0;
13445 struct cfg80211_bss *bss = NULL;
13446
Jeff Johnson295189b2012-06-20 16:38:30 -070013447 if( NULL == pBssDesc )
13448 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013449 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013450 return bss;
13451 }
13452
13453 chan_no = pBssDesc->channelId;
13454 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
13455 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
13456
13457 if( NULL == ie )
13458 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013459 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013460 return bss;
13461 }
13462
13463#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
13464 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
13465 {
13466 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
13467 }
13468 else
13469 {
13470 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
13471 }
13472#else
13473 freq = ieee80211_channel_to_frequency(chan_no);
13474#endif
13475
13476 chan = __ieee80211_get_channel(wiphy, freq);
13477
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053013478 if (!chan) {
13479 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
13480 return NULL;
13481 }
13482
Abhishek Singhaee43942014-06-16 18:55:47 +053013483 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070013484
Anand N Sunkad9f80b742015-07-30 20:05:51 +053013485 return cfg80211_inform_bss(wiphy, chan,
13486#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13487 CFG80211_BSS_FTYPE_UNKNOWN,
13488#endif
13489 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013490 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070013491 pBssDesc->capabilityInfo,
13492 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053013493 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070013494}
13495
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053013496/*
13497 * wlan_hdd_cfg80211_update_bss_list :to inform nl80211
13498 * interface that BSS might have been lost.
13499 * @pAdapter: adaptor
13500 * @bssid: bssid which might have been lost
13501 *
13502 * Return: bss which is unlinked from kernel cache
13503 */
13504struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_list(
13505 hdd_adapter_t *pAdapter, tSirMacAddr bssid)
13506{
13507 struct net_device *dev = pAdapter->dev;
13508 struct wireless_dev *wdev = dev->ieee80211_ptr;
13509 struct wiphy *wiphy = wdev->wiphy;
13510 struct cfg80211_bss *bss = NULL;
13511
Abhishek Singh5a597e62016-12-05 15:16:30 +053013512 bss = hdd_get_bss_entry(wiphy,
13513 NULL, bssid,
13514 NULL, 0);
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053013515 if (bss == NULL) {
13516 hddLog(LOGE, FL("BSS not present"));
13517 } else {
13518 hddLog(LOG1, FL("cfg80211_unlink_bss called for BSSID "
13519 MAC_ADDRESS_STR), MAC_ADDR_ARRAY(bssid));
13520 cfg80211_unlink_bss(wiphy, bss);
13521 }
13522 return bss;
13523}
Jeff Johnson295189b2012-06-20 16:38:30 -070013524
13525
13526/*
13527 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
13528 * This function is used to inform the BSS details to nl80211 interface.
13529 */
13530struct cfg80211_bss*
13531wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
13532 tSirBssDescription *bss_desc
13533 )
13534{
13535 /*
13536 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
13537 already exists in bss data base of cfg80211 for that particular BSS ID.
13538 Using cfg80211_inform_bss_frame to update the bss entry instead of
13539 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
13540 now there is no possibility to get the mgmt(probe response) frame from PE,
13541 converting bss_desc to ieee80211_mgmt(probe response) and passing to
13542 cfg80211_inform_bss_frame.
13543 */
13544 struct net_device *dev = pAdapter->dev;
13545 struct wireless_dev *wdev = dev->ieee80211_ptr;
13546 struct wiphy *wiphy = wdev->wiphy;
13547 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080013548#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
13549 qcom_ie_age *qie_age = NULL;
13550 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
13551#else
Jeff Johnson295189b2012-06-20 16:38:30 -070013552 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080013553#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013554 const char *ie =
13555 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
13556 unsigned int freq;
13557 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053013558 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013559 struct cfg80211_bss *bss_status = NULL;
13560 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
13561 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070013562 hdd_context_t *pHddCtx;
13563 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070013564#ifdef WLAN_OPEN_SOURCE
13565 struct timespec ts;
13566#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013567
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013568
Wilson Yangf80a0542013-10-07 13:02:37 -070013569 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13570 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070013571 if (0 != status)
13572 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070013573 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070013574 }
13575
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053013576 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070013577 if (!mgmt)
13578 {
13579 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13580 "%s: memory allocation failed ", __func__);
13581 return NULL;
13582 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070013583
Jeff Johnson295189b2012-06-20 16:38:30 -070013584 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070013585
13586#ifdef WLAN_OPEN_SOURCE
13587 /* Android does not want the timestamp from the frame.
13588 Instead it wants a monotonic increasing value */
13589 get_monotonic_boottime(&ts);
13590 mgmt->u.probe_resp.timestamp =
13591 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
13592#else
13593 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070013594 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
13595 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070013596
13597#endif
13598
Jeff Johnson295189b2012-06-20 16:38:30 -070013599 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
13600 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080013601
13602#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
13603 /* GPS Requirement: need age ie per entry. Using vendor specific. */
13604 /* Assuming this is the last IE, copy at the end */
13605 ie_length -=sizeof(qcom_ie_age);
13606 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
13607 qie_age->element_id = QCOM_VENDOR_IE_ID;
13608 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
13609 qie_age->oui_1 = QCOM_OUI1;
13610 qie_age->oui_2 = QCOM_OUI2;
13611 qie_age->oui_3 = QCOM_OUI3;
13612 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
Selvaraj, Sridhar4b3a8362016-10-12 12:34:08 +053013613 /* Lowi expects the timestamp of bss in units of 1/10 ms. In driver all
13614 * bss related timestamp is in units of ms. Due to this when scan results
13615 * are sent to lowi the scan age is high.To address this, send age in units
13616 * of 1/10 ms.
13617 */
13618 qie_age->age = (vos_timer_get_system_time() -
13619 bss_desc->nReceivedTime)/10;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080013620#endif
13621
Jeff Johnson295189b2012-06-20 16:38:30 -070013622 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053013623 if (bss_desc->fProbeRsp)
13624 {
13625 mgmt->frame_control |=
13626 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
13627 }
13628 else
13629 {
13630 mgmt->frame_control |=
13631 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
13632 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013633
13634#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013635 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070013636 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
13637 {
13638 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
13639 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013640 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070013641 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
13642
13643 {
13644 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
13645 }
13646 else
13647 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013648 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
13649 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070013650 kfree(mgmt);
13651 return NULL;
13652 }
13653#else
13654 freq = ieee80211_channel_to_frequency(chan_no);
13655#endif
13656 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080013657 /*when the band is changed on the fly using the GUI, three things are done
13658 * 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)
13659 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
13660 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
13661 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
13662 * and discards the channels correponding to previous band and calls back with zero bss results.
13663 * 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
13664 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
13665 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
13666 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
13667 * So drop the bss and continue to next bss.
13668 */
13669 if(chan == NULL)
13670 {
Deepthi Gowri306657b2016-04-28 17:10:41 +053013671 hddLog(VOS_TRACE_LEVEL_ERROR,
13672 FL("chan pointer is NULL, chan_no: %d freq: %d"),
13673 chan_no, freq);
Chilam Ngc4244af2013-04-01 15:37:32 -070013674 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080013675 return NULL;
13676 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053013677 /*To keep the rssi icon of the connected AP in the scan window
13678 *and the rssi icon of the wireless networks in sync
13679 * */
13680 if (( eConnectionState_Associated ==
13681 pAdapter->sessionCtx.station.conn_info.connState ) &&
13682 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
13683 pAdapter->sessionCtx.station.conn_info.bssId,
13684 WNI_CFG_BSSID_LEN)) &&
13685 (pHddCtx->hdd_wlan_suspended == FALSE))
13686 {
13687 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
13688 rssi = (pAdapter->rssi * 100);
13689 }
13690 else
13691 {
13692 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
13693 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013694
Nirav Shah20ac06f2013-12-12 18:14:06 +053013695 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053013696 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
13697 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053013698
Jeff Johnson295189b2012-06-20 16:38:30 -070013699 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
13700 frame_len, rssi, GFP_KERNEL);
13701 kfree(mgmt);
13702 return bss_status;
13703}
13704
13705/*
13706 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
13707 * This function is used to update the BSS data base of CFG8011
13708 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013709struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070013710 tCsrRoamInfo *pRoamInfo
13711 )
13712{
13713 tCsrRoamConnectedProfile roamProfile;
13714 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13715 struct cfg80211_bss *bss = NULL;
13716
13717 ENTER();
13718
13719 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
13720 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
13721
13722 if (NULL != roamProfile.pBssDesc)
13723 {
Girish Gowlif4b68022014-08-28 23:18:57 +053013724 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
13725 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070013726
13727 if (NULL == bss)
13728 {
13729 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
13730 __func__);
13731 }
13732
13733 sme_RoamFreeConnectProfile(hHal, &roamProfile);
13734 }
13735 else
13736 {
13737 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
13738 __func__);
13739 }
13740 return bss;
13741}
13742
13743/*
13744 * FUNCTION: wlan_hdd_cfg80211_update_bss
13745 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013746static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
13747 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070013748 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013749{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013750 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013751 tCsrScanResultInfo *pScanResult;
13752 eHalStatus status = 0;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013753 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013754 tScanResultHandle pResult;
13755 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070013756 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013757 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070013758 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013759
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013760 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13761 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
13762 NO_SESSION, pAdapter->sessionId));
13763
Wilson Yangf80a0542013-10-07 13:02:37 -070013764 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013765 ret = wlan_hdd_validate_context(pHddCtx);
13766 if (0 != ret)
Jeff Johnson295189b2012-06-20 16:38:30 -070013767 {
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013768 return ret;
Wilson Yangf80a0542013-10-07 13:02:37 -070013769 }
13770
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013771 if (pAdapter->request != NULL)
13772 {
13773 if ((pAdapter->request->n_ssids == 1)
13774 && (pAdapter->request->ssids != NULL)
13775 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
13776 is_p2p_scan = true;
13777 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013778 /*
13779 * start getting scan results and populate cgf80211 BSS database
13780 */
13781 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
13782
13783 /* no scan results */
13784 if (NULL == pResult)
13785 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013786 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
13787 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053013788 wlan_hdd_get_frame_logs(pAdapter,
13789 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070013790 return status;
13791 }
13792
13793 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
13794
13795 while (pScanResult)
13796 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013797 /*
13798 * cfg80211_inform_bss() is not updating ie field of bss entry, if
13799 * entry already exists in bss data base of cfg80211 for that
13800 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
13801 * bss entry instead of cfg80211_inform_bss, But this call expects
13802 * mgmt packet as input. As of now there is no possibility to get
13803 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070013804 * ieee80211_mgmt(probe response) and passing to c
13805 * fg80211_inform_bss_frame.
13806 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013807 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
13808 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
13809 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013810 pScanResult = sme_ScanResultGetNext(hHal, pResult);
13811 continue; //Skip the non p2p bss entries
13812 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013813 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
13814 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013815
Jeff Johnson295189b2012-06-20 16:38:30 -070013816
13817 if (NULL == bss_status)
13818 {
13819 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013820 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013821 }
13822 else
13823 {
Yue Maf49ba872013-08-19 12:04:25 -070013824 cfg80211_put_bss(
13825#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
13826 wiphy,
13827#endif
13828 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070013829 }
13830
13831 pScanResult = sme_ScanResultGetNext(hHal, pResult);
13832 }
13833
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013834 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013835 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013836 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013837}
13838
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013839void
13840hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
13841{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013842 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080013843 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013844} /****** end hddPrintMacAddr() ******/
13845
13846void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070013847hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013848{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013849 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013850 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070013851 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
13852 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
13853 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013854} /****** end hddPrintPmkId() ******/
13855
13856//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
13857//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
13858
13859//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
13860//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
13861
13862#define dump_bssid(bssid) \
13863 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070013864 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
13865 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013866 }
13867
13868#define dump_pmkid(pMac, pmkid) \
13869 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070013870 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
13871 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013872 }
13873
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070013874#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013875/*
13876 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
13877 * This function is used to notify the supplicant of a new PMKSA candidate.
13878 */
13879int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013880 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013881 int index, bool preauth )
13882{
Jeff Johnsone7245742012-09-05 17:12:55 -070013883#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013884 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070013885 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013886
13887 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070013888 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013889
13890 if( NULL == pRoamInfo )
13891 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013892 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013893 return -EINVAL;
13894 }
13895
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070013896 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
13897 {
13898 dump_bssid(pRoamInfo->bssid);
13899 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013900 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070013901 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013902#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013903 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013904}
13905#endif //FEATURE_WLAN_LFR
13906
Yue Maef608272013-04-08 23:09:17 -070013907#ifdef FEATURE_WLAN_LFR_METRICS
13908/*
13909 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
13910 * 802.11r/LFR metrics reporting function to report preauth initiation
13911 *
13912 */
13913#define MAX_LFR_METRICS_EVENT_LENGTH 100
13914VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
13915 tCsrRoamInfo *pRoamInfo)
13916{
13917 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
13918 union iwreq_data wrqu;
13919
13920 ENTER();
13921
13922 if (NULL == pAdapter)
13923 {
13924 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
13925 return VOS_STATUS_E_FAILURE;
13926 }
13927
13928 /* create the event */
13929 memset(&wrqu, 0, sizeof(wrqu));
13930 memset(metrics_notification, 0, sizeof(metrics_notification));
13931
13932 wrqu.data.pointer = metrics_notification;
13933 wrqu.data.length = scnprintf(metrics_notification,
13934 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
13935 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
13936
13937 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
13938
13939 EXIT();
13940
13941 return VOS_STATUS_SUCCESS;
13942}
13943
13944/*
13945 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
13946 * 802.11r/LFR metrics reporting function to report preauth completion
13947 * or failure
13948 */
13949VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
13950 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
13951{
13952 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
13953 union iwreq_data wrqu;
13954
13955 ENTER();
13956
13957 if (NULL == pAdapter)
13958 {
13959 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
13960 return VOS_STATUS_E_FAILURE;
13961 }
13962
13963 /* create the event */
13964 memset(&wrqu, 0, sizeof(wrqu));
13965 memset(metrics_notification, 0, sizeof(metrics_notification));
13966
13967 scnprintf(metrics_notification, sizeof(metrics_notification),
13968 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
13969 MAC_ADDR_ARRAY(pRoamInfo->bssid));
13970
13971 if (1 == preauth_status)
13972 strncat(metrics_notification, " TRUE", 5);
13973 else
13974 strncat(metrics_notification, " FALSE", 6);
13975
13976 wrqu.data.pointer = metrics_notification;
13977 wrqu.data.length = strlen(metrics_notification);
13978
13979 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
13980
13981 EXIT();
13982
13983 return VOS_STATUS_SUCCESS;
13984}
13985
13986/*
13987 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
13988 * 802.11r/LFR metrics reporting function to report handover initiation
13989 *
13990 */
13991VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
13992 tCsrRoamInfo *pRoamInfo)
13993{
13994 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
13995 union iwreq_data wrqu;
13996
13997 ENTER();
13998
13999 if (NULL == pAdapter)
14000 {
14001 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14002 return VOS_STATUS_E_FAILURE;
14003 }
14004
14005 /* create the event */
14006 memset(&wrqu, 0, sizeof(wrqu));
14007 memset(metrics_notification, 0, sizeof(metrics_notification));
14008
14009 wrqu.data.pointer = metrics_notification;
14010 wrqu.data.length = scnprintf(metrics_notification,
14011 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
14012 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
14013
14014 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14015
14016 EXIT();
14017
14018 return VOS_STATUS_SUCCESS;
14019}
14020#endif
14021
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014022
14023/**
14024 * wlan_hdd_cfg80211_validate_scan_req - validate scan request
14025 * @scan_req: scan request to be checked
14026 *
14027 * Return: true or false
14028 */
14029#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
14030static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
14031 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014032 *scan_req, hdd_context_t
14033 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014034{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014035 if (!scan_req || !scan_req->wiphy ||
14036 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014037 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
14038 return false;
14039 }
14040 if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HDD, NULL)) {
14041 hddLog(VOS_TRACE_LEVEL_ERROR, "Load/Unload in progress");
14042 return false;
14043 }
14044 return true;
14045}
14046#else
14047static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
14048 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014049 *scan_req, hdd_context_t
14050 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014051{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014052 if (!scan_req || !scan_req->wiphy ||
14053 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014054 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
14055 return false;
14056 }
14057 return true;
14058}
14059#endif
14060
Mukul Sharmab392b642017-08-17 17:45:29 +053014061#define NET_DEV_IS_IFF_UP(pAdapter) (pAdapter->dev->flags & IFF_UP)
Jeff Johnson295189b2012-06-20 16:38:30 -070014062/*
14063 * FUNCTION: hdd_cfg80211_scan_done_callback
14064 * scanning callback function, called after finishing scan
14065 *
14066 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014067static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070014068 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
14069{
14070 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014071 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070014072 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014073 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070014074 struct cfg80211_scan_request *req = NULL;
14075 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014076 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014077 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014078 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014079 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014080
14081 ENTER();
14082
c_manjee1b4ab9a2016-10-26 11:36:55 +053014083 if (!pAdapter || pAdapter->magic != WLAN_HDD_ADAPTER_MAGIC ||
14084 !pAdapter->dev) {
14085 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Adapter is not valid"));
14086 return 0;
14087 }
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014088 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053014089 if (NULL == pHddCtx) {
14090 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014091 return 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014092 }
14093
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014094#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014095 if (!NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014096 {
14097 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Interface is down"));
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014098 }
14099#endif
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014100 pScanInfo = &pHddCtx->scan_info;
14101
Jeff Johnson295189b2012-06-20 16:38:30 -070014102 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014103 "%s called with halHandle = %pK, pContext = %pK,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080014104 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014105 __func__, halHandle, pContext, (int) scanId, (int) status);
14106
Kiet Lamac06e2c2013-10-23 16:25:07 +053014107 pScanInfo->mScanPendingCounter = 0;
14108
Jeff Johnson295189b2012-06-20 16:38:30 -070014109 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014110 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070014111 &pScanInfo->scan_req_completion_event,
14112 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014113 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070014114 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014115 hddLog(VOS_TRACE_LEVEL_ERROR,
14116 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070014117 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070014118 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014119 }
14120
Yue Maef608272013-04-08 23:09:17 -070014121 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070014122 {
14123 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070014124 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014125 }
14126
14127 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014128 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070014129 {
14130 hddLog(VOS_TRACE_LEVEL_INFO,
14131 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080014132 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070014133 (int) scanId);
14134 }
14135
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014136#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014137 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014138#endif
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014139 {
14140 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
14141 pAdapter);
14142 if (0 > ret)
14143 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014144 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014145
Jeff Johnson295189b2012-06-20 16:38:30 -070014146 /* If any client wait scan result through WEXT
14147 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014148 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070014149 {
14150 /* The other scan request waiting for current scan finish
14151 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014152 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070014153 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014154 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070014155 }
14156 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014157 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070014158 {
14159 struct net_device *dev = pAdapter->dev;
14160 union iwreq_data wrqu;
14161 int we_event;
14162 char *msg;
14163
14164 memset(&wrqu, '\0', sizeof(wrqu));
14165 we_event = SIOCGIWSCAN;
14166 msg = NULL;
14167 wireless_send_event(dev, we_event, &wrqu, msg);
14168 }
14169 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014170 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014171
14172 /* Get the Scan Req */
14173 req = pAdapter->request;
mukul sharmae7041822015-12-03 15:09:21 +053014174 pAdapter->request = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014175
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014176 /* Scan is no longer pending */
14177 pScanInfo->mScanPending = VOS_FALSE;
14178
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014179 if (!wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Jeff Johnson295189b2012-06-20 16:38:30 -070014180 {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014181#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
14182 hddLog(VOS_TRACE_LEVEL_ERROR, FL("interface state %s"),
Mukul Sharmab392b642017-08-17 17:45:29 +053014183 NET_DEV_IS_IFF_UP(pAdapter) ? "up" : "down");
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014184#endif
14185
14186 if (pAdapter->dev) {
14187 hddLog(VOS_TRACE_LEVEL_ERROR, FL("device name %s"),
14188 pAdapter->dev->name);
14189 }
mukul sharmae7041822015-12-03 15:09:21 +053014190 complete(&pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -070014191 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014192 }
14193
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014194 /* last_scan_timestamp is used to decide if new scan
14195 * is needed or not on station interface. If last station
14196 * scan time and new station scan time is less then
14197 * last_scan_timestamp ; driver will return cached scan.
14198 */
14199 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
14200 {
14201 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
14202
14203 if ( req->n_channels )
14204 {
14205 for (i = 0; i < req->n_channels ; i++ )
14206 {
14207 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
14208 }
14209 /* store no of channel scanned */
14210 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
14211 }
14212
14213 }
14214
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070014215 /*
14216 * cfg80211_scan_done informing NL80211 about completion
14217 * of scanning
14218 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014219 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
14220 {
14221 aborted = true;
14222 }
mukul sharmae7041822015-12-03 15:09:21 +053014223
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014224#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014225 if (NET_DEV_IS_IFF_UP(pAdapter) &&
14226 wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014227#endif
14228 cfg80211_scan_done(req, aborted);
mukul sharmae7041822015-12-03 15:09:21 +053014229
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080014230 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070014231
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014232allow_suspend:
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053014233 if ((pHddCtx->cfg_ini->enableMacSpoofing == MAC_ADDR_SPOOFING_FW_HOST_ENABLE
14234 ) && (pHddCtx->spoofMacAddr.isEnabled
14235 || pHddCtx->spoofMacAddr.isReqDeferred)) {
Siddharth Bhal76972212014-10-15 16:22:51 +053014236 /* Generate new random mac addr for next scan */
14237 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +053014238
14239 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
14240 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhal76972212014-10-15 16:22:51 +053014241 }
14242
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070014243 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014244 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070014245
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070014246 /* Acquire wakelock to handle the case where APP's tries to suspend
14247 * immediatly after the driver gets connect request(i.e after scan)
14248 * from supplicant, this result in app's is suspending and not able
14249 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014250 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070014251
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014252#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014253 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014254#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070014255#ifdef FEATURE_WLAN_TDLS
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014256 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070014257#endif
14258
Jeff Johnson295189b2012-06-20 16:38:30 -070014259 EXIT();
14260 return 0;
14261}
14262
14263/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053014264 * FUNCTION: hdd_isConnectionInProgress
14265 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014266 *
14267 */
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014268v_BOOL_t hdd_isConnectionInProgress(hdd_context_t *pHddCtx, v_U8_t *session_id,
14269 scan_reject_states *reason)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014270{
14271 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
14272 hdd_station_ctx_t *pHddStaCtx = NULL;
14273 hdd_adapter_t *pAdapter = NULL;
14274 VOS_STATUS status = 0;
14275 v_U8_t staId = 0;
14276 v_U8_t *staMac = NULL;
14277
14278 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
14279
14280 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
14281 {
14282 pAdapter = pAdapterNode->pAdapter;
14283
14284 if( pAdapter )
14285 {
14286 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014287 "%s: Adapter with device mode %s (%d) exists",
14288 __func__, hdd_device_modetoString(pAdapter->device_mode),
14289 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014290 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053014291 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
14292 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
14293 (eConnectionState_Connecting ==
14294 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
14295 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014296 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014297 "%s: %pK(%d) Connection is in progress", __func__,
Rashmi Ramannab1429032014-04-26 14:59:09 +053014298 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014299 if (session_id && reason)
14300 {
14301 *session_id = pAdapter->sessionId;
14302 *reason = eHDD_CONNECTION_IN_PROGRESS;
14303 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053014304 return VOS_TRUE;
14305 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014306 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053014307 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014308 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014309 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014310 "%s: %pK(%d) Reassociation is in progress", __func__,
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014311 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014312 if (session_id && reason)
14313 {
14314 *session_id = pAdapter->sessionId;
14315 *reason = eHDD_REASSOC_IN_PROGRESS;
14316 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014317 return VOS_TRUE;
14318 }
14319 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014320 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
14321 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014322 {
14323 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14324 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014325 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014326 {
14327 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014328 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080014329 "%s: client " MAC_ADDRESS_STR
14330 " is in the middle of WPS/EAPOL exchange.", __func__,
14331 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014332 if (session_id && reason)
14333 {
14334 *session_id = pAdapter->sessionId;
14335 *reason = eHDD_EAPOL_IN_PROGRESS;
14336 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053014337 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014338 }
14339 }
14340 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
14341 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
14342 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014343 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
14344 ptSapContext pSapCtx = NULL;
14345 pSapCtx = VOS_GET_SAP_CB(pVosContext);
14346 if(pSapCtx == NULL){
14347 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14348 FL("psapCtx is NULL"));
14349 return VOS_FALSE;
14350 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014351 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
14352 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014353 if ((pSapCtx->aStaInfo[staId].isUsed) &&
14354 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014355 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014356 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014357
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014358 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080014359 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
14360 "middle of WPS/EAPOL exchange.", __func__,
14361 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014362 if (session_id && reason)
14363 {
14364 *session_id = pAdapter->sessionId;
14365 *reason = eHDD_SAP_EAPOL_IN_PROGRESS;
14366 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053014367 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014368 }
14369 }
14370 }
14371 }
14372 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
14373 pAdapterNode = pNext;
14374 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053014375 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014376}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014377
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053014378/**
14379 * csr_scan_request_assign_bssid() - Set the BSSID received from Supplicant
14380 * to the Scan request
14381 * @scanRequest: Pointer to the csr scan request
14382 * @request: Pointer to the scan request from supplicant
14383 *
14384 * Return: None
14385 */
14386#ifdef CFG80211_SCAN_BSSID
14387static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
14388 struct cfg80211_scan_request *request)
14389{
14390 vos_mem_copy(scanRequest->bssid, request->bssid, VOS_MAC_ADDR_SIZE);
14391}
14392#else
14393static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
14394 struct cfg80211_scan_request *request)
14395{
14396}
14397#endif
14398
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014399/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014400 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070014401 * this scan respond to scan trigger and update cfg80211 scan database
14402 * later, scan dump command can be used to recieve scan results
14403 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014404int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080014405#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
14406 struct net_device *dev,
14407#endif
14408 struct cfg80211_scan_request *request)
14409{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053014410 hdd_adapter_t *pAdapter = NULL;
14411 hdd_context_t *pHddCtx = NULL;
14412 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014413 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014414 tCsrScanRequest scanRequest;
14415 tANI_U8 *channelList = NULL, i;
14416 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014417 int status;
14418 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014419 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014420 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053014421 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053014422 bool is_p2p_scan = false;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014423 v_U8_t curr_session_id;
14424 scan_reject_states curr_reason;
Jeff Johnson295189b2012-06-20 16:38:30 -070014425
Siddharth Bhal0c162d02014-05-06 19:50:42 +053014426#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
14427 struct net_device *dev = NULL;
14428 if (NULL == request)
14429 {
14430 hddLog(VOS_TRACE_LEVEL_ERROR,
14431 "%s: scan req param null", __func__);
14432 return -EINVAL;
14433 }
14434 dev = request->wdev->netdev;
14435#endif
14436
14437 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
14438 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
14439 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
14440
Jeff Johnson295189b2012-06-20 16:38:30 -070014441 ENTER();
14442
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014443 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
14444 __func__, hdd_device_modetoString(pAdapter->device_mode),
14445 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014446
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014447 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014448 if (0 != status)
14449 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014450 return status;
14451 }
14452
Siddharth Bhal0c162d02014-05-06 19:50:42 +053014453 if (NULL == pwextBuf)
14454 {
14455 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
14456 __func__);
14457 return -EIO;
14458 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014459 cfg_param = pHddCtx->cfg_ini;
14460 pScanInfo = &pHddCtx->scan_info;
14461
Jeff Johnson295189b2012-06-20 16:38:30 -070014462#ifdef WLAN_BTAMP_FEATURE
14463 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080014464 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070014465 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080014466 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014467 "%s: No scanning when AMP is on", __func__);
14468 return -EOPNOTSUPP;
14469 }
14470#endif
14471 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080014472 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070014473 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080014474 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014475 "%s: Not scanning on device_mode = %s (%d)",
14476 __func__, hdd_device_modetoString(pAdapter->device_mode),
14477 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070014478 return -EOPNOTSUPP;
14479 }
14480
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053014481 if (pAdapter->device_mode == WLAN_HDD_MONITOR) {
14482 hddLog(LOGE, FL("Scan is not supported for monitor adapter"));
14483 return -EOPNOTSUPP;
14484 }
14485
Jeff Johnson295189b2012-06-20 16:38:30 -070014486 if (TRUE == pScanInfo->mScanPending)
14487 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053014488 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
14489 {
14490 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
14491 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080014492 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070014493 }
14494
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053014495 // Don't allow scan if PNO scan is going on.
14496 if (pHddCtx->isPnoEnable)
14497 {
14498 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14499 FL("pno scan in progress"));
14500 return -EBUSY;
14501 }
14502
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014503 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070014504 //Channel and action frame is pending
14505 //Otherwise Cancel Remain On Channel and allow Scan
14506 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080014507 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070014508 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053014509 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070014510 return -EBUSY;
14511 }
14512
Jeff Johnson295189b2012-06-20 16:38:30 -070014513 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
14514 {
14515 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080014516 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014517 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014518 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014519 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
14520 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014521 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014522 "%s: MAX TM Level Scan not allowed", __func__);
14523 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014524 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070014525 }
14526 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
14527
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014528 /* Check if scan is allowed at this point of time.
14529 */
Hanumanth Reddy Pothulaec960842016-09-14 19:04:26 +053014530 if (TRUE == pHddCtx->btCoexModeSet)
14531 {
14532 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14533 FL("BTCoex Mode operation in progress"));
14534 return -EBUSY;
14535 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014536 if (hdd_isConnectionInProgress(pHddCtx, &curr_session_id, &curr_reason))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014537 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014538
14539 if (!(pHddCtx->scan_reject_cnt % HDD_SCAN_REJECT_RATE_LIMIT))
14540 hddLog(LOGE, FL("Scan not allowed Session %d reason %d"),
14541 curr_session_id, curr_reason);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014542 if (pHddCtx->last_scan_reject_session_id != curr_session_id ||
14543 pHddCtx->last_scan_reject_reason != curr_reason ||
14544 !pHddCtx->last_scan_reject_timestamp)
14545 {
14546 pHddCtx->last_scan_reject_session_id = curr_session_id;
14547 pHddCtx->last_scan_reject_reason = curr_reason;
Abhishek Singh3e500772017-07-17 10:13:43 +053014548 pHddCtx->last_scan_reject_timestamp =
14549 jiffies_to_msecs(jiffies) + SCAN_REJECT_THRESHOLD_TIME;
Abhishek Singhe4b12562017-06-20 16:53:39 +053014550 pHddCtx->scan_reject_cnt = 0;
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053014551 }
Abhishek Singhe4b12562017-06-20 16:53:39 +053014552 else
14553 {
14554 pHddCtx->scan_reject_cnt++;
14555
Abhishek Singhe4b12562017-06-20 16:53:39 +053014556 if ((pHddCtx->scan_reject_cnt >=
14557 SCAN_REJECT_THRESHOLD) &&
Abhishek Singh3e500772017-07-17 10:13:43 +053014558 vos_system_time_after(jiffies_to_msecs(jiffies),
14559 pHddCtx->last_scan_reject_timestamp))
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014560 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014561 hddLog(LOGE, FL("Session %d reason %d reject cnt %d threshold time has elapsed? %d"),
14562 curr_session_id, curr_reason, pHddCtx->scan_reject_cnt,
14563 vos_system_time_after(jiffies_to_msecs(jiffies),
14564 pHddCtx->last_scan_reject_timestamp));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014565 pHddCtx->last_scan_reject_timestamp = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053014566 pHddCtx->scan_reject_cnt = 0;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014567 if (pHddCtx->cfg_ini->enableFatalEvent)
14568 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
14569 WLAN_LOG_INDICATOR_HOST_DRIVER,
14570 WLAN_LOG_REASON_SCAN_NOT_ALLOWED,
14571 FALSE, FALSE);
14572 else
14573 {
14574 hddLog(LOGE, FL("Triggering SSR"));
14575 vos_wlanRestart();
14576 }
14577 }
14578 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014579 return -EBUSY;
14580 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014581 pHddCtx->last_scan_reject_timestamp = 0;
14582 pHddCtx->last_scan_reject_session_id = 0xFF;
14583 pHddCtx->last_scan_reject_reason = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053014584 pHddCtx->scan_reject_cnt = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014585
Jeff Johnson295189b2012-06-20 16:38:30 -070014586 vos_mem_zero( &scanRequest, sizeof(scanRequest));
14587
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014588 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
14589 * Becasue of this, driver is assuming that this is not wildcard scan and so
14590 * is not aging out the scan results.
14591 */
Hanumanth Reddy Pothula998efeb2017-10-31 15:43:19 +053014592 if ((request->ssids) && (request->n_ssids == 1) &&
14593 ('\0' == request->ssids->ssid[0])) {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014594 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014595 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014596
14597 if ((request->ssids) && (0 < request->n_ssids))
14598 {
14599 tCsrSSIDInfo *SsidInfo;
14600 int j;
14601 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
14602 /* Allocate num_ssid tCsrSSIDInfo structure */
14603 SsidInfo = scanRequest.SSIDs.SSIDList =
14604 ( tCsrSSIDInfo *)vos_mem_malloc(
14605 request->n_ssids*sizeof(tCsrSSIDInfo));
14606
14607 if(NULL == scanRequest.SSIDs.SSIDList)
14608 {
14609 hddLog(VOS_TRACE_LEVEL_ERROR,
14610 "%s: memory alloc failed SSIDInfo buffer", __func__);
14611 return -ENOMEM;
14612 }
14613
14614 /* copy all the ssid's and their length */
14615 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
14616 {
14617 /* get the ssid length */
14618 SsidInfo->SSID.length = request->ssids[j].ssid_len;
14619 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
14620 SsidInfo->SSID.length);
14621 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
14622 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
14623 j, SsidInfo->SSID.ssId);
14624 }
14625 /* set the scan type to active */
14626 scanRequest.scanType = eSIR_ACTIVE_SCAN;
14627 }
14628 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070014629 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053014630 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14631 TRACE_CODE_HDD_CFG80211_SCAN,
14632 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070014633 /* set the scan type to active */
14634 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070014635 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014636 else
14637 {
14638 /*Set the scan type to default type, in this case it is ACTIVE*/
14639 scanRequest.scanType = pScanInfo->scan_mode;
14640 }
14641 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
14642 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070014643
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053014644 csr_scan_request_assign_bssid(&scanRequest, request);
14645
Jeff Johnson295189b2012-06-20 16:38:30 -070014646 /* set BSSType to default type */
14647 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
14648
14649 /*TODO: scan the requested channels only*/
14650
14651 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014652 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070014653 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014654 hddLog(VOS_TRACE_LEVEL_WARN,
14655 "No of Scan Channels exceeded limit: %d", request->n_channels);
14656 request->n_channels = MAX_CHANNEL;
14657 }
14658
14659 hddLog(VOS_TRACE_LEVEL_INFO,
14660 "No of Scan Channels: %d", request->n_channels);
14661
14662
14663 if( request->n_channels )
14664 {
14665 char chList [(request->n_channels*5)+1];
14666 int len;
14667 channelList = vos_mem_malloc( request->n_channels );
14668 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053014669 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014670 hddLog(VOS_TRACE_LEVEL_ERROR,
14671 "%s: memory alloc failed channelList", __func__);
14672 status = -ENOMEM;
14673 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053014674 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014675
14676 for( i = 0, len = 0; i < request->n_channels ; i++ )
14677 {
14678 channelList[i] = request->channels[i]->hw_value;
14679 len += snprintf(chList+len, 5, "%d ", channelList[i]);
14680 }
14681
Nirav Shah20ac06f2013-12-12 18:14:06 +053014682 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014683 "Channel-List: %s ", chList);
14684 }
c_hpothu53512302014-04-15 18:49:53 +053014685
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014686 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
14687 scanRequest.ChannelInfo.ChannelList = channelList;
14688
14689 /* set requestType to full scan */
14690 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
14691
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014692 /* if there is back to back scan happening in driver with in
14693 * nDeferScanTimeInterval interval driver should defer new scan request
14694 * and should provide last cached scan results instead of new channel list.
14695 * This rule is not applicable if scan is p2p scan.
14696 * This condition will work only in case when last request no of channels
14697 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053014698 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053014699 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014700 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014701
Sushant Kaushik86592172015-04-27 16:35:03 +053014702 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
14703 /* if wps ie is NULL , then only defer scan */
14704 if ( pWpsIe == NULL &&
14705 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053014706 {
14707 if ( pScanInfo->last_scan_timestamp !=0 &&
14708 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
14709 {
14710 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
14711 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
14712 vos_mem_compare(pScanInfo->last_scan_channelList,
14713 channelList, pScanInfo->last_scan_numChannels))
14714 {
14715 hddLog(VOS_TRACE_LEVEL_WARN,
14716 " New and old station scan time differ is less then %u",
14717 pHddCtx->cfg_ini->nDeferScanTimeInterval);
14718
14719 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014720 pAdapter);
14721
Agarwal Ashish57e84372014-12-05 18:26:53 +053014722 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053014723 "Return old cached scan as all channels and no of channels are same");
14724
Agarwal Ashish57e84372014-12-05 18:26:53 +053014725 if (0 > ret)
14726 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014727
Agarwal Ashish57e84372014-12-05 18:26:53 +053014728 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053014729
14730 status = eHAL_STATUS_SUCCESS;
14731 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053014732 }
14733 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014734 }
14735
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014736 /* Flush the scan results(only p2p beacons) for STA scan and P2P
14737 * search (Flush on both full scan and social scan but not on single
14738 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
14739 */
14740
14741 /* Supplicant does single channel scan after 8-way handshake
14742 * and in that case driver shoudnt flush scan results. If
14743 * driver flushes the scan results here and unfortunately if
14744 * the AP doesnt respond to our probe req then association
14745 * fails which is not desired
14746 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053014747 if ((request->n_ssids == 1)
14748 && (request->ssids != NULL)
14749 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
14750 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014751
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053014752 if( is_p2p_scan ||
14753 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014754 {
14755 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
14756 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
14757 pAdapter->sessionId );
14758 }
14759
14760 if( request->ie_len )
14761 {
14762 /* save this for future association (join requires this) */
14763 /*TODO: Array needs to be converted to dynamic allocation,
14764 * as multiple ie.s can be sent in cfg80211_scan_request structure
14765 * CR 597966
14766 */
14767 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
14768 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
14769 pScanInfo->scanAddIE.length = request->ie_len;
14770
14771 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
14772 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
14773 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070014774 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014775 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070014776 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014777 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
14778 memcpy( pwextBuf->roamProfile.addIEScan,
14779 request->ie, request->ie_len);
14780 }
14781 else
14782 {
14783 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
14784 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070014785 }
14786
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014787 }
14788 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
14789 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
14790
14791 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
14792 request->ie_len);
14793 if (pP2pIe != NULL)
14794 {
14795#ifdef WLAN_FEATURE_P2P_DEBUG
14796 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
14797 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
14798 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053014799 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014800 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
14801 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
14802 "Go nego completed to Connection is started");
14803 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
14804 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053014805 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014806 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
14807 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070014808 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014809 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
14810 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
14811 "Disconnected state to Connection is started");
14812 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
14813 "for 4way Handshake");
14814 }
14815#endif
14816
14817 /* no_cck will be set during p2p find to disable 11b rates */
14818 if(TRUE == request->no_cck)
14819 {
14820 hddLog(VOS_TRACE_LEVEL_INFO,
14821 "%s: This is a P2P Search", __func__);
14822 scanRequest.p2pSearch = 1;
14823
14824 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053014825 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014826 /* set requestType to P2P Discovery */
14827 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
14828 }
14829
14830 /*
14831 Skip Dfs Channel in case of P2P Search
14832 if it is set in ini file
14833 */
14834 if(cfg_param->skipDfsChnlInP2pSearch)
14835 {
14836 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053014837 }
14838 else
14839 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014840 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053014841 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014842
Agarwal Ashish4f616132013-12-30 23:32:50 +053014843 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014844 }
14845 }
14846
14847 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
14848
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014849#ifdef FEATURE_WLAN_TDLS
14850 /* if tdls disagree scan right now, return immediately.
14851 tdls will schedule the scan when scan is allowed. (return SUCCESS)
14852 or will reject the scan if any TDLS is in progress. (return -EBUSY)
14853 */
14854 status = wlan_hdd_tdls_scan_callback (pAdapter,
14855 wiphy,
14856#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
14857 dev,
14858#endif
14859 request);
Abhishek Singhe2b63952016-01-05 18:27:29 +053014860 if (status <= 0)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014861 {
Abhishek Singhe2b63952016-01-05 18:27:29 +053014862 if (!status)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014863 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
14864 "scan rejected %d", __func__, status);
14865 else
14866 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
14867 __func__, status);
Abhishek Singhe2b63952016-01-05 18:27:29 +053014868 hdd_wlan_block_scan_by_tdls();
Gupta, Kapil2ebf3e02016-03-17 19:45:19 +053014869 goto free_mem;
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014870 }
14871#endif
14872
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070014873 /* acquire the wakelock to avoid the apps suspend during the scan. To
14874 * address the following issues.
14875 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
14876 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
14877 * for long time, this result in apps running at full power for long time.
14878 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
14879 * be stuck in full power because of resume BMPS
14880 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014881 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070014882
Nirav Shah20ac06f2013-12-12 18:14:06 +053014883 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
14884 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014885 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
14886 scanRequest.requestType, scanRequest.scanType,
14887 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053014888 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
14889
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053014890 if (pHddCtx->spoofMacAddr.isEnabled &&
14891 pHddCtx->cfg_ini->enableMacSpoofing == 1)
Siddharth Bhal76972212014-10-15 16:22:51 +053014892 {
14893 hddLog(VOS_TRACE_LEVEL_INFO,
14894 "%s: MAC Spoofing enabled for current scan", __func__);
14895 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
14896 * to fill TxBds for probe request during current scan
14897 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053014898 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053014899 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053014900
14901 if(status != VOS_STATUS_SUCCESS)
14902 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014903 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053014904 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053014905#ifdef FEATURE_WLAN_TDLS
14906 wlan_hdd_tdls_scan_done_callback(pAdapter);
14907#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053014908 goto free_mem;
14909 }
Siddharth Bhal76972212014-10-15 16:22:51 +053014910 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053014911 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070014912 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070014913 pAdapter->sessionId, &scanRequest, &scanId,
14914 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070014915
Jeff Johnson295189b2012-06-20 16:38:30 -070014916 if (eHAL_STATUS_SUCCESS != status)
14917 {
14918 hddLog(VOS_TRACE_LEVEL_ERROR,
14919 "%s: sme_ScanRequest returned error %d", __func__, status);
14920 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070014921 if(eHAL_STATUS_RESOURCES == status)
14922 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014923 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
14924 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070014925 status = -EBUSY;
14926 } else {
14927 status = -EIO;
14928 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014929 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014930
14931#ifdef FEATURE_WLAN_TDLS
14932 wlan_hdd_tdls_scan_done_callback(pAdapter);
14933#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014934 goto free_mem;
14935 }
14936
14937 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053014938 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070014939 pAdapter->request = request;
14940 pScanInfo->scanId = scanId;
14941
14942 complete(&pScanInfo->scan_req_completion_event);
14943
14944free_mem:
14945 if( scanRequest.SSIDs.SSIDList )
14946 {
14947 vos_mem_free(scanRequest.SSIDs.SSIDList);
14948 }
14949
14950 if( channelList )
14951 vos_mem_free( channelList );
14952
14953 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014954 return status;
14955}
14956
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014957int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
14958#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
14959 struct net_device *dev,
14960#endif
14961 struct cfg80211_scan_request *request)
14962{
14963 int ret;
14964
14965 vos_ssr_protect(__func__);
14966 ret = __wlan_hdd_cfg80211_scan(wiphy,
14967#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
14968 dev,
14969#endif
14970 request);
14971 vos_ssr_unprotect(__func__);
14972
14973 return ret;
14974}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014975
14976void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
14977{
14978 v_U8_t iniDot11Mode =
14979 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
14980 eHddDot11Mode hddDot11Mode = iniDot11Mode;
14981
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014982 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
14983 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014984 switch ( iniDot11Mode )
14985 {
14986 case eHDD_DOT11_MODE_AUTO:
14987 case eHDD_DOT11_MODE_11ac:
14988 case eHDD_DOT11_MODE_11ac_ONLY:
14989#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053014990 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
14991 sme_IsFeatureSupportedByFW(DOT11AC) )
14992 hddDot11Mode = eHDD_DOT11_MODE_11ac;
14993 else
14994 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014995#else
14996 hddDot11Mode = eHDD_DOT11_MODE_11n;
14997#endif
14998 break;
14999 case eHDD_DOT11_MODE_11n:
15000 case eHDD_DOT11_MODE_11n_ONLY:
15001 hddDot11Mode = eHDD_DOT11_MODE_11n;
15002 break;
15003 default:
15004 hddDot11Mode = iniDot11Mode;
15005 break;
15006 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053015007#ifdef WLAN_FEATURE_AP_HT40_24G
15008 if (operationChannel > SIR_11B_CHANNEL_END)
15009#endif
15010 {
15011 /* This call decides required channel bonding mode */
15012 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015013 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
Abhishek Singh02b823e2017-10-30 17:53:20 +053015014 operationChannel, eHT_MAX_CHANNEL_WIDTH);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053015015 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015016}
15017
Jeff Johnson295189b2012-06-20 16:38:30 -070015018/*
15019 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015020 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070015021 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015022int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053015023 const u8 *ssid, size_t ssid_len, const u8 *bssid,
15024 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070015025{
15026 int status = 0;
15027 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080015028 hdd_context_t *pHddCtx;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053015029 hdd_station_ctx_t *hdd_sta_ctx;
Jeff Johnson295189b2012-06-20 16:38:30 -070015030 v_U32_t roamId;
15031 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070015032 eCsrAuthType RSNAuthType;
15033
15034 ENTER();
15035
15036 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080015037 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053015038 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080015039
15040 status = wlan_hdd_validate_context(pHddCtx);
15041 if (status)
15042 {
Yue Mae36e3552014-03-05 17:06:20 -080015043 return status;
15044 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015045
Jeff Johnson295189b2012-06-20 16:38:30 -070015046 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
15047 {
15048 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
15049 return -EINVAL;
15050 }
15051
Nitesh Shah9b066282017-06-06 18:05:52 +053015052 wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
15053
Jeff Johnson295189b2012-06-20 16:38:30 -070015054 pRoamProfile = &pWextState->roamProfile;
15055
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015056 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070015057 {
Jeff Johnsone7245742012-09-05 17:12:55 -070015058 hdd_station_ctx_t *pHddStaCtx;
15059 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Abhishek Singh6782c9e2017-06-06 13:37:45 +053015060 pHddStaCtx->get_mgmt_log_sent = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015061
Siddharth Bhalda0d1622015-04-24 15:47:49 +053015062 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
15063
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015064 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070015065 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
15066 {
15067 /*QoS not enabled in cfg file*/
15068 pRoamProfile->uapsd_mask = 0;
15069 }
15070 else
15071 {
15072 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015073 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070015074 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
15075 }
15076
15077 pRoamProfile->SSIDs.numOfSSIDs = 1;
15078 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
15079 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015080 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070015081 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
15082 ssid, ssid_len);
15083
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015084 vos_mem_zero(pRoamProfile->BSSIDs.bssid, WNI_CFG_BSSID_LEN);
15085 vos_mem_zero(pRoamProfile->bssid_hint, WNI_CFG_BSSID_LEN);
15086
Jeff Johnson295189b2012-06-20 16:38:30 -070015087 if (bssid)
15088 {
15089 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015090 vos_mem_copy(pRoamProfile->BSSIDs.bssid, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070015091 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015092 /* Save BSSID in seperate variable as well, as RoamProfile
15093 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070015094 case of join failure we should send valid BSSID to supplicant
15095 */
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015096 vos_mem_copy(pWextState->req_bssId, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070015097 WNI_CFG_BSSID_LEN);
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015098
Jeff Johnson295189b2012-06-20 16:38:30 -070015099 }
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015100 else if (bssid_hint)
Dhanashri Atre51981c62013-06-13 11:47:57 -070015101 {
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015102 /* Store bssid_hint to use in the scan filter. */
15103 vos_mem_copy(pRoamProfile->bssid_hint, bssid_hint,
15104 WNI_CFG_BSSID_LEN);
15105 /*
15106 * Save BSSID in seperate variable as well, as RoamProfile
15107 * BSSID is getting zeroed out in the association process. And in
15108 * case of join failure we should send valid BSSID to supplicant
15109 */
15110 vos_mem_copy(pWextState->req_bssId, bssid_hint,
15111 WNI_CFG_BSSID_LEN);
15112 hddLog(LOG1, FL(" bssid_hint: "MAC_ADDRESS_STR),
15113 MAC_ADDR_ARRAY(pRoamProfile->bssid_hint));
Dhanashri Atre51981c62013-06-13 11:47:57 -070015114 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015115
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015116
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015117 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
15118 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070015119 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
15120 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015121 {
Jeff Johnson295189b2012-06-20 16:38:30 -070015122 /*set gen ie*/
15123 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
15124 /*set auth*/
15125 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
15126 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015127#ifdef FEATURE_WLAN_WAPI
15128 if (pAdapter->wapi_info.nWapiMode)
15129 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015130 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015131 switch (pAdapter->wapi_info.wapiAuthMode)
15132 {
15133 case WAPI_AUTH_MODE_PSK:
15134 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015135 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015136 pAdapter->wapi_info.wapiAuthMode);
15137 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
15138 break;
15139 }
15140 case WAPI_AUTH_MODE_CERT:
15141 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015142 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015143 pAdapter->wapi_info.wapiAuthMode);
15144 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
15145 break;
15146 }
15147 } // End of switch
15148 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
15149 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
15150 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015151 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015152 pRoamProfile->AuthType.numEntries = 1;
15153 pRoamProfile->EncryptionType.numEntries = 1;
15154 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
15155 pRoamProfile->mcEncryptionType.numEntries = 1;
15156 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
15157 }
15158 }
15159#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015160#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015161 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015162 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
15163 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
15164 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015165 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
15166 sizeof (tSirGtkOffloadParams));
15167 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015168 }
15169#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015170 pRoamProfile->csrPersona = pAdapter->device_mode;
15171
Jeff Johnson32d95a32012-09-10 13:15:23 -070015172 if( operatingChannel )
15173 {
15174 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
15175 pRoamProfile->ChannelInfo.numOfChannels = 1;
15176 }
Chet Lanctot186b5732013-03-18 10:26:30 -070015177 else
15178 {
15179 pRoamProfile->ChannelInfo.ChannelList = NULL;
15180 pRoamProfile->ChannelInfo.numOfChannels = 0;
15181 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015182 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
15183 {
15184 hdd_select_cbmode(pAdapter,operatingChannel);
15185 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015186
Agarwal Ashish40f9b872015-09-01 16:17:35 +053015187 /*
15188 * Change conn_state to connecting before sme_RoamConnect(),
15189 * because sme_RoamConnect() has a direct path to call
15190 * hdd_smeRoamCallback(), which will change the conn_state
15191 * If direct path, conn_state will be accordingly changed
15192 * to NotConnected or Associated by either
15193 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
15194 * in sme_RoamCallback()
15195 * if sme_RomConnect is to be queued,
15196 * Connecting state will remain until it is completed.
15197 * If connection state is not changed,
15198 * connection state will remain in eConnectionState_NotConnected state.
15199 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
15200 * if conn state is eConnectionState_NotConnected.
15201 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
15202 * informed of connect result indication which is an issue.
15203 */
15204
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053015205 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
15206 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053015207 {
15208 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053015209 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080015210 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
15211 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053015212 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015213 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070015214 pAdapter->sessionId, pRoamProfile, &roamId);
15215
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053015216 if ((eHAL_STATUS_SUCCESS != status) &&
15217 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
15218 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053015219
15220 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053015221 hddLog(VOS_TRACE_LEVEL_ERROR,
15222 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
15223 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080015224 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053015225 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080015226 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053015227 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080015228
15229 pRoamProfile->ChannelInfo.ChannelList = NULL;
15230 pRoamProfile->ChannelInfo.numOfChannels = 0;
15231
Jeff Johnson295189b2012-06-20 16:38:30 -070015232 }
15233 else
15234 {
15235 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
15236 return -EINVAL;
15237 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080015238 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015239 return status;
15240}
15241
15242/*
15243 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
15244 * This function is used to set the authentication type (OPEN/SHARED).
15245 *
15246 */
15247static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
15248 enum nl80211_auth_type auth_type)
15249{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015250 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070015251 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15252
15253 ENTER();
15254
15255 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015256 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070015257 {
Jeff Johnson295189b2012-06-20 16:38:30 -070015258 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053015259 hddLog(VOS_TRACE_LEVEL_INFO,
15260 "%s: set authentication type to AUTOSWITCH", __func__);
15261 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
15262 break;
15263
15264 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015265#ifdef WLAN_FEATURE_VOWIFI_11R
15266 case NL80211_AUTHTYPE_FT:
15267#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015268 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070015269 "%s: set authentication type to OPEN", __func__);
15270 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
15271 break;
15272
15273 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015274 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070015275 "%s: set authentication type to SHARED", __func__);
15276 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
15277 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080015278#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070015279 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015280 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070015281 "%s: set authentication type to CCKM WPA", __func__);
15282 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
15283 break;
15284#endif
15285
15286
15287 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015288 hddLog(VOS_TRACE_LEVEL_ERROR,
15289 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015290 auth_type);
15291 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
15292 return -EINVAL;
15293 }
15294
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015295 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070015296 pHddStaCtx->conn_info.authType;
15297 return 0;
15298}
15299
15300/*
15301 * FUNCTION: wlan_hdd_set_akm_suite
15302 * This function is used to set the key mgmt type(PSK/8021x).
15303 *
15304 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015305static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070015306 u32 key_mgmt
15307 )
15308{
15309 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15310 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053015311 /* Should be in ieee802_11_defs.h */
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053015312#ifndef WLAN_AKM_SUITE_8021X_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053015313#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053015314#endif
15315#ifndef WLAN_AKM_SUITE_PSK_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053015316#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053015317#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015318 /*set key mgmt type*/
15319 switch(key_mgmt)
15320 {
15321 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053015322 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053015323#ifdef WLAN_FEATURE_VOWIFI_11R
15324 case WLAN_AKM_SUITE_FT_PSK:
15325#endif
15326 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070015327 __func__);
15328 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
15329 break;
15330
15331 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053015332 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053015333#ifdef WLAN_FEATURE_VOWIFI_11R
15334 case WLAN_AKM_SUITE_FT_8021X:
15335#endif
15336 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070015337 __func__);
15338 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
15339 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080015340#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070015341#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
15342#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
15343 case WLAN_AKM_SUITE_CCKM:
15344 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
15345 __func__);
15346 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
15347 break;
15348#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070015349#ifndef WLAN_AKM_SUITE_OSEN
15350#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
15351 case WLAN_AKM_SUITE_OSEN:
15352 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
15353 __func__);
15354 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
15355 break;
15356#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015357
15358 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015359 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015360 __func__, key_mgmt);
15361 return -EINVAL;
15362
15363 }
15364 return 0;
15365}
15366
15367/*
15368 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015369 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070015370 * (NONE/WEP40/WEP104/TKIP/CCMP).
15371 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015372static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
15373 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070015374 bool ucast
15375 )
15376{
15377 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015378 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070015379 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15380
15381 ENTER();
15382
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015383 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070015384 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053015385 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070015386 __func__, cipher);
15387 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
15388 }
15389 else
15390 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015391
Jeff Johnson295189b2012-06-20 16:38:30 -070015392 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015393 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070015394 {
15395 case IW_AUTH_CIPHER_NONE:
15396 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
15397 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015398
Jeff Johnson295189b2012-06-20 16:38:30 -070015399 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053015400 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070015401 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015402
Jeff Johnson295189b2012-06-20 16:38:30 -070015403 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053015404 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070015405 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015406
Jeff Johnson295189b2012-06-20 16:38:30 -070015407 case WLAN_CIPHER_SUITE_TKIP:
15408 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
15409 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015410
Jeff Johnson295189b2012-06-20 16:38:30 -070015411 case WLAN_CIPHER_SUITE_CCMP:
15412 encryptionType = eCSR_ENCRYPT_TYPE_AES;
15413 break;
15414#ifdef FEATURE_WLAN_WAPI
15415 case WLAN_CIPHER_SUITE_SMS4:
15416 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
15417 break;
15418#endif
15419
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080015420#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070015421 case WLAN_CIPHER_SUITE_KRK:
15422 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
15423 break;
15424#endif
15425 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015426 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015427 __func__, cipher);
15428 return -EOPNOTSUPP;
15429 }
15430 }
15431
15432 if (ucast)
15433 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015434 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015435 __func__, encryptionType);
15436 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
15437 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015438 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070015439 encryptionType;
15440 }
15441 else
15442 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015443 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015444 __func__, encryptionType);
15445 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
15446 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
15447 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
15448 }
15449
15450 return 0;
15451}
15452
15453
15454/*
15455 * FUNCTION: wlan_hdd_cfg80211_set_ie
15456 * This function is used to parse WPA/RSN IE's.
15457 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015458int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015459#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15460 const u8 *ie,
15461#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015462 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015463#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015464 size_t ie_len
15465 )
15466{
15467 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015468#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15469 const u8 *genie = ie;
15470#else
Jeff Johnson295189b2012-06-20 16:38:30 -070015471 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015472#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015473 v_U16_t remLen = ie_len;
15474#ifdef FEATURE_WLAN_WAPI
15475 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
15476 u16 *tmp;
15477 v_U16_t akmsuiteCount;
15478 int *akmlist;
15479#endif
15480 ENTER();
15481
15482 /* clear previous assocAddIE */
15483 pWextState->assocAddIE.length = 0;
15484 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070015485 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015486
15487 while (remLen >= 2)
15488 {
15489 v_U16_t eLen = 0;
15490 v_U8_t elementId;
15491 elementId = *genie++;
15492 eLen = *genie++;
15493 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015494
Nachiket Kukade4aba5f02017-06-09 15:43:48 +053015495 /* Sanity check on eLen */
15496 if (eLen > remLen) {
15497 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid IE length[%d] for IE[0x%X]",
15498 __func__, eLen, elementId);
15499 VOS_ASSERT(0);
15500 return -EINVAL;
15501 }
15502
Arif Hussain6d2a3322013-11-17 19:50:10 -080015503 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070015504 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015505
15506 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070015507 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015508 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015509 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 -070015510 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015511 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015512 "%s: Invalid WPA IE", __func__);
15513 return -EINVAL;
15514 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015515 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070015516 {
15517 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015518 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070015519 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015520
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015521 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015522 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015523 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
15524 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070015525 VOS_ASSERT(0);
15526 return -ENOMEM;
15527 }
15528 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
15529 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15530 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015531
Jeff Johnson295189b2012-06-20 16:38:30 -070015532 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
15533 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15534 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15535 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015536 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
15537 {
Nachiket Kukade3d72b7e2017-06-09 16:58:24 +053015538 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
15539 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d]",
15540 __func__, eLen);
15541 VOS_ASSERT(0);
15542 return -EINVAL;
15543 }
15544
Jeff Johnson295189b2012-06-20 16:38:30 -070015545 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
15546 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
15547 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
15548 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
15549 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
15550 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015551 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053015552 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070015553 {
15554 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015555 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070015556 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015557
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015558 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015559 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015560 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15561 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070015562 VOS_ASSERT(0);
15563 return -ENOMEM;
15564 }
15565 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
15566 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15567 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015568
Jeff Johnson295189b2012-06-20 16:38:30 -070015569 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15570 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15571 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015572#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015573 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
15574 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015575 /*Consider WFD IE, only for P2P Client */
15576 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
15577 {
15578 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015579 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070015580 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015581
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015582 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015583 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015584 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15585 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070015586 VOS_ASSERT(0);
15587 return -ENOMEM;
15588 }
15589 // WFD IE is saved to Additional IE ; it should be accumulated to handle
15590 // WPS IE + P2P IE + WFD IE
15591 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15592 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015593
Jeff Johnson295189b2012-06-20 16:38:30 -070015594 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15595 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15596 }
15597#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015598 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015599 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015600 HS20_OUI_TYPE_SIZE)) )
15601 {
15602 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015603 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015604 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015605
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015606 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015607 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015608 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15609 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015610 VOS_ASSERT(0);
15611 return -ENOMEM;
15612 }
15613 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15614 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015615
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015616 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15617 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15618 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070015619 /* Appending OSEN Information Element in Assiciation Request */
15620 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
15621 OSEN_OUI_TYPE_SIZE)) )
15622 {
15623 v_U16_t curAddIELen = pWextState->assocAddIE.length;
15624 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
15625 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015626
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015627 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070015628 {
15629 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15630 "Need bigger buffer space");
15631 VOS_ASSERT(0);
15632 return -ENOMEM;
15633 }
15634 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15635 pWextState->assocAddIE.length += eLen + 2;
15636
15637 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
15638 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15639 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15640 }
15641
Abhishek Singh4322e622015-06-10 15:42:54 +053015642 /* Update only for WPA IE */
15643 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
15644 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070015645
15646 /* populating as ADDIE in beacon frames */
15647 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015648 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070015649 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
15650 {
15651 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
15652 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
15653 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
15654 {
15655 hddLog(LOGE,
15656 "Coldn't pass "
15657 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
15658 }
15659 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
15660 else
15661 hddLog(LOGE,
15662 "Could not pass on "
15663 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
15664
15665 /* IBSS mode doesn't contain params->proberesp_ies still
15666 beaconIE's need to be populated in probe response frames */
15667 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
15668 {
15669 u16 rem_probe_resp_ie_len = eLen + 2;
15670 u8 probe_rsp_ie_len[3] = {0};
15671 u8 counter = 0;
15672
15673 /* Check Probe Resp Length if it is greater then 255 then
15674 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
15675 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
15676 not able Store More then 255 bytes into One Variable */
15677
15678 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
15679 {
15680 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
15681 {
15682 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
15683 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
15684 }
15685 else
15686 {
15687 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
15688 rem_probe_resp_ie_len = 0;
15689 }
15690 }
15691
15692 rem_probe_resp_ie_len = 0;
15693
15694 if (probe_rsp_ie_len[0] > 0)
15695 {
15696 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
15697 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
15698 (tANI_U8*)(genie - 2),
15699 probe_rsp_ie_len[0], NULL,
15700 eANI_BOOLEAN_FALSE)
15701 == eHAL_STATUS_FAILURE)
15702 {
15703 hddLog(LOGE,
15704 "Could not pass"
15705 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
15706 }
15707 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
15708 }
15709
15710 if (probe_rsp_ie_len[1] > 0)
15711 {
15712 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
15713 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
15714 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
15715 probe_rsp_ie_len[1], NULL,
15716 eANI_BOOLEAN_FALSE)
15717 == eHAL_STATUS_FAILURE)
15718 {
15719 hddLog(LOGE,
15720 "Could not pass"
15721 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
15722 }
15723 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
15724 }
15725
15726 if (probe_rsp_ie_len[2] > 0)
15727 {
15728 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
15729 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
15730 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
15731 probe_rsp_ie_len[2], NULL,
15732 eANI_BOOLEAN_FALSE)
15733 == eHAL_STATUS_FAILURE)
15734 {
15735 hddLog(LOGE,
15736 "Could not pass"
15737 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
15738 }
15739 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
15740 }
15741
15742 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
15743 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
15744 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
15745 {
15746 hddLog(LOGE,
15747 "Could not pass"
15748 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
15749 }
15750 }
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070015751 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070015752 break;
15753 case DOT11F_EID_RSN:
15754 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
15755 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
15756 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
15757 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
15758 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
15759 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053015760
Abhishek Singhb16f3562016-01-20 11:08:32 +053015761 /* Appending extended capabilities with Interworking or
15762 * bsstransition bit set in Assoc Req.
Abhishek Singh15d95602015-03-24 15:52:57 +053015763 *
15764 * In assoc req this EXT Cap will only be taken into account if
Abhishek Singhb16f3562016-01-20 11:08:32 +053015765 * interworkingService or bsstransition bit is set to 1.
15766 * Driver is only interested in interworkingService and
15767 * bsstransition capability from supplicant.
15768 * If in future any other EXT Cap info is
Abhishek Singh15d95602015-03-24 15:52:57 +053015769 * required from supplicat, it needs to be handled while
15770 * sending Assoc Req in LIM.
15771 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015772 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015773 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015774 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015775 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015776 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015777
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015778 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015779 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015780 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15781 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015782 VOS_ASSERT(0);
15783 return -ENOMEM;
15784 }
15785 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15786 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015787
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015788 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15789 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15790 break;
15791 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015792#ifdef FEATURE_WLAN_WAPI
15793 case WLAN_EID_WAPI:
15794 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070015795 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070015796 pAdapter->wapi_info.nWapiMode);
15797 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015798 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070015799 akmsuiteCount = WPA_GET_LE16(tmp);
15800 tmp = tmp + 1;
15801 akmlist = (int *)(tmp);
15802 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
15803 {
15804 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
15805 }
15806 else
15807 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015808 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070015809 VOS_ASSERT(0);
15810 return -EINVAL;
15811 }
15812
15813 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
15814 {
15815 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015816 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015817 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015818 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015819 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015820 {
Jeff Johnson295189b2012-06-20 16:38:30 -070015821 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015822 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015823 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
15824 }
15825 break;
15826#endif
15827 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015828 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015829 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015830 /* when Unknown IE is received we should break and continue
15831 * to the next IE in the buffer instead we were returning
15832 * so changing this to break */
15833 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070015834 }
15835 genie += eLen;
15836 remLen -= eLen;
15837 }
15838 EXIT();
15839 return 0;
15840}
15841
15842/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053015843 * FUNCTION: hdd_isWPAIEPresent
15844 * Parse the received IE to find the WPA IE
15845 *
15846 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015847static bool hdd_isWPAIEPresent(
15848#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
15849 const u8 *ie,
15850#else
15851 u8 *ie,
15852#endif
15853 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053015854{
15855 v_U8_t eLen = 0;
15856 v_U16_t remLen = ie_len;
15857 v_U8_t elementId = 0;
15858
15859 while (remLen >= 2)
15860 {
15861 elementId = *ie++;
15862 eLen = *ie++;
15863 remLen -= 2;
15864 if (eLen > remLen)
15865 {
15866 hddLog(VOS_TRACE_LEVEL_ERROR,
15867 "%s: IE length is wrong %d", __func__, eLen);
15868 return FALSE;
15869 }
15870 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
15871 {
15872 /* OUI - 0x00 0X50 0XF2
15873 WPA Information Element - 0x01
15874 WPA version - 0x01*/
15875 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
15876 return TRUE;
15877 }
15878 ie += eLen;
15879 remLen -= eLen;
15880 }
15881 return FALSE;
15882}
15883
15884/*
Jeff Johnson295189b2012-06-20 16:38:30 -070015885 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015886 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070015887 * parameters during connect operation.
15888 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015889int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070015890 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015891 )
Jeff Johnson295189b2012-06-20 16:38:30 -070015892{
15893 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015894 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070015895 ENTER();
15896
15897 /*set wpa version*/
15898 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
15899
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015900 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070015901 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053015902 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070015903 {
15904 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
15905 }
15906 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
15907 {
15908 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
15909 }
15910 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015911
15912 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015913 pWextState->wpaVersion);
15914
15915 /*set authentication type*/
15916 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
15917
15918 if (0 > status)
15919 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015920 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015921 "%s: failed to set authentication type ", __func__);
15922 return status;
15923 }
15924
15925 /*set key mgmt type*/
15926 if (req->crypto.n_akm_suites)
15927 {
15928 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
15929 if (0 > status)
15930 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015931 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070015932 __func__);
15933 return status;
15934 }
15935 }
15936
15937 /*set pairwise cipher type*/
15938 if (req->crypto.n_ciphers_pairwise)
15939 {
15940 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
15941 req->crypto.ciphers_pairwise[0], true);
15942 if (0 > status)
15943 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015944 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015945 "%s: failed to set unicast cipher type", __func__);
15946 return status;
15947 }
15948 }
15949 else
15950 {
15951 /*Reset previous cipher suite to none*/
15952 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
15953 if (0 > status)
15954 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015955 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015956 "%s: failed to set unicast cipher type", __func__);
15957 return status;
15958 }
15959 }
15960
15961 /*set group cipher type*/
15962 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
15963 false);
15964
15965 if (0 > status)
15966 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015967 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070015968 __func__);
15969 return status;
15970 }
15971
Chet Lanctot186b5732013-03-18 10:26:30 -070015972#ifdef WLAN_FEATURE_11W
15973 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
15974#endif
15975
Jeff Johnson295189b2012-06-20 16:38:30 -070015976 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
15977 if (req->ie_len)
15978 {
15979 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
15980 if ( 0 > status)
15981 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015982 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070015983 __func__);
15984 return status;
15985 }
15986 }
15987
15988 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015989 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070015990 {
15991 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
15992 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
15993 )
15994 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015995 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070015996 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
15997 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015998 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070015999 __func__);
16000 return -EOPNOTSUPP;
16001 }
16002 else
16003 {
16004 u8 key_len = req->key_len;
16005 u8 key_idx = req->key_idx;
16006
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016007 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070016008 && (CSR_MAX_NUM_KEY > key_idx)
16009 )
16010 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016011 hddLog(VOS_TRACE_LEVEL_INFO,
16012 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016013 __func__, key_idx, key_len);
16014 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016015 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070016016 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016017 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070016018 (u8)key_len;
16019 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
16020 }
16021 }
16022 }
16023 }
16024
16025 return status;
16026}
16027
16028/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016029 * FUNCTION: wlan_hdd_try_disconnect
16030 * This function is used to disconnect from previous
16031 * connection
16032 */
Agrawal Ashishc407f192017-01-23 17:18:35 +053016033int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016034{
16035 long ret = 0;
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016036 int status, result = 0;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016037 hdd_station_ctx_t *pHddStaCtx;
16038 eMib_dot11DesiredBssType connectedBssType;
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016039 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016040
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016041 ret = wlan_hdd_validate_context(pHddCtx);
16042 if (0 != ret)
16043 {
16044 return ret;
16045 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016046 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16047
16048 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
16049
16050 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
16051 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
Abhishek Singh630ff592016-01-07 18:15:53 +053016052 (eConnectionState_Connecting == pHddStaCtx->conn_info.connState) ||
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016053 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
16054 {
Abhishek Singh9f4df782017-03-15 17:29:10 +053016055 /* Indicate disconnect to SME so that in-progress connection or preauth
16056 * can be aborted
16057 */
16058 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
16059 pAdapter->sessionId);
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016060 spin_lock_bh(&pAdapter->lock_for_active_session);
16061 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
16062 {
16063 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
16064 }
16065 spin_unlock_bh(&pAdapter->lock_for_active_session);
Abhishek Singhf7962582015-10-23 10:54:06 +053016066 hdd_connSetConnectionState(pHddStaCtx,
16067 eConnectionState_Disconnecting);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016068 /* Issue disconnect to CSR */
16069 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016070 status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016071 pAdapter->sessionId,
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016072 eCSR_DISCONNECT_REASON_UNSPECIFIED);
16073 if(eHAL_STATUS_CMD_NOT_QUEUED == status) {
16074 hddLog(LOG1,
16075 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
16076 } else if ( 0 != status ) {
16077 hddLog(LOGE,
16078 FL("csrRoamDisconnect failure, returned %d"),
16079 (int)status );
16080 result = -EINVAL;
16081 goto disconnected;
16082 }
16083 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016084 &pAdapter->disconnect_comp_var,
16085 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016086 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status)) {
16087 hddLog(LOGE,
16088 "%s: Failed to disconnect, timed out", __func__);
16089 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016090 }
16091 }
16092 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
16093 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016094 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016095 &pAdapter->disconnect_comp_var,
16096 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016097 if (!ret)
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016098 {
16099 hddLog(LOGE, FL("Failed to receive disconnect event"));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016100 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016101 }
16102 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016103disconnected:
16104 hddLog(LOG1,
16105 FL("Set HDD connState to eConnectionState_NotConnected"));
16106 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
16107 return result;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016108}
16109
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053016110/**
16111 * wlan_hdd_reassoc_bssid_hint() - Start reassociation if bssid is present
16112 * @adapter: Pointer to the HDD adapter
16113 * @req: Pointer to the structure cfg_connect_params receieved from user space
16114 *
16115 * This function will start reassociation if bssid hint, channel hint and
16116 * previous bssid parameters are present in the connect request
16117 *
16118 * Return: success if reassociation is happening
16119 * Error code if reassociation is not permitted or not happening
16120 */
16121#ifdef CFG80211_CONNECT_PREV_BSSID
16122static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
16123 struct cfg80211_connect_params *req)
16124{
16125 int status = -EPERM;
16126 if (req->bssid_hint && req->channel_hint && req->prev_bssid) {
16127 hddLog(VOS_TRACE_LEVEL_INFO,
16128 FL("REASSOC Attempt on channel %d to "MAC_ADDRESS_STR),
16129 req->channel_hint->hw_value,
16130 MAC_ADDR_ARRAY(req->bssid_hint));
16131 status = hdd_reassoc(adapter, req->bssid_hint,
16132 req->channel_hint->hw_value,
16133 CONNECT_CMD_USERSPACE);
16134 }
16135 return status;
16136}
16137#else
16138static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
16139 struct cfg80211_connect_params *req)
16140{
16141 return -EPERM;
16142}
16143#endif
16144
Abhishek Singhe3beee22017-07-31 15:35:40 +053016145/**
16146 * wlan_hdd_check_ht20_ht40_ind() - check if Supplicant has indicated to
16147 * connect in HT20 mode
16148 * @hdd_ctx: hdd context
16149 * @adapter: Pointer to the HDD adapter
16150 * @req: Pointer to the structure cfg_connect_params receieved from user space
16151 *
16152 * This function will check if supplicant has indicated to to connect in HT20
16153 * mode. this is currently applicable only for 2.4Ghz mode only.
16154 * if feature is enabled and supplicant indicate HT20 set
16155 * force_24ghz_in_ht20 to true to force 2.4Ghz in HT20 else set it to false.
16156 *
16157 * Return: void
16158 */
16159#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
16160static void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
16161 hdd_adapter_t *adapter,
16162 struct cfg80211_connect_params *req)
16163{
16164 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
16165 tCsrRoamProfile *roam_profile;
16166
16167 roam_profile = &wext_state->roamProfile;
16168 roam_profile->force_24ghz_in_ht20 = false;
16169 if (hdd_ctx->cfg_ini->override_ht20_40_24g &&
16170 !(req->ht_capa.cap_info &
16171 IEEE80211_HT_CAP_SUP_WIDTH_20_40))
16172 roam_profile->force_24ghz_in_ht20 = true;
16173
16174 hddLog(LOG1, FL("req->ht_capa.cap_info %x override_ht20_40_24g %d"),
16175 req->ht_capa.cap_info, hdd_ctx->cfg_ini->override_ht20_40_24g);
16176}
16177#else
16178static inline void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
16179 hdd_adapter_t *adapter,
16180 struct cfg80211_connect_params *req)
16181{
16182 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
16183 tCsrRoamProfile *roam_profile;
16184
16185 roam_profile = &wext_state->roamProfile;
16186 roam_profile->force_24ghz_in_ht20 = false;
16187}
16188#endif
16189
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016190/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053016191 * FUNCTION: __wlan_hdd_cfg80211_connect
16192 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070016193 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016194static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016195 struct net_device *ndev,
16196 struct cfg80211_connect_params *req
16197 )
16198{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016199 int status;
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016200 u16 channel;
Edhar, Mahesh Kumar496c7f72016-03-18 12:47:44 +053016201#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) || \
16202 defined(CFG80211_BSSID_HINT_BACKPORT)
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016203 const u8 *bssid_hint = req->bssid_hint;
16204#else
16205 const u8 *bssid_hint = NULL;
16206#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016207 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070016208 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053016209 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070016210
16211 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016212
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016213 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16214 TRACE_CODE_HDD_CFG80211_CONNECT,
16215 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016216 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016217 "%s: device_mode = %s (%d)", __func__,
16218 hdd_device_modetoString(pAdapter->device_mode),
16219 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070016220
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016221 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080016222 if (!pHddCtx)
16223 {
16224 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16225 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053016226 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080016227 }
16228
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016229 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016230 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070016231 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016232 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016233 }
16234
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053016235 if (wlan_hdd_check_and_stop_mon(pAdapter, true))
16236 return -EINVAL;
16237
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053016238 status = wlan_hdd_reassoc_bssid_hint(pAdapter, req);
16239 if (0 == status)
16240 return status;
16241
Agarwal Ashish51325b52014-06-16 16:50:49 +053016242
Jeff Johnson295189b2012-06-20 16:38:30 -070016243#ifdef WLAN_BTAMP_FEATURE
16244 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016245 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070016246 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016247 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016248 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080016249 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070016250 }
16251#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016252
16253 //If Device Mode is Station Concurrent Sessions Exit BMps
16254 //P2P Mode will be taken care in Open/close adapter
16255 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053016256 (vos_concurrent_open_sessions_running())) {
16257 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
16258 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016259 }
16260
16261 /*Try disconnecting if already in connected state*/
16262 status = wlan_hdd_try_disconnect(pAdapter);
16263 if ( 0 > status)
16264 {
16265 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
16266 " connection"));
16267 return -EALREADY;
16268 }
Agrawal Ashish559530c2015-12-01 18:04:20 +053016269 /* Check for max concurrent connections after doing disconnect if any*/
16270 if (vos_max_concurrent_connections_reached()) {
16271 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
16272 return -ECONNREFUSED;
16273 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016274
Jeff Johnson295189b2012-06-20 16:38:30 -070016275 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016276 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070016277
16278 if ( 0 > status)
16279 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016280 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070016281 __func__);
16282 return status;
16283 }
Sravan Kumar Kairam589c5722016-01-27 20:28:53 +053016284
16285 if (pHddCtx->spoofMacAddr.isEnabled)
16286 {
16287 hddLog(VOS_TRACE_LEVEL_INFO,
16288 "%s: MAC Spoofing enabled ", __func__);
16289 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
16290 * to fill TxBds for probe request during SSID scan which may happen
16291 * as part of connect command
16292 */
16293 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
16294 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
16295 if (status != VOS_STATUS_SUCCESS)
16296 return -ECONNREFUSED;
16297 }
16298
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016299 if (req->channel)
16300 channel = req->channel->hw_value;
Mohit Khanna765234a2012-09-11 15:08:35 -070016301 else
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016302 channel = 0;
Kapil Gupta312028a2016-10-25 14:15:20 +053016303
16304 /* Abort if any scan is going on */
16305 status = wlan_hdd_scan_abort(pAdapter);
16306 if (0 != status)
16307 hddLog(VOS_TRACE_LEVEL_ERROR, FL("scan abort failed"));
16308
Abhishek Singhe3beee22017-07-31 15:35:40 +053016309 wlan_hdd_check_ht20_ht40_ind(pHddCtx, pAdapter, req);
16310
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016311 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
16312 req->ssid_len, req->bssid,
16313 bssid_hint, channel);
Jeff Johnson295189b2012-06-20 16:38:30 -070016314
Sushant Kaushikd7083982015-03-18 14:33:24 +053016315 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070016316 {
16317 //ReEnable BMPS if disabled
16318 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
16319 (NULL != pHddCtx))
16320 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053016321 if (pHddCtx->hdd_wlan_suspended)
16322 {
16323 hdd_set_pwrparams(pHddCtx);
16324 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016325 //ReEnable Bmps and Imps back
16326 hdd_enable_bmps_imps(pHddCtx);
16327 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053016328 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070016329 return status;
16330 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016331 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070016332 EXIT();
16333 return status;
16334}
16335
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016336static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
16337 struct net_device *ndev,
16338 struct cfg80211_connect_params *req)
16339{
16340 int ret;
16341 vos_ssr_protect(__func__);
16342 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
16343 vos_ssr_unprotect(__func__);
16344
16345 return ret;
16346}
Jeff Johnson295189b2012-06-20 16:38:30 -070016347
16348/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016349 * FUNCTION: wlan_hdd_disconnect
16350 * This function is used to issue a disconnect request to SME
16351 */
16352int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
16353{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053016354 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016355 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016356 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053016357 long ret;
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053016358 eConnectionState prev_conn_state;
Yeshwanth Sriram Guntukaae784d22017-12-06 14:20:51 +053016359 uint32_t wait_time = WLAN_WAIT_TIME_DISCONNECT;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016360
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016361 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016362
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016363 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016364 if (0 != status)
16365 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016366 return status;
16367 }
Abhishek Singh07e4a892015-11-23 11:29:57 +053016368 /* Indicate sme of disconnect so that in progress connection or preauth
16369 * can be aborted
16370 */
16371 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
Sushant Kaushikb4834d22015-07-15 15:29:05 +053016372 pAdapter->sessionId);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016373 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053016374
Agarwal Ashish47d18112014-08-04 19:55:07 +053016375 /* Need to apply spin lock before decreasing active sessions
16376 * as there can be chance for double decrement if context switch
16377 * Calls hdd_DisConnectHandler.
16378 */
16379
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053016380 prev_conn_state = pHddStaCtx->conn_info.connState;
16381
Agarwal Ashish47d18112014-08-04 19:55:07 +053016382 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053016383 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
16384 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053016385 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
16386 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053016387 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
16388 spin_unlock_bh(&pAdapter->lock_for_active_session);
Abhishek Singh78c691f2017-11-30 13:48:44 +053016389 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053016390
Abhishek Singhf4669da2014-05-26 15:07:49 +053016391 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053016392 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
16393
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016394 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016395
Mihir Shete182a0b22014-08-18 16:08:48 +053016396 /*
16397 * stop tx queues before deleting STA/BSS context from the firmware.
16398 * tx has to be disabled because the firmware can get busy dropping
16399 * the tx frames after BSS/STA has been deleted and will not send
16400 * back a response resulting in WDI timeout
16401 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053016402 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053016403 netif_tx_disable(pAdapter->dev);
16404 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053016405
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053016406 wlan_hdd_check_and_stop_mon(pAdapter, true);
16407
Mihir Shete182a0b22014-08-18 16:08:48 +053016408 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016409 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
16410 pAdapter->sessionId, reason);
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053016411 if((eHAL_STATUS_CMD_NOT_QUEUED == status) &&
16412 prev_conn_state != eConnectionState_Connecting)
16413 {
16414 hddLog(LOG1,
16415 FL("status = %d, already disconnected"), status);
16416 result = 0;
Yeshwanth Sriram Guntukaae784d22017-12-06 14:20:51 +053016417 /*
16418 * Wait here instead of returning directly. This will block the
16419 * next connect command and allow processing of the disconnect
16420 * in SME else we might hit some race conditions leading to SME
16421 * and HDD out of sync. As disconnect is already in progress,
16422 * wait here for 1 sec instead of 5 sec.
16423 */
16424 wait_time = WLAN_WAIT_DISCONNECT_ALREADY_IN_PROGRESS;
16425 goto wait_for_disconnect;
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053016426 }
16427 /*
16428 * Wait here instead of returning directly, this will block the next
16429 * connect command and allow processing of the scan for ssid and
16430 * the previous connect command in CSR. Else we might hit some
16431 * race conditions leading to SME and HDD out of sync.
16432 */
16433 else if(eHAL_STATUS_CMD_NOT_QUEUED == status)
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016434 {
16435 hddLog(LOG1,
16436 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053016437 }
16438 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016439 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016440 hddLog(LOGE,
16441 FL("csrRoamDisconnect failure, returned %d"),
16442 (int)status);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053016443 result = -EINVAL;
16444 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016445 }
Yeshwanth Sriram Guntukaae784d22017-12-06 14:20:51 +053016446wait_for_disconnect:
16447 ret = wait_for_completion_timeout(&pAdapter->disconnect_comp_var,
16448 msecs_to_jiffies(wait_time));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016449 if (!ret && (eHAL_STATUS_CMD_NOT_QUEUED != status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016450 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016451 hddLog(LOGE,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053016452 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053016453 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053016454 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053016455disconnected:
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016456 hddLog(LOG1,
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053016457 FL("Set HDD connState to eConnectionState_NotConnected"));
16458 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Mahesh A Saptasagar936ffc32016-05-25 11:27:43 +053016459#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
16460 /* Sending disconnect event to userspace for kernel version < 3.11
16461 * is handled by __cfg80211_disconnect call to __cfg80211_disconnected
16462 */
16463 hddLog(LOG1, FL("Send disconnected event to userspace"));
16464
Mahesh A Saptasagarf5859b12016-06-01 17:17:50 +053016465 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, true,
Mahesh A Saptasagar936ffc32016-05-25 11:27:43 +053016466 WLAN_REASON_UNSPECIFIED);
16467#endif
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053016468
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016469 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053016470 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016471}
16472
16473
16474/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016475 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070016476 * This function is used to issue a disconnect request to SME
16477 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016478static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016479 struct net_device *dev,
16480 u16 reason
16481 )
16482{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016483 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016484 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053016485 tCsrRoamProfile *pRoamProfile;
16486 hdd_station_ctx_t *pHddStaCtx;
16487 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053016488#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016489 tANI_U8 staIdx;
16490#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016491
Jeff Johnson295189b2012-06-20 16:38:30 -070016492 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016493
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053016494 if (!pAdapter) {
16495 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
16496 return -EINVAL;
16497 }
16498
16499 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16500 if (!pHddStaCtx) {
16501 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
16502 return -EINVAL;
16503 }
16504
16505 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16506 status = wlan_hdd_validate_context(pHddCtx);
16507 if (0 != status)
16508 {
16509 return status;
16510 }
16511
16512 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
16513
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016514 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16515 TRACE_CODE_HDD_CFG80211_DISCONNECT,
16516 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016517 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
16518 __func__, hdd_device_modetoString(pAdapter->device_mode),
16519 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070016520
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016521 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
16522 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070016523
Jeff Johnson295189b2012-06-20 16:38:30 -070016524 if (NULL != pRoamProfile)
16525 {
16526 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053016527 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
16528 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070016529 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016530 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070016531 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053016532 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070016533 switch(reason)
16534 {
16535 case WLAN_REASON_MIC_FAILURE:
16536 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
16537 break;
16538
16539 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
16540 case WLAN_REASON_DISASSOC_AP_BUSY:
16541 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
16542 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
16543 break;
16544
16545 case WLAN_REASON_PREV_AUTH_NOT_VALID:
16546 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053016547 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070016548 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
16549 break;
16550
Jeff Johnson295189b2012-06-20 16:38:30 -070016551 default:
16552 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
16553 break;
16554 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053016555 pScanInfo = &pHddCtx->scan_info;
16556 if (pScanInfo->mScanPending)
16557 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053016558 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053016559 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053016560 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053016561 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053016562 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053016563 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016564#ifdef FEATURE_WLAN_TDLS
16565 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080016566 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016567 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080016568 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
16569 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016570 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016571 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080016572 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053016573 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016574 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080016575 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016576 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016577 status = sme_DeleteTdlsPeerSta(
16578 WLAN_HDD_GET_HAL_CTX(pAdapter),
16579 pAdapter->sessionId,
16580 mac);
16581 if (status != eHAL_STATUS_SUCCESS) {
16582 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
16583 return -EPERM;
16584 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016585 }
16586 }
16587#endif
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053016588
16589 hddLog(LOG1, FL("Disconnecting with reasoncode:%u connState %d"),
16590 reasonCode,
16591 pHddStaCtx->conn_info.connState);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016592 status = wlan_hdd_disconnect(pAdapter, reasonCode);
16593 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070016594 {
16595 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080016596 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016597 __func__, (int)status );
16598 return -EINVAL;
16599 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016600 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053016601 else
16602 {
16603 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
16604 "called while in %d state", __func__,
16605 pHddStaCtx->conn_info.connState);
16606 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016607 }
16608 else
16609 {
16610 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
16611 }
16612
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016613 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016614 return status;
16615}
16616
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016617static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
16618 struct net_device *dev,
16619 u16 reason
16620 )
16621{
16622 int ret;
16623 vos_ssr_protect(__func__);
16624 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
16625 vos_ssr_unprotect(__func__);
16626
16627 return ret;
16628}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016629
Jeff Johnson295189b2012-06-20 16:38:30 -070016630/*
16631 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016632 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070016633 * settings in IBSS mode.
16634 */
16635static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016636 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070016637 struct cfg80211_ibss_params *params
16638 )
16639{
16640 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016641 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016642 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
16643 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016644
Jeff Johnson295189b2012-06-20 16:38:30 -070016645 ENTER();
16646
16647 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070016648 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070016649
16650 if (params->ie_len && ( NULL != params->ie) )
16651 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016652 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
16653 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070016654 {
16655 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
16656 encryptionType = eCSR_ENCRYPT_TYPE_AES;
16657 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016658 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070016659 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070016660 tDot11fIEWPA dot11WPAIE;
16661 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016662 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070016663
Wilson Yang00256342013-10-10 23:13:38 -070016664 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016665 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
16666 params->ie_len, DOT11F_EID_WPA);
16667 if ( NULL != ie )
16668 {
16669 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
16670 // Unpack the WPA IE
16671 //Skip past the EID byte and length byte - and four byte WiFi OUI
16672 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
16673 &ie[2+4],
16674 ie[1] - 4,
16675 &dot11WPAIE);
16676 /*Extract the multicast cipher, the encType for unicast
16677 cipher for wpa-none is none*/
16678 encryptionType =
16679 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
16680 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016681 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016682
Jeff Johnson295189b2012-06-20 16:38:30 -070016683 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
16684
16685 if (0 > status)
16686 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016687 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070016688 __func__);
16689 return status;
16690 }
16691 }
16692
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016693 pWextState->roamProfile.AuthType.authType[0] =
16694 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070016695 eCSR_AUTH_TYPE_OPEN_SYSTEM;
16696
16697 if (params->privacy)
16698 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016699 /* Security enabled IBSS, At this time there is no information available
16700 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070016701 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016702 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070016703 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016704 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070016705 *enable privacy bit in beacons */
16706
16707 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
16708 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070016709 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
16710 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070016711 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
16712 pWextState->roamProfile.EncryptionType.numEntries = 1;
16713 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070016714 return status;
16715}
16716
16717/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016718 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016719 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070016720 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016721static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016722 struct net_device *dev,
16723 struct cfg80211_ibss_params *params
16724 )
16725{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016726 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070016727 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
16728 tCsrRoamProfile *pRoamProfile;
16729 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016730 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16731 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016732 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070016733
16734 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016735
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016736 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16737 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
16738 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016739 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016740 "%s: device_mode = %s (%d)", __func__,
16741 hdd_device_modetoString(pAdapter->device_mode),
16742 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070016743
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016744 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016745 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070016746 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016747 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016748 }
16749
16750 if (NULL == pWextState)
16751 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016752 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070016753 __func__);
16754 return -EIO;
16755 }
16756
Agarwal Ashish51325b52014-06-16 16:50:49 +053016757 if (vos_max_concurrent_connections_reached()) {
16758 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
16759 return -ECONNREFUSED;
16760 }
16761
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016762 /*Try disconnecting if already in connected state*/
16763 status = wlan_hdd_try_disconnect(pAdapter);
16764 if ( 0 > status)
16765 {
16766 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
16767 " IBSS connection"));
16768 return -EALREADY;
16769 }
16770
Jeff Johnson295189b2012-06-20 16:38:30 -070016771 pRoamProfile = &pWextState->roamProfile;
16772
16773 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
16774 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016775 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080016776 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016777 return -EINVAL;
16778 }
16779
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070016780 /* BSSID is provided by upper layers hence no need to AUTO generate */
16781 if (NULL != params->bssid) {
16782 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
16783 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
16784 hddLog (VOS_TRACE_LEVEL_ERROR,
16785 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
16786 return -EIO;
16787 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016788 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070016789 }
krunal sonie9002db2013-11-25 14:24:17 -080016790 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
16791 {
16792 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
16793 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
16794 {
16795 hddLog (VOS_TRACE_LEVEL_ERROR,
16796 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
16797 return -EIO;
16798 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016799
16800 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080016801 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016802 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080016803 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070016804
Jeff Johnson295189b2012-06-20 16:38:30 -070016805 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070016806 if (NULL !=
16807#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
16808 params->chandef.chan)
16809#else
16810 params->channel)
16811#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016812 {
16813 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016814 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
16815 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
16816 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
16817 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070016818
16819 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016820 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070016821 ieee80211_frequency_to_channel(
16822#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
16823 params->chandef.chan->center_freq);
16824#else
16825 params->channel->center_freq);
16826#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016827
16828 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
16829 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070016830 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016831 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
16832 __func__);
16833 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070016834 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016835
16836 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070016837 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016838 if (channelNum == validChan[indx])
16839 {
16840 break;
16841 }
16842 }
16843 if (indx >= numChans)
16844 {
16845 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016846 __func__, channelNum);
16847 return -EINVAL;
16848 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016849 /* Set the Operational Channel */
16850 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
16851 channelNum);
16852 pRoamProfile->ChannelInfo.numOfChannels = 1;
16853 pHddStaCtx->conn_info.operationChannel = channelNum;
16854 pRoamProfile->ChannelInfo.ChannelList =
16855 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070016856 }
16857
16858 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016859 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070016860 if (status < 0)
16861 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016862 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070016863 __func__);
16864 return status;
16865 }
16866
16867 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016868 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Abhishek Singh4d924682015-11-17 15:23:06 +053016869 params->ssid_len, (const u8 *)&bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016870 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070016871
16872 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070016873 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016874
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016875 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016876 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016877}
16878
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016879static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
16880 struct net_device *dev,
16881 struct cfg80211_ibss_params *params
16882 )
16883{
16884 int ret = 0;
16885
16886 vos_ssr_protect(__func__);
16887 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
16888 vos_ssr_unprotect(__func__);
16889
16890 return ret;
16891}
16892
Jeff Johnson295189b2012-06-20 16:38:30 -070016893/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016894 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016895 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070016896 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016897static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016898 struct net_device *dev
16899 )
16900{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016901 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016902 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
16903 tCsrRoamProfile *pRoamProfile;
16904 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016905 int status;
Abhishek Singh69de3302016-11-11 16:44:32 +053016906 eHalStatus hal_status;
Abhishek Singh7cd040e2016-01-07 10:51:04 +053016907#ifdef WLAN_FEATURE_RMC
16908 tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN] = {0};
16909#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016910
16911 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016912
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016913 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16914 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
16915 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016916 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016917 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016918 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016919 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016920 }
16921
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016922 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
16923 hdd_device_modetoString(pAdapter->device_mode),
16924 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070016925 if (NULL == pWextState)
16926 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016927 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070016928 __func__);
16929 return -EIO;
16930 }
16931
16932 pRoamProfile = &pWextState->roamProfile;
16933
16934 /* Issue disconnect only if interface type is set to IBSS */
16935 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
16936 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016937 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070016938 __func__);
16939 return -EINVAL;
16940 }
16941
Abhishek Singh7cd040e2016-01-07 10:51:04 +053016942#ifdef WLAN_FEATURE_RMC
16943 /* Clearing add IE of beacon */
16944 if (ccmCfgSetStr(pHddCtx->hHal,
16945 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0],
16946 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN,
16947 NULL, eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
16948 {
16949 hddLog (VOS_TRACE_LEVEL_ERROR,
16950 "%s: unable to clear PROBE_RSP_BCN_ADDNIE_DATA", __func__);
16951 return -EINVAL;
16952 }
16953 if (ccmCfgSetInt(pHddCtx->hHal,
16954 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0, NULL,
16955 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
16956 {
16957 hddLog (VOS_TRACE_LEVEL_ERROR,
16958 "%s: unable to clear WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
16959 __func__);
16960 return -EINVAL;
16961 }
16962
16963 // Reset WNI_CFG_PROBE_RSP Flags
16964 wlan_hdd_reset_prob_rspies(pAdapter);
16965
16966 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
16967 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 0,NULL,
16968 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
16969 {
16970 hddLog (VOS_TRACE_LEVEL_ERROR,
16971 "%s: unable to clear WNI_CFG_PROBE_RSP_ADDNIE_FLAG",
16972 __func__);
16973 return -EINVAL;
16974 }
16975#endif
16976
Jeff Johnson295189b2012-06-20 16:38:30 -070016977 /* Issue Disconnect request */
16978 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singh69de3302016-11-11 16:44:32 +053016979 hal_status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
16980 pAdapter->sessionId,
16981 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
16982 if (!HAL_STATUS_SUCCESS(hal_status)) {
16983 hddLog(LOGE,
16984 FL("sme_RoamDisconnect failed hal_status(%d)"),
16985 hal_status);
16986 return -EAGAIN;
16987 }
16988 status = wait_for_completion_timeout(
16989 &pAdapter->disconnect_comp_var,
16990 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
16991 if (!status) {
16992 hddLog(LOGE,
16993 FL("wait on disconnect_comp_var failed"));
16994 return -ETIMEDOUT;
16995 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016996
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016997 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016998 return 0;
16999}
17000
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017001static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
17002 struct net_device *dev
17003 )
17004{
17005 int ret = 0;
17006
17007 vos_ssr_protect(__func__);
17008 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
17009 vos_ssr_unprotect(__func__);
17010
17011 return ret;
17012}
17013
Jeff Johnson295189b2012-06-20 16:38:30 -070017014/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017015 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070017016 * This function is used to set the phy parameters
17017 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
17018 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017019static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017020 u32 changed)
17021{
17022 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
17023 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017024 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017025
17026 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017027
17028 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017029 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
17030 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017031
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017032 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017033 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017034 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017035 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017036 }
17037
Jeff Johnson295189b2012-06-20 16:38:30 -070017038 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
17039 {
17040 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
17041 WNI_CFG_RTS_THRESHOLD_STAMAX :
17042 wiphy->rts_threshold;
17043
17044 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017045 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070017046 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017047 hddLog(VOS_TRACE_LEVEL_ERROR,
17048 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017049 __func__, rts_threshold);
17050 return -EINVAL;
17051 }
17052
17053 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
17054 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017055 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017056 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017057 hddLog(VOS_TRACE_LEVEL_ERROR,
17058 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017059 __func__, rts_threshold);
17060 return -EIO;
17061 }
17062
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017063 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070017064 rts_threshold);
17065 }
17066
17067 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
17068 {
17069 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
17070 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
17071 wiphy->frag_threshold;
17072
17073 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017074 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070017075 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017076 hddLog(VOS_TRACE_LEVEL_ERROR,
17077 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070017078 frag_threshold);
17079 return -EINVAL;
17080 }
17081
17082 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
17083 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017084 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017085 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017086 hddLog(VOS_TRACE_LEVEL_ERROR,
17087 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017088 __func__, frag_threshold);
17089 return -EIO;
17090 }
17091
17092 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
17093 frag_threshold);
17094 }
17095
17096 if ((changed & WIPHY_PARAM_RETRY_SHORT)
17097 || (changed & WIPHY_PARAM_RETRY_LONG))
17098 {
17099 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
17100 wiphy->retry_short :
17101 wiphy->retry_long;
17102
17103 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
17104 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
17105 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017106 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017107 __func__, retry_value);
17108 return -EINVAL;
17109 }
17110
17111 if (changed & WIPHY_PARAM_RETRY_SHORT)
17112 {
17113 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
17114 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017115 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017116 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017117 hddLog(VOS_TRACE_LEVEL_ERROR,
17118 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017119 __func__, retry_value);
17120 return -EIO;
17121 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017122 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017123 __func__, retry_value);
17124 }
17125 else if (changed & WIPHY_PARAM_RETRY_SHORT)
17126 {
17127 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
17128 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017129 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017130 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017131 hddLog(VOS_TRACE_LEVEL_ERROR,
17132 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017133 __func__, retry_value);
17134 return -EIO;
17135 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017136 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017137 __func__, retry_value);
17138 }
17139 }
17140
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017141 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017142 return 0;
17143}
17144
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017145static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
17146 u32 changed)
17147{
17148 int ret;
17149
17150 vos_ssr_protect(__func__);
17151 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
17152 vos_ssr_unprotect(__func__);
17153
17154 return ret;
17155}
17156
Jeff Johnson295189b2012-06-20 16:38:30 -070017157/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017158 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070017159 * This function is used to set the txpower
17160 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017161static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070017162#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17163 struct wireless_dev *wdev,
17164#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017165#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017166 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070017167#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017168 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070017169#endif
17170 int dbm)
17171{
17172 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017173 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070017174 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
17175 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017176 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017177
17178 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017179
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017180 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17181 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
17182 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017183 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017184 if (0 != status)
17185 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017186 return status;
17187 }
17188
17189 hHal = pHddCtx->hHal;
17190
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017191 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
17192 dbm, ccmCfgSetCallback,
17193 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017194 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017195 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070017196 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
17197 return -EIO;
17198 }
17199
17200 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
17201 dbm);
17202
17203 switch(type)
17204 {
17205 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
17206 /* Fall through */
17207 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
17208 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
17209 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017210 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
17211 __func__);
17212 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070017213 }
17214 break;
17215 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017216 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070017217 __func__);
17218 return -EOPNOTSUPP;
17219 break;
17220 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017221 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
17222 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070017223 return -EIO;
17224 }
17225
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017226 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017227 return 0;
17228}
17229
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017230static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
17231#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17232 struct wireless_dev *wdev,
17233#endif
17234#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
17235 enum tx_power_setting type,
17236#else
17237 enum nl80211_tx_power_setting type,
17238#endif
17239 int dbm)
17240{
17241 int ret;
17242 vos_ssr_protect(__func__);
17243 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
17244#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17245 wdev,
17246#endif
17247#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
17248 type,
17249#else
17250 type,
17251#endif
17252 dbm);
17253 vos_ssr_unprotect(__func__);
17254
17255 return ret;
17256}
17257
Jeff Johnson295189b2012-06-20 16:38:30 -070017258/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017259 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070017260 * This function is used to read the txpower
17261 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017262static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070017263#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17264 struct wireless_dev *wdev,
17265#endif
17266 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070017267{
17268
17269 hdd_adapter_t *pAdapter;
17270 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017271 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017272
Jeff Johnsone7245742012-09-05 17:12:55 -070017273 ENTER();
17274
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017275 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017276 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017277 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017278 *dbm = 0;
17279 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017280 }
17281
Jeff Johnson295189b2012-06-20 16:38:30 -070017282 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
17283 if (NULL == pAdapter)
17284 {
17285 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
17286 return -ENOENT;
17287 }
17288
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017289 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17290 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
17291 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070017292 wlan_hdd_get_classAstats(pAdapter);
17293 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
17294
Jeff Johnsone7245742012-09-05 17:12:55 -070017295 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017296 return 0;
17297}
17298
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017299static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
17300#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17301 struct wireless_dev *wdev,
17302#endif
17303 int *dbm)
17304{
17305 int ret;
17306
17307 vos_ssr_protect(__func__);
17308 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
17309#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17310 wdev,
17311#endif
17312 dbm);
17313 vos_ssr_unprotect(__func__);
17314
17315 return ret;
17316}
17317
Dustin Brown8c1d4092017-07-28 18:08:01 +053017318/*
17319 * wlan_hdd_fill_summary_stats() - populate station_info summary stats
17320 * @stats: summary stats to use as a source
17321 * @info: kernel station_info struct to use as a destination
17322 *
17323 * Return: None
17324 */
17325static void wlan_hdd_fill_summary_stats(tCsrSummaryStatsInfo *stats,
17326 struct station_info *info)
17327{
17328 int i;
17329
17330 info->rx_packets = stats->rx_frm_cnt;
17331 info->tx_packets = 0;
17332 info->tx_retries = 0;
17333 info->tx_failed = 0;
17334
17335 for (i = 0; i < 4; ++i) {
17336 info->tx_packets += stats->tx_frm_cnt[i];
17337 info->tx_retries += stats->multiple_retry_cnt[i];
17338 info->tx_failed += stats->fail_cnt[i];
17339 }
17340
17341 info->filled |= STATION_INFO_TX_PACKETS |
17342 STATION_INFO_TX_RETRIES |
17343 STATION_INFO_TX_FAILED |
17344 STATION_INFO_RX_PACKETS;
17345}
17346
17347/**
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017348 * wlan_hdd_sap_get_sta_rssi() - get RSSI of the SAP client
17349 * @adapter: sap adapter pointer
17350 * @staid: station id of the client
17351 * @rssi: rssi value to fill
17352 *
17353 * Return: None
17354 */
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053017355void
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017356wlan_hdd_sap_get_sta_rssi(hdd_adapter_t *adapter, uint8_t staid, s8 *rssi)
17357{
17358 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
17359
17360 WLANTL_GetSAPStaRSSi(pVosContext, staid, rssi);
17361}
17362
17363/**
Dustin Brown8c1d4092017-07-28 18:08:01 +053017364 * wlan_hdd_get_sap_stats() - get aggregate SAP stats
17365 * @adapter: sap adapter to get stats for
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017366 * @mac: mac address of the station
Dustin Brown8c1d4092017-07-28 18:08:01 +053017367 * @info: kernel station_info struct to populate
17368 *
17369 * Fetch the vdev-level aggregate stats for the given SAP adapter. This is to
17370 * support "station dump" and "station get" for SAP vdevs, even though they
17371 * aren't technically stations.
17372 *
17373 * Return: errno
17374 */
17375static int
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017376wlan_hdd_get_sap_stats(hdd_adapter_t *adapter,
17377#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17378 const u8* mac,
17379#else
17380 u8* mac,
17381#endif
17382 struct station_info *info)
Dustin Brown8c1d4092017-07-28 18:08:01 +053017383{
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017384 v_MACADDR_t *peerMacAddr;
17385 uint8_t staid;
Dustin Brown8c1d4092017-07-28 18:08:01 +053017386 VOS_STATUS status;
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017387 bool bc_mac_addr;
Dustin Brown8c1d4092017-07-28 18:08:01 +053017388
17389 status = wlan_hdd_get_station_stats(adapter);
17390 if (!VOS_IS_STATUS_SUCCESS(status)) {
17391 hddLog(VOS_TRACE_LEVEL_ERROR,
17392 "Failed to get SAP stats; status:%d", status);
17393 return 0;
17394 }
17395
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017396 peerMacAddr = (v_MACADDR_t *)mac;
17397 bc_mac_addr = vos_is_macaddr_broadcast(peerMacAddr);
17398 staid = hdd_sta_id_find_from_mac_addr(adapter, peerMacAddr);
17399 hddLog(VOS_TRACE_LEVEL_INFO, "Get SAP stats for sta id:%d", staid);
17400
17401 if (staid < WLAN_MAX_STA_COUNT && !bc_mac_addr) {
17402 wlan_hdd_sap_get_sta_rssi(adapter, staid, &info->signal);
17403 info->filled |= STATION_INFO_SIGNAL;
17404 }
17405
Dustin Brown8c1d4092017-07-28 18:08:01 +053017406 wlan_hdd_fill_summary_stats(&adapter->hdd_stats.summary_stat, info);
17407
17408 return 0;
17409}
17410
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017411static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017412#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17413 const u8* mac,
17414#else
17415 u8* mac,
17416#endif
17417 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070017418{
17419 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
17420 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17421 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053017422 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070017423
17424 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
17425 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070017426
17427 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
17428 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
17429 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
17430 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
17431 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
17432 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
17433 tANI_U16 maxRate = 0;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053017434 int8_t snr = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070017435 tANI_U16 myRate;
17436 tANI_U16 currentRate = 0;
17437 tANI_U8 maxSpeedMCS = 0;
17438 tANI_U8 maxMCSIdx = 0;
17439 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053017440 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070017441 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017442 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017443
Leo Chang6f8870f2013-03-26 18:11:36 -070017444#ifdef WLAN_FEATURE_11AC
17445 tANI_U32 vht_mcs_map;
17446 eDataRate11ACMaxMcs vhtMaxMcs;
17447#endif /* WLAN_FEATURE_11AC */
17448
Jeff Johnsone7245742012-09-05 17:12:55 -070017449 ENTER();
17450
Dustin Brown8c1d4092017-07-28 18:08:01 +053017451 status = wlan_hdd_validate_context(pHddCtx);
17452 if (0 != status)
17453 {
17454 return status;
17455 }
17456
17457 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017458 return wlan_hdd_get_sap_stats(pAdapter, mac, sinfo);
Dustin Brown8c1d4092017-07-28 18:08:01 +053017459
Jeff Johnson295189b2012-06-20 16:38:30 -070017460 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
17461 (0 == ssidlen))
17462 {
17463 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
17464 " Invalid ssidlen, %d", __func__, ssidlen);
17465 /*To keep GUI happy*/
17466 return 0;
17467 }
17468
Mukul Sharma811205f2014-07-09 21:07:30 +053017469 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
17470 {
17471 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17472 "%s: Roaming in progress, so unable to proceed this request", __func__);
Sachin Ahuja81ab1812016-08-19 21:35:58 +053017473 /* return a cached value */
17474 sinfo->signal = pAdapter->rssi;
Mukul Sharma811205f2014-07-09 21:07:30 +053017475 return 0;
17476 }
17477
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053017478 wlan_hdd_get_station_stats(pAdapter);
17479 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070017480
Kiet Lam3b17fc82013-09-27 05:24:08 +053017481 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053017482 wlan_hdd_get_snr(pAdapter, &snr);
17483 pHddStaCtx->conn_info.signal = sinfo->signal;
17484 pHddStaCtx->conn_info.noise = pHddStaCtx->conn_info.signal - snr;
Kiet Lam3b17fc82013-09-27 05:24:08 +053017485 sinfo->filled |= STATION_INFO_SIGNAL;
17486
c_hpothu09f19542014-05-30 21:53:31 +053017487 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053017488 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
17489 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053017490 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053017491 {
17492 rate_flags = pAdapter->maxRateFlags;
17493 }
c_hpothu44ff4e02014-05-08 00:13:57 +053017494
Jeff Johnson295189b2012-06-20 16:38:30 -070017495 //convert to the UI units of 100kbps
17496 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
17497
17498#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070017499 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 -070017500 sinfo->signal,
17501 pCfg->reportMaxLinkSpeed,
17502 myRate,
17503 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070017504 (int) pCfg->linkSpeedRssiMid,
17505 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070017506 (int) rate_flags,
17507 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070017508#endif //LINKSPEED_DEBUG_ENABLED
17509
17510 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
17511 {
17512 // we do not want to necessarily report the current speed
17513 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
17514 {
17515 // report the max possible speed
17516 rssidx = 0;
17517 }
17518 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
17519 {
17520 // report the max possible speed with RSSI scaling
17521 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
17522 {
17523 // report the max possible speed
17524 rssidx = 0;
17525 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070017526 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070017527 {
17528 // report middle speed
17529 rssidx = 1;
17530 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070017531 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
17532 {
17533 // report middle speed
17534 rssidx = 2;
17535 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017536 else
17537 {
17538 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070017539 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070017540 }
17541 }
17542 else
17543 {
17544 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
17545 hddLog(VOS_TRACE_LEVEL_ERROR,
17546 "%s: Invalid value for reportMaxLinkSpeed: %u",
17547 __func__, pCfg->reportMaxLinkSpeed);
17548 rssidx = 0;
17549 }
17550
17551 maxRate = 0;
17552
17553 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053017554 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
17555 OperationalRates, &ORLeng))
17556 {
17557 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
17558 /*To keep GUI happy*/
17559 return 0;
17560 }
17561
Jeff Johnson295189b2012-06-20 16:38:30 -070017562 for (i = 0; i < ORLeng; i++)
17563 {
Jeff Johnsone7245742012-09-05 17:12:55 -070017564 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070017565 {
17566 /* Validate Rate Set */
17567 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
17568 {
17569 currentRate = supported_data_rate[j].supported_rate[rssidx];
17570 break;
17571 }
17572 }
17573 /* Update MAX rate */
17574 maxRate = (currentRate > maxRate)?currentRate:maxRate;
17575 }
17576
17577 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053017578 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
17579 ExtendedRates, &ERLeng))
17580 {
17581 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
17582 /*To keep GUI happy*/
17583 return 0;
17584 }
17585
Jeff Johnson295189b2012-06-20 16:38:30 -070017586 for (i = 0; i < ERLeng; i++)
17587 {
Jeff Johnsone7245742012-09-05 17:12:55 -070017588 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070017589 {
17590 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
17591 {
17592 currentRate = supported_data_rate[j].supported_rate[rssidx];
17593 break;
17594 }
17595 }
17596 /* Update MAX rate */
17597 maxRate = (currentRate > maxRate)?currentRate:maxRate;
17598 }
c_hpothu79aab322014-07-14 21:11:01 +053017599
Kiet Lamb69f8dc2013-11-15 15:34:27 +053017600 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053017601 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053017602 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053017603 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070017604 {
c_hpothu79aab322014-07-14 21:11:01 +053017605 if (rate_flags & eHAL_TX_RATE_VHT80)
17606 mode = 2;
17607 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
17608 mode = 1;
17609 else
17610 mode = 0;
17611
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053017612 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
17613 MCSRates, &MCSLeng))
17614 {
17615 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
17616 /*To keep GUI happy*/
17617 return 0;
17618 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017619 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070017620#ifdef WLAN_FEATURE_11AC
17621 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017622 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070017623 {
Leo Chang6f8870f2013-03-26 18:11:36 -070017624 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017625 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070017626 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070017627 {
Leo Chang6f8870f2013-03-26 18:11:36 -070017628 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070017629 }
Leo Chang6f8870f2013-03-26 18:11:36 -070017630 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070017631 {
Leo Chang6f8870f2013-03-26 18:11:36 -070017632 maxMCSIdx = 7;
17633 }
17634 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
17635 {
17636 maxMCSIdx = 8;
17637 }
17638 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
17639 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017640 //VHT20 is supporting 0~8
17641 if (rate_flags & eHAL_TX_RATE_VHT20)
17642 maxMCSIdx = 8;
17643 else
17644 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070017645 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017646
c_hpothu79aab322014-07-14 21:11:01 +053017647 if (0 != rssidx)/*check for scaled */
17648 {
17649 //get middle rate MCS index if rssi=1/2
17650 for (i=0; i <= maxMCSIdx; i++)
17651 {
17652 if (sinfo->signal <= rssiMcsTbl[mode][i])
17653 {
17654 maxMCSIdx = i;
17655 break;
17656 }
17657 }
17658 }
17659
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017660 if (rate_flags & eHAL_TX_RATE_VHT80)
17661 {
17662 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
17663 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
17664 }
17665 else if (rate_flags & eHAL_TX_RATE_VHT40)
17666 {
17667 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
17668 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
17669 }
17670 else if (rate_flags & eHAL_TX_RATE_VHT20)
17671 {
17672 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
17673 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
17674 }
17675
Leo Chang6f8870f2013-03-26 18:11:36 -070017676 maxSpeedMCS = 1;
17677 if (currentRate > maxRate)
17678 {
17679 maxRate = currentRate;
17680 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017681
Leo Chang6f8870f2013-03-26 18:11:36 -070017682 }
17683 else
17684#endif /* WLAN_FEATURE_11AC */
17685 {
17686 if (rate_flags & eHAL_TX_RATE_HT40)
17687 {
17688 rateFlag |= 1;
17689 }
17690 if (rate_flags & eHAL_TX_RATE_SGI)
17691 {
17692 rateFlag |= 2;
17693 }
17694
Girish Gowli01abcee2014-07-31 20:18:55 +053017695 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053017696 if (rssidx == 1 || rssidx == 2)
17697 {
17698 //get middle rate MCS index if rssi=1/2
17699 for (i=0; i <= 7; i++)
17700 {
17701 if (sinfo->signal <= rssiMcsTbl[mode][i])
17702 {
17703 temp = i+1;
17704 break;
17705 }
17706 }
17707 }
c_hpothu79aab322014-07-14 21:11:01 +053017708
17709 for (i = 0; i < MCSLeng; i++)
17710 {
Leo Chang6f8870f2013-03-26 18:11:36 -070017711 for (j = 0; j < temp; j++)
17712 {
17713 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
17714 {
17715 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053017716 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070017717 break;
17718 }
17719 }
17720 if ((j < temp) && (currentRate > maxRate))
17721 {
17722 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070017723 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017724 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053017725 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070017726 }
17727 }
17728
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017729 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
17730 {
17731 maxRate = myRate;
17732 maxSpeedMCS = 1;
17733 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
17734 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017735 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053017736 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070017737 {
17738 maxRate = myRate;
17739 if (rate_flags & eHAL_TX_RATE_LEGACY)
17740 {
17741 maxSpeedMCS = 0;
17742 }
17743 else
17744 {
17745 maxSpeedMCS = 1;
17746 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
17747 }
17748 }
17749
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017750 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070017751 {
17752 sinfo->txrate.legacy = maxRate;
17753#ifdef LINKSPEED_DEBUG_ENABLED
17754 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
17755#endif //LINKSPEED_DEBUG_ENABLED
17756 }
17757 else
17758 {
17759 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070017760#ifdef WLAN_FEATURE_11AC
17761 sinfo->txrate.nss = 1;
17762 if (rate_flags & eHAL_TX_RATE_VHT80)
17763 {
17764 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017765 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070017766 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017767 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070017768 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017769 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
17770 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
17771 }
17772 else if (rate_flags & eHAL_TX_RATE_VHT20)
17773 {
17774 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
17775 }
17776#endif /* WLAN_FEATURE_11AC */
17777 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
17778 {
17779 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
17780 if (rate_flags & eHAL_TX_RATE_HT40)
17781 {
17782 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
17783 }
Leo Chang6f8870f2013-03-26 18:11:36 -070017784 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017785 if (rate_flags & eHAL_TX_RATE_SGI)
17786 {
17787 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
17788 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017789
Jeff Johnson295189b2012-06-20 16:38:30 -070017790#ifdef LINKSPEED_DEBUG_ENABLED
17791 pr_info("Reporting MCS rate %d flags %x\n",
17792 sinfo->txrate.mcs,
17793 sinfo->txrate.flags );
17794#endif //LINKSPEED_DEBUG_ENABLED
17795 }
17796 }
17797 else
17798 {
17799 // report current rate instead of max rate
17800
17801 if (rate_flags & eHAL_TX_RATE_LEGACY)
17802 {
17803 //provide to the UI in units of 100kbps
17804 sinfo->txrate.legacy = myRate;
17805#ifdef LINKSPEED_DEBUG_ENABLED
17806 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
17807#endif //LINKSPEED_DEBUG_ENABLED
17808 }
17809 else
17810 {
17811 //must be MCS
17812 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070017813#ifdef WLAN_FEATURE_11AC
17814 sinfo->txrate.nss = 1;
17815 if (rate_flags & eHAL_TX_RATE_VHT80)
17816 {
17817 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
17818 }
17819 else
17820#endif /* WLAN_FEATURE_11AC */
17821 {
17822 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
17823 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017824 if (rate_flags & eHAL_TX_RATE_SGI)
17825 {
17826 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
17827 }
17828 if (rate_flags & eHAL_TX_RATE_HT40)
17829 {
17830 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
17831 }
Leo Chang6f8870f2013-03-26 18:11:36 -070017832#ifdef WLAN_FEATURE_11AC
17833 else if (rate_flags & eHAL_TX_RATE_VHT80)
17834 {
17835 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
17836 }
17837#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070017838#ifdef LINKSPEED_DEBUG_ENABLED
17839 pr_info("Reporting actual MCS rate %d flags %x\n",
17840 sinfo->txrate.mcs,
17841 sinfo->txrate.flags );
17842#endif //LINKSPEED_DEBUG_ENABLED
17843 }
17844 }
17845 sinfo->filled |= STATION_INFO_TX_BITRATE;
17846
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070017847 sinfo->tx_packets =
17848 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
17849 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
17850 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
17851 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
17852
17853 sinfo->tx_retries =
17854 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
17855 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
17856 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
17857 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
17858
17859 sinfo->tx_failed =
17860 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
17861 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
17862 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
17863 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
17864
17865 sinfo->filled |=
17866 STATION_INFO_TX_PACKETS |
17867 STATION_INFO_TX_RETRIES |
17868 STATION_INFO_TX_FAILED;
17869
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053017870 sinfo->rx_packets = pAdapter->hdd_stats.summary_stat.rx_frm_cnt;
17871 sinfo->filled |= STATION_INFO_RX_PACKETS;
17872
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053017873 vos_mem_copy(&pHddStaCtx->conn_info.txrate,
17874 &sinfo->txrate, sizeof(sinfo->txrate));
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053017875 if (rate_flags & eHAL_TX_RATE_LEGACY)
17876 hddLog(LOG1, FL("Reporting RSSI:%d legacy rate %d pkt cnt tx %d rx %d"),
17877 sinfo->signal, sinfo->txrate.legacy, sinfo->tx_packets,
17878 sinfo->rx_packets);
17879 else
17880 hddLog(LOG1,
17881 FL("Reporting RSSI:%d MCS rate %d flags 0x%x pkt cnt tx %d rx %d"),
17882 sinfo->signal, sinfo->txrate.mcs, sinfo->txrate.flags,
17883 sinfo->tx_packets, sinfo->rx_packets);
17884
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017885 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17886 TRACE_CODE_HDD_CFG80211_GET_STA,
17887 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070017888 EXIT();
17889 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070017890}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017891#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
17892static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
17893 const u8* mac, struct station_info *sinfo)
17894#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017895static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
17896 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017897#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017898{
17899 int ret;
17900
17901 vos_ssr_protect(__func__);
17902 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
17903 vos_ssr_unprotect(__func__);
17904
17905 return ret;
17906}
17907
17908static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070017909 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070017910{
17911 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017912 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070017913 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017914 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017915
Jeff Johnsone7245742012-09-05 17:12:55 -070017916 ENTER();
17917
Jeff Johnson295189b2012-06-20 16:38:30 -070017918 if (NULL == pAdapter)
17919 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017920 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017921 return -ENODEV;
17922 }
17923
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017924 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17925 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
17926 pAdapter->sessionId, timeout));
17927
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017928 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017929 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017930 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017931 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017932 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017933 }
17934
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017935 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
17936 (TRUE == pHddCtx->hdd_wlan_suspended) &&
17937 (pHddCtx->cfg_ini->fhostArpOffload) &&
17938 (eConnectionState_Associated ==
17939 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
17940 {
Amar Singhald53568e2013-09-26 11:03:45 -070017941
17942 hddLog(VOS_TRACE_LEVEL_INFO,
17943 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053017944 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017945 if (!VOS_IS_STATUS_SUCCESS(vos_status))
17946 {
17947 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017948 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017949 __func__, vos_status);
17950 }
17951 }
17952
Jeff Johnson295189b2012-06-20 16:38:30 -070017953 /**The get power cmd from the supplicant gets updated by the nl only
17954 *on successful execution of the function call
17955 *we are oppositely mapped w.r.t mode in the driver
17956 **/
17957 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
17958
17959 if (VOS_STATUS_E_FAILURE == vos_status)
17960 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053017961 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17962 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017963 return -EINVAL;
17964 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017965 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017966 return 0;
17967}
17968
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017969static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
17970 struct net_device *dev, bool mode, int timeout)
17971{
17972 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070017973
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017974 vos_ssr_protect(__func__);
17975 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
17976 vos_ssr_unprotect(__func__);
17977
17978 return ret;
17979}
Sushant Kaushik084f6592015-09-10 13:11:56 +053017980
Jeff Johnson295189b2012-06-20 16:38:30 -070017981#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017982static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
17983 struct net_device *netdev,
17984 u8 key_index)
17985{
17986 ENTER();
17987 return 0;
17988}
17989
Jeff Johnson295189b2012-06-20 16:38:30 -070017990static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017991 struct net_device *netdev,
17992 u8 key_index)
17993{
17994 int ret;
17995 vos_ssr_protect(__func__);
17996 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
17997 vos_ssr_unprotect(__func__);
17998 return ret;
17999}
18000#endif //LINUX_VERSION_CODE
18001
18002#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
18003static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
18004 struct net_device *dev,
18005 struct ieee80211_txq_params *params)
18006{
18007 ENTER();
18008 return 0;
18009}
18010#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
18011static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
18012 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070018013{
Jeff Johnsone7245742012-09-05 17:12:55 -070018014 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070018015 return 0;
18016}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018017#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070018018
18019#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
18020static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018021 struct net_device *dev,
18022 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070018023{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018024 int ret;
18025
18026 vos_ssr_protect(__func__);
18027 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
18028 vos_ssr_unprotect(__func__);
18029 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018030}
18031#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
18032static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
18033 struct ieee80211_txq_params *params)
18034{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018035 int ret;
18036
18037 vos_ssr_protect(__func__);
18038 ret = __wlan_hdd_set_txq_params(wiphy, params);
18039 vos_ssr_unprotect(__func__);
18040 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018041}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018042#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018043
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018044static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018045 struct net_device *dev,
18046 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070018047{
18048 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018049 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018050 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018051 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018052 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018053 v_CONTEXT_t pVosContext = NULL;
18054 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018055
Jeff Johnsone7245742012-09-05 17:12:55 -070018056 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018057
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018058 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070018059 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018060 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018061 return -EINVAL;
18062 }
18063
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018064 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18065 TRACE_CODE_HDD_CFG80211_DEL_STA,
18066 pAdapter->sessionId, pAdapter->device_mode));
18067
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018068 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18069 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018070 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018071 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018072 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018073 }
18074
Jeff Johnson295189b2012-06-20 16:38:30 -070018075 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070018076 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070018077 )
18078 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018079 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
18080 pSapCtx = VOS_GET_SAP_CB(pVosContext);
18081 if(pSapCtx == NULL){
18082 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18083 FL("psapCtx is NULL"));
18084 return -ENOENT;
18085 }
Agrawal Ashish306b75f2017-01-11 19:16:25 +053018086 if (pHddCtx->cfg_ini->enable_sap_auth_offload)
18087 {
18088 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
18089 "Change reason code to eSIR_MAC_DISASSOC_LEAVING_BSS_REASON in sap auth offload");
18090 pDelStaParams->reason_code = eSIR_MAC_DISASSOC_LEAVING_BSS_REASON;
18091 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018092 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070018093 {
18094 v_U16_t i;
18095 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
18096 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018097 if ((pSapCtx->aStaInfo[i].isUsed) &&
18098 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070018099 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018100 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018101 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018102 ETHER_ADDR_LEN);
18103
Jeff Johnson295189b2012-06-20 16:38:30 -070018104 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018105 "%s: Delete STA with MAC::"
18106 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018107 __func__,
18108 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
18109 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070018110 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018111 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070018112 }
18113 }
18114 }
18115 else
18116 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018117
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018118 vos_status = hdd_softap_GetStaId(pAdapter,
18119 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018120 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18121 {
18122 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018123 "%s: Skip this DEL STA as this is not used::"
18124 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018125 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018126 return -ENOENT;
18127 }
18128
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018129 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018130 {
18131 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018132 "%s: Skip this DEL STA as deauth is in progress::"
18133 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018134 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018135 return -ENOENT;
18136 }
18137
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018138 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018139
Jeff Johnson295189b2012-06-20 16:38:30 -070018140 hddLog(VOS_TRACE_LEVEL_INFO,
18141 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080018142 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070018143 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018144 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018145
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018146 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018147 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18148 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018149 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018150 hddLog(VOS_TRACE_LEVEL_INFO,
18151 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080018152 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018153 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018154 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018155 return -ENOENT;
18156 }
18157
Jeff Johnson295189b2012-06-20 16:38:30 -070018158 }
18159 }
18160
18161 EXIT();
18162
18163 return 0;
18164}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018165
18166#ifdef CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053018167int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018168 struct net_device *dev,
18169 struct station_del_parameters *param)
18170#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018171#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
Kapil Gupta137ef892016-12-13 19:38:00 +053018172int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018173 struct net_device *dev, const u8 *mac)
18174#else
Kapil Gupta137ef892016-12-13 19:38:00 +053018175int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018176 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018177#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018178#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018179{
18180 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018181 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070018182
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018183 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018184
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018185#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018186 if (NULL == param) {
18187 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018188 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018189 return -EINVAL;
18190 }
18191
18192 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
18193 param->subtype, &delStaParams);
18194
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018195#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053018196 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018197 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018198#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018199 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
18200
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018201 vos_ssr_unprotect(__func__);
18202
18203 return ret;
18204}
18205
18206static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018207 struct net_device *dev,
18208#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18209 const u8 *mac,
18210#else
18211 u8 *mac,
18212#endif
18213 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018214{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018215 hdd_adapter_t *pAdapter;
18216 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018217 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018218#ifdef FEATURE_WLAN_TDLS
18219 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018220
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018221 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018222
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018223 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18224 if (NULL == pAdapter)
18225 {
18226 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18227 "%s: Adapter is NULL",__func__);
18228 return -EINVAL;
18229 }
18230 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18231 status = wlan_hdd_validate_context(pHddCtx);
18232 if (0 != status)
18233 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018234 return status;
18235 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018236
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018237 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18238 TRACE_CODE_HDD_CFG80211_ADD_STA,
18239 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018240 mask = params->sta_flags_mask;
18241
18242 set = params->sta_flags_set;
18243
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018244 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018245 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
18246 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018247
18248 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
18249 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080018250 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018251 }
18252 }
18253#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018254 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018255 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018256}
18257
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018258#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18259static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
18260 struct net_device *dev, const u8 *mac,
18261 struct station_parameters *params)
18262#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018263static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
18264 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018265#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018266{
18267 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018268
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018269 vos_ssr_protect(__func__);
18270 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
18271 vos_ssr_unprotect(__func__);
18272
18273 return ret;
18274}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018275#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070018276
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018277static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070018278 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018279{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018280 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18281 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018282 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018283 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018284 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018285 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070018286
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018287 ENTER();
18288
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018289 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018290 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018291 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018292 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018293 return -EINVAL;
18294 }
18295
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018296 if (!pmksa) {
18297 hddLog(LOGE, FL("pmksa is NULL"));
18298 return -EINVAL;
18299 }
18300
18301 if (!pmksa->bssid || !pmksa->pmkid) {
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070018302 hddLog(LOGE, FL("pmksa->bssid(%pK) or pmksa->pmkid(%pK) is NULL"),
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018303 pmksa->bssid, pmksa->pmkid);
18304 return -EINVAL;
18305 }
18306
18307 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
18308 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
18309
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018310 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18311 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018312 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018313 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018314 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018315 }
18316
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018317 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018318 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
18319
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018320 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
18321 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018322
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018323 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018324 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018325 &pmk_id, 1, FALSE);
18326
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018327 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18328 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
18329 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018330
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018331 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018332 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018333}
18334
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018335static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
18336 struct cfg80211_pmksa *pmksa)
18337{
18338 int ret;
18339
18340 vos_ssr_protect(__func__);
18341 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
18342 vos_ssr_unprotect(__func__);
18343
18344 return ret;
18345}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018346
Wilson Yang6507c4e2013-10-01 20:11:19 -070018347
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018348static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070018349 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018350{
Wilson Yang6507c4e2013-10-01 20:11:19 -070018351 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18352 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018353 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080018354 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018355
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018356 ENTER();
18357
Wilson Yang6507c4e2013-10-01 20:11:19 -070018358 /* Validate pAdapter */
18359 if (NULL == pAdapter)
18360 {
18361 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
18362 return -EINVAL;
18363 }
18364
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018365 if (!pmksa) {
18366 hddLog(LOGE, FL("pmksa is NULL"));
18367 return -EINVAL;
18368 }
18369
18370 if (!pmksa->bssid) {
18371 hddLog(LOGE, FL("pmksa->bssid is NULL"));
18372 return -EINVAL;
18373 }
18374
Kiet Lam98c46a12014-10-31 15:34:57 -070018375 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
18376 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
18377
Wilson Yang6507c4e2013-10-01 20:11:19 -070018378 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18379 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070018380 if (0 != status)
18381 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070018382 return status;
18383 }
18384
18385 /*Retrieve halHandle*/
18386 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
18387
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018388 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18389 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
18390 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018391 /* Delete the PMKID CSR cache */
18392 if (eHAL_STATUS_SUCCESS !=
18393 sme_RoamDelPMKIDfromCache(halHandle,
18394 pAdapter->sessionId, pmksa->bssid, FALSE)) {
18395 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
18396 MAC_ADDR_ARRAY(pmksa->bssid));
18397 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018398 }
18399
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018400 EXIT();
18401 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018402}
18403
Wilson Yang6507c4e2013-10-01 20:11:19 -070018404
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018405static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
18406 struct cfg80211_pmksa *pmksa)
18407{
18408 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018409
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018410 vos_ssr_protect(__func__);
18411 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
18412 vos_ssr_unprotect(__func__);
18413
18414 return ret;
18415
18416}
18417
18418static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018419{
Wilson Yang6507c4e2013-10-01 20:11:19 -070018420 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18421 tHalHandle halHandle;
18422 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080018423 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018424
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018425 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070018426
18427 /* Validate pAdapter */
18428 if (NULL == pAdapter)
18429 {
18430 hddLog(VOS_TRACE_LEVEL_ERROR,
18431 "%s: Invalid Adapter" ,__func__);
18432 return -EINVAL;
18433 }
18434
18435 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18436 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070018437 if (0 != status)
18438 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070018439 return status;
18440 }
18441
18442 /*Retrieve halHandle*/
18443 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
18444
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018445 /* Flush the PMKID cache in CSR */
18446 if (eHAL_STATUS_SUCCESS !=
18447 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
18448 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
18449 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018450 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018451 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080018452 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018453}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018454
18455static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
18456{
18457 int ret;
18458
18459 vos_ssr_protect(__func__);
18460 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
18461 vos_ssr_unprotect(__func__);
18462
18463 return ret;
18464}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018465#endif
18466
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018467#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018468static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
18469 struct net_device *dev,
18470 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018471{
18472 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18473 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018474 hdd_context_t *pHddCtx;
18475 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018476
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018477 ENTER();
18478
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018479 if (NULL == pAdapter)
18480 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080018481 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018482 return -ENODEV;
18483 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018484 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18485 ret = wlan_hdd_validate_context(pHddCtx);
18486 if (0 != ret)
18487 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018488 return ret;
18489 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018490 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018491 if (NULL == pHddStaCtx)
18492 {
18493 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
18494 return -EINVAL;
18495 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018496
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018497 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18498 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
18499 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018500 // Added for debug on reception of Re-assoc Req.
18501 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
18502 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080018503 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018504 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080018505 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018506 }
18507
18508#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080018509 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018510 ftie->ie_len);
18511#endif
18512
18513 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053018514 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
18515 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018516 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018517
18518 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018519 return 0;
18520}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018521
18522static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
18523 struct net_device *dev,
18524 struct cfg80211_update_ft_ies_params *ftie)
18525{
18526 int ret;
18527
18528 vos_ssr_protect(__func__);
18529 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
18530 vos_ssr_unprotect(__func__);
18531
18532 return ret;
18533}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018534#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018535
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018536#ifdef FEATURE_WLAN_SCAN_PNO
18537
18538void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
18539 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
18540{
18541 int ret;
18542 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
18543 hdd_context_t *pHddCtx;
18544
Nirav Shah80830bf2013-12-31 16:35:12 +053018545 ENTER();
18546
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018547 if (NULL == pAdapter)
18548 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053018549 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018550 "%s: HDD adapter is Null", __func__);
18551 return ;
18552 }
18553
18554 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18555 if (NULL == pHddCtx)
18556 {
18557 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18558 "%s: HDD context is Null!!!", __func__);
18559 return ;
18560 }
18561
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018562 spin_lock(&pHddCtx->schedScan_lock);
18563 if (TRUE == pHddCtx->isWiphySuspended)
18564 {
18565 pHddCtx->isSchedScanUpdatePending = TRUE;
18566 spin_unlock(&pHddCtx->schedScan_lock);
18567 hddLog(VOS_TRACE_LEVEL_INFO,
18568 "%s: Update cfg80211 scan database after it resume", __func__);
18569 return ;
18570 }
18571 spin_unlock(&pHddCtx->schedScan_lock);
18572
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018573 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
18574
18575 if (0 > ret)
18576 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagarfb49cdd2015-10-16 18:41:59 +053018577 else
18578 {
18579 /* Acquire wakelock to handle the case where APP's tries to suspend
18580 * immediatly after the driver gets connect request(i.e after pno)
18581 * from supplicant, this result in app's is suspending and not able
18582 * to process the connect request to AP */
18583 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
18584 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018585 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018586 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18587 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018588}
18589
18590/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018591 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053018592 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018593 */
18594static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
18595{
18596 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
18597 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018598 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018599 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18600 int status = 0;
Agrawal Ashishcff31692016-12-16 17:17:50 +053018601
18602 if (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
18603 {
18604 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18605 "%s: PNO is allowed only in STA interface", __func__);
18606 return eHAL_STATUS_FAILURE;
18607 }
18608
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018609 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
18610
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053018611 /* The current firmware design does not allow PNO during any
Agrawal Ashishcff31692016-12-16 17:17:50 +053018612 * active sessions. PNO is allowed only in case when sap session
18613 * is present and sapo auth offload feature enabled in firmare.
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053018614 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018615 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
18616 {
18617 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018618 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018619
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018620 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
18621 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
18622 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
18623 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
Agrawal Ashishcff31692016-12-16 17:17:50 +053018624 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode &&
18625 !pHddCtx->cfg_ini->enable_sap_auth_offload)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053018626 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018627 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018628 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018629 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018630 }
18631 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
18632 pAdapterNode = pNext;
18633 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018634 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018635}
18636
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018637void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
18638{
18639 hdd_adapter_t *pAdapter = callbackContext;
18640 hdd_context_t *pHddCtx;
18641
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018642 ENTER();
18643
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018644 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
18645 {
18646 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18647 FL("Invalid adapter or adapter has invalid magic"));
18648 return;
18649 }
18650
18651 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18652 if (0 != wlan_hdd_validate_context(pHddCtx))
18653 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018654 return;
18655 }
18656
c_hpothub53c45d2014-08-18 16:53:14 +053018657 if (VOS_STATUS_SUCCESS != status)
18658 {
18659 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018660 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053018661 pHddCtx->isPnoEnable = FALSE;
18662 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018663
18664 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
18665 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018666 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018667}
18668
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018669#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) || \
18670 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
18671/**
18672 * hdd_config_sched_scan_plan() - configures the sched scan plans
18673 * from the framework.
18674 * @pno_req: pointer to PNO scan request
18675 * @request: pointer to scan request from framework
18676 *
18677 * Return: None
18678 */
18679static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
18680 struct cfg80211_sched_scan_request *request,
18681 hdd_context_t *hdd_ctx)
18682{
18683 v_U32_t i = 0;
18684
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018685 pno_req->scanTimers.ucScanTimersCount = request->n_scan_plans;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018686 for (i = 0; i < request->n_scan_plans; i++)
18687 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018688 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
18689 request->scan_plans[i].iterations;
18690 pno_req->scanTimers.aTimerValues[i].uTimerValue =
18691 request->scan_plans[i].interval;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018692 }
18693}
18694#else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018695static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018696 struct cfg80211_sched_scan_request *request,
18697 hdd_context_t *hdd_ctx)
18698{
18699 v_U32_t i, temp_int;
18700 /* Driver gets only one time interval which is hardcoded in
18701 * supplicant for 10000ms. Taking power consumption into account 6
18702 * timers will be used, Timervalue is increased exponentially
18703 * i.e 10,20,40, 80,160,320 secs. And number of scan cycle for each
18704 * timer is configurable through INI param gPNOScanTimerRepeatValue.
18705 * If it is set to 0 only one timer will be used and PNO scan cycle
18706 * will be repeated after each interval specified by supplicant
18707 * till PNO is disabled.
18708 */
18709 if (0 == hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue)
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018710 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018711 HDD_PNO_SCAN_TIMERS_SET_ONE;
18712 else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018713 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018714 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
18715
18716 temp_int = (request->interval)/1000;
18717 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18718 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
18719 temp_int, hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue);
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018720 for ( i = 0; i < pno_req->scanTimers.ucScanTimersCount; i++)
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018721 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018722 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018723 hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue;
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018724 pno_req->scanTimers.aTimerValues[i].uTimerValue = temp_int;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018725 temp_int *= 2;
18726 }
18727 //Repeat last timer until pno disabled.
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018728 pno_req->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018729}
18730#endif
18731
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018732/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018733 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
18734 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018735 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018736static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018737 struct net_device *dev, struct cfg80211_sched_scan_request *request)
18738{
18739 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018740 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018741 hdd_context_t *pHddCtx;
18742 tHalHandle hHal;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018743 v_U32_t i, indx, num_ch, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053018744 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
18745 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018746 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
18747 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018748 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053018749 hdd_config_t *pConfig = NULL;
18750 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018751
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018752 ENTER();
18753
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018754 if (NULL == pAdapter)
18755 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018756 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018757 "%s: HDD adapter is Null", __func__);
18758 return -ENODEV;
18759 }
18760
18761 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018762 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018763
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018764 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018765 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018766 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018767 }
18768
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053018769 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018770 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
18771 if (NULL == hHal)
18772 {
18773 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18774 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018775 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018776 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018777 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18778 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
18779 pAdapter->sessionId, pAdapter->device_mode));
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053018780 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053018781 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053018782 {
18783 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18784 "%s: aborting the existing scan is unsuccessfull", __func__);
18785 return -EBUSY;
18786 }
18787
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018788 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018789 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053018790 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018791 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018792 return -EBUSY;
18793 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018794
c_hpothu37f21312014-04-09 21:49:54 +053018795 if (TRUE == pHddCtx->isPnoEnable)
18796 {
18797 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
18798 FL("already PNO is enabled"));
18799 return -EBUSY;
18800 }
c_hpothu225aa7c2014-10-22 17:45:13 +053018801
18802 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
18803 {
18804 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18805 "%s: abort ROC failed ", __func__);
18806 return -EBUSY;
18807 }
18808
c_hpothu37f21312014-04-09 21:49:54 +053018809 pHddCtx->isPnoEnable = TRUE;
18810
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018811 pnoRequest.enable = 1; /*Enable PNO */
18812 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018813
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018814 if (( !pnoRequest.ucNetworksCount ) ||
18815 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018816 {
18817 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053018818 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018819 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053018820 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018821 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018822 goto error;
18823 }
18824
18825 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
18826 {
18827 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053018828 "%s: Incorrect number of channels %d",
18829 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018830 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018831 goto error;
18832 }
18833
18834 /* Framework provides one set of channels(all)
18835 * common for all saved profile */
18836 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
18837 channels_allowed, &num_channels_allowed))
18838 {
18839 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18840 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018841 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018842 goto error;
18843 }
18844 /* Checking each channel against allowed channel list */
18845 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053018846 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018847 {
Nirav Shah80830bf2013-12-31 16:35:12 +053018848 char chList [(request->n_channels*5)+1];
18849 int len;
18850 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018851 {
Nirav Shah80830bf2013-12-31 16:35:12 +053018852 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018853 {
Nirav Shah80830bf2013-12-31 16:35:12 +053018854 if (request->channels[i]->hw_value == channels_allowed[indx])
18855 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053018856 if ((!pConfig->enableDFSPnoChnlScan) &&
18857 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
18858 {
18859 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18860 "%s : Dropping DFS channel : %d",
18861 __func__,channels_allowed[indx]);
18862 num_ignore_dfs_ch++;
18863 break;
18864 }
18865
Nirav Shah80830bf2013-12-31 16:35:12 +053018866 valid_ch[num_ch++] = request->channels[i]->hw_value;
18867 len += snprintf(chList+len, 5, "%d ",
18868 request->channels[i]->hw_value);
18869 break ;
18870 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018871 }
18872 }
Nirav Shah80830bf2013-12-31 16:35:12 +053018873 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018874
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053018875 /*If all channels are DFS and dropped, then ignore the PNO request*/
18876 if (num_ignore_dfs_ch == request->n_channels)
18877 {
18878 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18879 "%s : All requested channels are DFS channels", __func__);
18880 ret = -EINVAL;
18881 goto error;
18882 }
18883 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018884
18885 pnoRequest.aNetworks =
18886 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
18887 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018888 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018889 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
18890 FL("failed to allocate memory aNetworks %u"),
18891 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
18892 goto error;
18893 }
18894 vos_mem_zero(pnoRequest.aNetworks,
18895 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
18896
18897 /* Filling per profile params */
18898 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
18899 {
18900 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018901 request->match_sets[i].ssid.ssid_len;
18902
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018903 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
18904 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018905 {
18906 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053018907 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018908 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018909 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018910 goto error;
18911 }
18912
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018913 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018914 request->match_sets[i].ssid.ssid,
18915 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053018916 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18917 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018918 i, pnoRequest.aNetworks[i].ssId.ssId);
18919 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
18920 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
18921 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018922
18923 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018924 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
18925 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018926
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018927 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018928 }
18929
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018930 for (i = 0; i < request->n_ssids; i++)
18931 {
18932 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018933 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018934 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018935 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018936 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018937 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018938 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018939 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018940 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018941 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018942 break;
18943 }
18944 j++;
18945 }
18946 }
18947 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18948 "Number of hidden networks being Configured = %d",
18949 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053018950 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080018951 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018952
18953 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
18954 if (pnoRequest.p24GProbeTemplate == NULL)
18955 {
18956 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
18957 FL("failed to allocate memory p24GProbeTemplate %u"),
18958 SIR_PNO_MAX_PB_REQ_SIZE);
18959 goto error;
18960 }
18961
18962 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
18963 if (pnoRequest.p5GProbeTemplate == NULL)
18964 {
18965 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
18966 FL("failed to allocate memory p5GProbeTemplate %u"),
18967 SIR_PNO_MAX_PB_REQ_SIZE);
18968 goto error;
18969 }
18970
18971 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
18972 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
18973
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053018974 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
18975 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053018976 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018977 pnoRequest.us24GProbeTemplateLen = request->ie_len;
18978 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
18979 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053018980
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018981 pnoRequest.us5GProbeTemplateLen = request->ie_len;
18982 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
18983 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053018984 }
18985
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018986 hdd_config_sched_scan_plan(&pnoRequest, request, pHddCtx);
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053018987
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018988 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018989
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018990 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018991 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
18992 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018993 pAdapter->pno_req_status = 0;
18994
Nirav Shah80830bf2013-12-31 16:35:12 +053018995 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18996 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018997 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
18998 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053018999
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019000 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019001 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019002 hdd_cfg80211_sched_scan_done_callback, pAdapter);
19003 if (eHAL_STATUS_SUCCESS != status)
19004 {
19005 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019006 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019007 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019008 goto error;
19009 }
19010
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019011 ret = wait_for_completion_timeout(
19012 &pAdapter->pno_comp_var,
19013 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
19014 if (0 >= ret)
19015 {
19016 // Did not receive the response for PNO enable in time.
19017 // Assuming the PNO enable was success.
19018 // Returning error from here, because we timeout, results
19019 // in side effect of Wifi (Wifi Setting) not to work.
19020 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19021 FL("Timed out waiting for PNO to be Enabled"));
19022 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019023 }
19024
19025 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053019026 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019027
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019028error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019029 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19030 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053019031 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019032 if (pnoRequest.aNetworks)
19033 vos_mem_free(pnoRequest.aNetworks);
19034 if (pnoRequest.p24GProbeTemplate)
19035 vos_mem_free(pnoRequest.p24GProbeTemplate);
19036 if (pnoRequest.p5GProbeTemplate)
19037 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019038
19039 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019040 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019041}
19042
19043/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019044 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
19045 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019046 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019047static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
19048 struct net_device *dev, struct cfg80211_sched_scan_request *request)
19049{
19050 int ret;
19051
19052 vos_ssr_protect(__func__);
19053 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
19054 vos_ssr_unprotect(__func__);
19055
19056 return ret;
19057}
19058
19059/*
19060 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
19061 * Function to disable PNO
19062 */
19063static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019064 struct net_device *dev)
19065{
19066 eHalStatus status = eHAL_STATUS_FAILURE;
19067 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19068 hdd_context_t *pHddCtx;
19069 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019070 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019071 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019072
19073 ENTER();
19074
19075 if (NULL == pAdapter)
19076 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019077 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019078 "%s: HDD adapter is Null", __func__);
19079 return -ENODEV;
19080 }
19081
19082 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019083
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019084 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019085 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019086 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019087 "%s: HDD context is Null", __func__);
19088 return -ENODEV;
19089 }
19090
19091 /* The return 0 is intentional when isLogpInProgress and
19092 * isLoadUnloadInProgress. We did observe a crash due to a return of
19093 * failure in sched_scan_stop , especially for a case where the unload
19094 * of the happens at the same time. The function __cfg80211_stop_sched_scan
19095 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
19096 * success. If it returns a failure , then its next invocation due to the
19097 * clean up of the second interface will have the dev pointer corresponding
19098 * to the first one leading to a crash.
19099 */
19100 if (pHddCtx->isLogpInProgress)
19101 {
19102 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19103 "%s: LOGP in Progress. Ignore!!!", __func__);
Mahesh A Saptasagar0c11d822015-10-08 19:54:08 +053019104 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019105 return ret;
19106 }
19107
Mihir Shete18156292014-03-11 15:38:30 +053019108 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019109 {
19110 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19111 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
19112 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019113 }
19114
19115 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
19116 if (NULL == hHal)
19117 {
19118 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19119 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019120 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019121 }
19122
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019123 pnoRequest.enable = 0; /* Disable PNO */
19124 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019125
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019126 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19127 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
19128 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019129
19130 INIT_COMPLETION(pAdapter->pno_comp_var);
19131 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
19132 pnoRequest.callbackContext = pAdapter;
19133 pAdapter->pno_req_status = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019134 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019135 pAdapter->sessionId,
19136 NULL, pAdapter);
19137 if (eHAL_STATUS_SUCCESS != status)
19138 {
19139 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19140 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019141 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019142 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019143 }
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019144 ret = wait_for_completion_timeout(
19145 &pAdapter->pno_comp_var,
19146 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
19147 if (0 >= ret)
19148 {
19149 // Did not receive the response for PNO disable in time.
19150 // Assuming the PNO disable was success.
19151 // Returning error from here, because we timeout, results
19152 // in side effect of Wifi (Wifi Setting) not to work.
Anurag Chouhan96b41cb2016-09-28 18:54:47 +053019153 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019154 FL("Timed out waiting for PNO to be disabled"));
19155 ret = 0;
19156 }
19157
19158 ret = pAdapter->pno_req_status;
19159 pHddCtx->isPnoEnable = (ret == 0) ? FALSE : TRUE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019160
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019161error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019162 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019163 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019164
19165 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019166 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019167}
19168
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019169/*
19170 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
19171 * NL interface to disable PNO
19172 */
19173static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
19174 struct net_device *dev)
19175{
19176 int ret;
19177
19178 vos_ssr_protect(__func__);
19179 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
19180 vos_ssr_unprotect(__func__);
19181
19182 return ret;
19183}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019184#endif /*FEATURE_WLAN_SCAN_PNO*/
19185
19186
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019187#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019188#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019189static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19190 struct net_device *dev,
19191 u8 *peer, u8 action_code,
19192 u8 dialog_token,
19193 u16 status_code, u32 peer_capability,
19194 const u8 *buf, size_t len)
19195#else /* TDLS_MGMT_VERSION2 */
19196#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
19197static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19198 struct net_device *dev,
19199 const u8 *peer, u8 action_code,
19200 u8 dialog_token, u16 status_code,
19201 u32 peer_capability, bool initiator,
19202 const u8 *buf, size_t len)
19203#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
19204static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19205 struct net_device *dev,
19206 const u8 *peer, u8 action_code,
19207 u8 dialog_token, u16 status_code,
19208 u32 peer_capability, const u8 *buf,
19209 size_t len)
19210#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
19211static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19212 struct net_device *dev,
19213 u8 *peer, u8 action_code,
19214 u8 dialog_token,
19215 u16 status_code, u32 peer_capability,
19216 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019217#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019218static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19219 struct net_device *dev,
19220 u8 *peer, u8 action_code,
19221 u8 dialog_token,
19222 u16 status_code, const u8 *buf,
19223 size_t len)
19224#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019225#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019226{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019227 hdd_adapter_t *pAdapter;
19228 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019229 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070019230 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080019231 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070019232 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019233 int ret;
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053019234 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019235#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019236 u32 peer_capability = 0;
19237#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053019238 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019239 hdd_station_ctx_t *pHddStaCtx = NULL;
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019240 tdlsCtx_t *pHddTdlsCtx;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019241
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019242 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19243 if (NULL == pAdapter)
19244 {
19245 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19246 "%s: Adapter is NULL",__func__);
19247 return -EINVAL;
19248 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019249 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19250 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
19251 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019252
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019253 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019254 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019255 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019256 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019257 "Invalid arguments");
19258 return -EINVAL;
19259 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019260
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080019261 if (pHddCtx->isLogpInProgress)
19262 {
19263 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19264 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053019265 wlan_hdd_tdls_set_link_status(pAdapter,
19266 peer,
19267 eTDLS_LINK_IDLE,
19268 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080019269 return -EBUSY;
19270 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019271
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019272 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
19273 {
19274 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19275 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
19276 return -EAGAIN;
19277 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019278
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019279 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
19280 if (!pHddTdlsCtx) {
19281 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19282 "%s: pHddTdlsCtx not valid.", __func__);
19283 }
19284
Hoonki Lee27511902013-03-14 18:19:06 -070019285 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019286 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019287 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070019288 "%s: TDLS mode is disabled OR not enabled in FW."
19289 MAC_ADDRESS_STR " action %d declined.",
19290 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019291 return -ENOTSUPP;
19292 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080019293
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019294 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
19295
19296 if( NULL == pHddStaCtx )
19297 {
19298 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19299 "%s: HDD station context NULL ",__func__);
19300 return -EINVAL;
19301 }
19302
19303 /* STA should be connected and authenticated
19304 * before sending any TDLS frames
19305 */
19306 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
19307 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
19308 {
19309 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19310 "STA is not connected or unauthenticated. "
19311 "connState %u, uIsAuthenticated %u",
19312 pHddStaCtx->conn_info.connState,
19313 pHddStaCtx->conn_info.uIsAuthenticated);
19314 return -EAGAIN;
19315 }
19316
Hoonki Lee27511902013-03-14 18:19:06 -070019317 /* other than teardown frame, other mgmt frames are not sent if disabled */
19318 if (SIR_MAC_TDLS_TEARDOWN != action_code)
19319 {
19320 /* if tdls_mode is disabled to respond to peer's request */
19321 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
19322 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019323 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070019324 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070019325 " TDLS mode is disabled. action %d declined.",
19326 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070019327
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019328 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070019329 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053019330
19331 if (vos_max_concurrent_connections_reached())
19332 {
19333 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
19334 return -EINVAL;
19335 }
Hoonki Lee27511902013-03-14 18:19:06 -070019336 }
19337
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019338 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
19339 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053019340 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019341 {
19342 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019343 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070019344 " TDLS setup is ongoing. action %d declined.",
19345 __func__, MAC_ADDR_ARRAY(peer), action_code);
19346 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019347 }
19348 }
19349
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019350 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
19351 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080019352 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053019353 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
19354 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080019355 {
19356 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
19357 we return error code at 'add_station()'. Hence we have this
19358 check again in addtion to add_station().
19359 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019360 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080019361 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019362 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19363 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053019364 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
19365 __func__, MAC_ADDR_ARRAY(peer), action_code,
19366 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053019367 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080019368 }
19369 else
19370 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019371 /* maximum reached. tweak to send error code to peer and return
19372 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080019373 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019374 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19375 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053019376 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
19377 __func__, MAC_ADDR_ARRAY(peer), status_code,
19378 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070019379 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019380 /* fall through to send setup resp with failure status
19381 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080019382 }
19383 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019384 else
19385 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019386 mutex_lock(&pHddCtx->tdls_lock);
19387 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019388 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019389 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019390 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019391 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070019392 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
19393 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019394 return -EPERM;
19395 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019396 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019397 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080019398 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019399
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019400 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053019401 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019402 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
19403 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019404
Hoonki Leea34dd892013-02-05 22:56:02 -080019405 /*Except teardown responder will not be used so just make 0*/
19406 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019407 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080019408 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070019409
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019410 mutex_lock(&pHddCtx->tdls_lock);
19411 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070019412
19413 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
19414 responder = pTdlsPeer->is_responder;
19415 else
Hoonki Leea34dd892013-02-05 22:56:02 -080019416 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070019417 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053019418 "%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 -070019419 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
19420 dialog_token, status_code, len);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019421 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070019422 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080019423 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019424 mutex_unlock(&pHddCtx->tdls_lock);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019425 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019426
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053019427 /* Discard TDLS setup if peer is removed by user app */
19428 if ((pHddCtx->cfg_ini->fTDLSExternalControl) &&
19429 ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
19430 (SIR_MAC_TDLS_SETUP_CNF == action_code) ||
19431 (SIR_MAC_TDLS_DIS_REQ == action_code))) {
19432
19433 mutex_lock(&pHddCtx->tdls_lock);
19434 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
19435 if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) {
19436 mutex_unlock(&pHddCtx->tdls_lock);
19437 hddLog(LOGE, FL("TDLS External Control enabled, but peer "
19438 MAC_ADDRESS_STR " is not forced, so reject the action code %d"),
19439 MAC_ADDR_ARRAY(peer), action_code);
19440 return -EINVAL;
19441 }
19442 mutex_unlock(&pHddCtx->tdls_lock);
19443 }
19444
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053019445 /* For explicit trigger of DIS_REQ come out of BMPS for
19446 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070019447 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Deepthi Gowrif78f1f72016-03-21 13:13:28 +053019448 (SIR_MAC_TDLS_SETUP_CNF== action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053019449 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
19450 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070019451 {
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019452 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter))) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019453 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019454 "%s: Sending frame action_code %u.Disable BMPS", __func__,
19455 action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019456 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
19457 if (status != VOS_STATUS_SUCCESS) {
19458 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019459 } else {
19460 pHddTdlsCtx->is_tdls_disabled_bmps = true;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019461 }
Hoonki Lee14621352013-04-16 17:51:19 -070019462 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019463 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019464 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019465 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
19466 }
19467 }
Hoonki Lee14621352013-04-16 17:51:19 -070019468 }
19469
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019470 /* make sure doesn't call send_mgmt() while it is pending */
19471 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
19472 {
19473 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080019474 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019475 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019476 ret = -EBUSY;
19477 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019478 }
19479
19480 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019481 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
19482
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019483 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
19484 pAdapter->sessionId, peer, action_code, dialog_token,
19485 status_code, peer_capability, (tANI_U8 *)buf, len,
19486 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019487
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019488 if (VOS_STATUS_SUCCESS != status)
19489 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019490 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19491 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019492 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019493 ret = -EINVAL;
19494 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019495 }
19496
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019497 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19498 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
19499 WAIT_TIME_TDLS_MGMT);
19500
Hoonki Leed37cbb32013-04-20 00:31:14 -070019501 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
19502 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
19503
19504 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019505 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070019506 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070019507 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070019508 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019509 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080019510
19511 if (pHddCtx->isLogpInProgress)
19512 {
19513 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19514 "%s: LOGP in Progress. Ignore!!!", __func__);
19515 return -EAGAIN;
19516 }
Abhishek Singh837adf22015-10-01 17:37:37 +053019517 if (rc <= 0)
19518 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
19519 WLAN_LOG_INDICATOR_HOST_DRIVER,
19520 WLAN_LOG_REASON_HDD_TIME_OUT,
19521 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080019522
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019523 ret = -EINVAL;
19524 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019525 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019526 else
19527 {
19528 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19529 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
19530 __func__, rc, pAdapter->mgmtTxCompletionStatus);
19531 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019532
Gopichand Nakkala05922802013-03-14 12:23:19 -070019533 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070019534 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019535 ret = max_sta_failed;
19536 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070019537 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019538
Hoonki Leea34dd892013-02-05 22:56:02 -080019539 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
19540 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019541 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019542 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
19543 }
Hoonki Leea34dd892013-02-05 22:56:02 -080019544 }
19545 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
19546 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019547 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019548 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
19549 }
Hoonki Leea34dd892013-02-05 22:56:02 -080019550 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019551
19552 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019553
19554tx_failed:
19555 /* add_station will be called before sending TDLS_SETUP_REQ and
19556 * TDLS_SETUP_RSP and as part of add_station driver will enable
19557 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
19558 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
19559 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
19560 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
19561 */
19562
19563 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
19564 (SIR_MAC_TDLS_SETUP_RSP == action_code))
19565 wlan_hdd_tdls_check_bmps(pAdapter);
19566 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019567}
19568
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019569#if TDLS_MGMT_VERSION2
19570static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
19571 u8 *peer, u8 action_code, u8 dialog_token,
19572 u16 status_code, u32 peer_capability,
19573 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019574#else /* TDLS_MGMT_VERSION2 */
19575#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
19576static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19577 struct net_device *dev,
19578 const u8 *peer, u8 action_code,
19579 u8 dialog_token, u16 status_code,
19580 u32 peer_capability, bool initiator,
19581 const u8 *buf, size_t len)
19582#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
19583static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19584 struct net_device *dev,
19585 const u8 *peer, u8 action_code,
19586 u8 dialog_token, u16 status_code,
19587 u32 peer_capability, const u8 *buf,
19588 size_t len)
19589#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
19590static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19591 struct net_device *dev,
19592 u8 *peer, u8 action_code,
19593 u8 dialog_token,
19594 u16 status_code, u32 peer_capability,
19595 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019596#else
19597static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
19598 u8 *peer, u8 action_code, u8 dialog_token,
19599 u16 status_code, const u8 *buf, size_t len)
19600#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019601#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019602{
19603 int ret;
19604
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019605 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019606#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019607 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
19608 dialog_token, status_code,
19609 peer_capability, buf, len);
19610#else /* TDLS_MGMT_VERSION2 */
19611#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
19612 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
19613 dialog_token, status_code,
19614 peer_capability, initiator,
19615 buf, len);
19616#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
19617 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
19618 dialog_token, status_code,
19619 peer_capability, buf, len);
19620#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
19621 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
19622 dialog_token, status_code,
19623 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019624#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019625 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
19626 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019627#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019628#endif
19629 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019630
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019631 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019632}
Atul Mittal115287b2014-07-08 13:26:33 +053019633
19634int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019635#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19636 const u8 *peer,
19637#else
Atul Mittal115287b2014-07-08 13:26:33 +053019638 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019639#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019640 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053019641 cfg80211_exttdls_callback callback)
19642{
19643
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019644 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053019645 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053019646 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053019647 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19648 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
19649 __func__, MAC_ADDR_ARRAY(peer));
19650
19651 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
19652 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
19653
19654 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019655 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
19656 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
19657 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053019658 return -ENOTSUPP;
19659 }
19660
19661 /* To cater the requirement of establishing the TDLS link
19662 * irrespective of the data traffic , get an entry of TDLS peer.
19663 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053019664 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019665 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
19666 if (pTdlsPeer == NULL) {
19667 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19668 "%s: peer " MAC_ADDRESS_STR " not existing",
19669 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053019670 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019671 return -EINVAL;
19672 }
19673
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053019674 /* check FW TDLS Off Channel capability */
19675 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053019676 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053019677 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019678 {
19679 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
19680 pTdlsPeer->peerParams.global_operating_class =
19681 tdls_peer_params->global_operating_class;
19682 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
19683 pTdlsPeer->peerParams.min_bandwidth_kbps =
19684 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053019685 /* check configured channel is valid, non dfs and
19686 * not current operating channel */
19687 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
19688 tdls_peer_params->channel)) &&
19689 (pHddStaCtx) &&
19690 (tdls_peer_params->channel !=
19691 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019692 {
19693 pTdlsPeer->isOffChannelConfigured = TRUE;
19694 }
19695 else
19696 {
19697 pTdlsPeer->isOffChannelConfigured = FALSE;
19698 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19699 "%s: Configured Tdls Off Channel is not valid", __func__);
19700
19701 }
19702 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053019703 "%s: tdls_off_channel %d isOffChannelConfigured %d "
19704 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019705 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053019706 pTdlsPeer->isOffChannelConfigured,
19707 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019708 }
19709 else
19710 {
19711 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053019712 "%s: TDLS off channel FW capability %d, "
19713 "host capab %d or Invalid TDLS Peer Params", __func__,
19714 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
19715 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019716 }
19717
Atul Mittal115287b2014-07-08 13:26:33 +053019718 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
19719
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019720 mutex_unlock(&pHddCtx->tdls_lock);
19721
Atul Mittal115287b2014-07-08 13:26:33 +053019722 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19723 " %s TDLS Add Force Peer Failed",
19724 __func__);
19725 return -EINVAL;
19726 }
19727 /*EXT TDLS*/
19728
19729 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019730 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019731 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19732 " %s TDLS set callback Failed",
19733 __func__);
19734 return -EINVAL;
19735 }
19736
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019737 mutex_unlock(&pHddCtx->tdls_lock);
19738
Atul Mittal115287b2014-07-08 13:26:33 +053019739 return(0);
19740
19741}
19742
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019743int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
19744#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19745 const u8 *peer
19746#else
19747 u8 *peer
19748#endif
19749)
Atul Mittal115287b2014-07-08 13:26:33 +053019750{
19751
19752 hddTdlsPeer_t *pTdlsPeer;
19753 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053019754
Atul Mittal115287b2014-07-08 13:26:33 +053019755 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19756 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
19757 __func__, MAC_ADDR_ARRAY(peer));
19758
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053019759 if (0 != wlan_hdd_validate_context(pHddCtx)) {
19760 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
19761 return -EINVAL;
19762 }
19763
Atul Mittal115287b2014-07-08 13:26:33 +053019764 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
19765 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
19766
19767 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019768 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
19769 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
19770 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053019771 return -ENOTSUPP;
19772 }
19773
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019774 mutex_lock(&pHddCtx->tdls_lock);
19775 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Atul Mittal115287b2014-07-08 13:26:33 +053019776
19777 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019778 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019779 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019780 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053019781 __func__, MAC_ADDR_ARRAY(peer));
19782 return -EINVAL;
19783 }
19784 else {
19785 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
19786 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053019787 hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_EXT_CTRL,
19788 pTdlsPeer->peerMac);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019789 /* if channel switch is configured, reset
19790 the channel for this peer */
19791 if (TRUE == pTdlsPeer->isOffChannelConfigured)
19792 {
19793 pTdlsPeer->peerParams.channel = 0;
19794 pTdlsPeer->isOffChannelConfigured = FALSE;
19795 }
Atul Mittal115287b2014-07-08 13:26:33 +053019796 }
19797
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019798 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019799 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019800 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053019801 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019802 }
Atul Mittal115287b2014-07-08 13:26:33 +053019803
19804 /*EXT TDLS*/
19805
19806 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019807 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019808 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19809 " %s TDLS set callback Failed",
19810 __func__);
19811 return -EINVAL;
19812 }
Atul Mittal115287b2014-07-08 13:26:33 +053019813
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019814 mutex_unlock(&pHddCtx->tdls_lock);
19815
19816 return(0);
Atul Mittal115287b2014-07-08 13:26:33 +053019817}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019818static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019819#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19820 const u8 *peer,
19821#else
19822 u8 *peer,
19823#endif
19824 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019825{
19826 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19827 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019828 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019829 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019830
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019831 ENTER();
19832
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053019833 if (!pAdapter) {
19834 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
19835 return -EINVAL;
19836 }
19837
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019838 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19839 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
19840 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019841 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019842 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019843 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070019844 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019845 return -EINVAL;
19846 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080019847
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019848 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019849 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080019850 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019851 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080019852 }
19853
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019854
19855 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080019856 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019857 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080019858 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019859 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
19860 "Cannot process TDLS commands",
19861 pHddCtx->cfg_ini->fEnableTDLSSupport,
19862 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019863 return -ENOTSUPP;
19864 }
19865
19866 switch (oper) {
19867 case NL80211_TDLS_ENABLE_LINK:
19868 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019869 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019870 long ret;
Hanumantha Reddy Pothulada389492016-02-11 17:29:27 +053019871 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams = { {0}, 0,
19872 0, 0, 0, 0, 0, 0, {0}, 0, {0} };
Agarwal Ashish16020c42014-12-29 22:01:11 +053019873 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019874 tANI_U16 numCurrTdlsPeers = 0;
19875 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053019876 tANI_U8 suppChannelLen = 0;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019877 tSirMacAddr peerMac;
19878 int channel;
19879 tTDLSLinkStatus peer_status = eTDLS_LINK_IDLE;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019880
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019881 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19882 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
19883 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019884
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019885 mutex_lock(&pHddCtx->tdls_lock);
19886 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053019887 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053019888 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019889 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053019890 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
19891 " (oper %d) not exsting. ignored",
19892 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
19893 return -EINVAL;
19894 }
19895
19896 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19897 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
19898 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
19899 "NL80211_TDLS_ENABLE_LINK");
19900
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070019901 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
19902 {
19903 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
19904 MAC_ADDRESS_STR " failed",
19905 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019906 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070019907 return -EINVAL;
19908 }
19909
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053019910 /* before starting tdls connection, set tdls
19911 * off channel established status to default value */
19912 pTdlsPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019913
19914 mutex_unlock(&pHddCtx->tdls_lock);
19915
Deepthi Gowri2d85bbf2016-07-25 15:43:31 +053019916 wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019917 /* TDLS Off Channel, Disable tdls channel switch,
19918 when there are more than one tdls link */
19919 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053019920 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019921 {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019922 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019923 /* get connected peer and send disable tdls off chan */
19924 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019925 if ((connPeer) &&
19926 (connPeer->isOffChannelSupported == TRUE) &&
19927 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019928 {
19929 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19930 "%s: More then one peer connected, Disable "
19931 "TDLS channel switch", __func__);
19932
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053019933 connPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019934 vos_mem_copy(peerMac, connPeer->peerMac, sizeof (tSirMacAddr));
19935 channel = connPeer->peerParams.channel;
19936
19937 mutex_unlock(&pHddCtx->tdls_lock);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019938
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019939 ret = sme_SendTdlsChanSwitchReq(
19940 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019941 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019942 peerMac,
19943 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019944 TDLS_OFF_CHANNEL_BW_OFFSET,
19945 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019946 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019947 hddLog(VOS_TRACE_LEVEL_ERROR,
19948 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019949 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019950 }
19951 else
19952 {
19953 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19954 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019955 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019956 "isOffChannelConfigured %d",
19957 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019958 (connPeer ? (connPeer->isOffChannelSupported)
19959 : -1),
19960 (connPeer ? (connPeer->isOffChannelConfigured)
19961 : -1));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019962 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019963 }
19964 }
19965
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019966 mutex_lock(&pHddCtx->tdls_lock);
19967 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
19968 if ( NULL == pTdlsPeer ) {
19969 mutex_unlock(&pHddCtx->tdls_lock);
19970 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19971 "%s: " MAC_ADDRESS_STR
19972 " (oper %d) peer got freed in other context. ignored",
19973 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
19974 return -EINVAL;
19975 }
19976 peer_status = pTdlsPeer->link_status;
19977 mutex_unlock(&pHddCtx->tdls_lock);
19978
19979 if (eTDLS_LINK_CONNECTED != peer_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019980 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019981 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053019982
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019983 if (0 != wlan_hdd_tdls_get_link_establish_params(
19984 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019985 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019986 return -EINVAL;
19987 }
19988 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053019989
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019990 ret = sme_SendTdlsLinkEstablishParams(
19991 WLAN_HDD_GET_HAL_CTX(pAdapter),
19992 pAdapter->sessionId, peer,
19993 &tdlsLinkEstablishParams);
19994 if (ret != VOS_STATUS_SUCCESS) {
19995 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
19996 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019997 /* Send TDLS peer UAPSD capabilities to the firmware and
19998 * register with the TL on after the response for this operation
19999 * is received .
20000 */
20001 ret = wait_for_completion_interruptible_timeout(
20002 &pAdapter->tdls_link_establish_req_comp,
20003 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
Masti, Narayanraddie1892a52015-12-15 15:01:01 +053020004
20005 mutex_lock(&pHddCtx->tdls_lock);
20006 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20007 if ( NULL == pTdlsPeer ) {
20008 mutex_unlock(&pHddCtx->tdls_lock);
20009 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20010 "%s %d: " MAC_ADDRESS_STR
20011 " (oper %d) peer got freed in other context. ignored",
20012 __func__, __LINE__, MAC_ADDR_ARRAY(peer),
20013 (int)oper);
20014 return -EINVAL;
20015 }
20016 peer_status = pTdlsPeer->link_status;
20017 mutex_unlock(&pHddCtx->tdls_lock);
20018
20019 if (ret <= 0 || (peer_status == eTDLS_LINK_TEARING))
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020020 {
20021 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020022 FL("Link Establish Request Failed Status %ld"),
20023 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020024 return -EINVAL;
20025 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020026 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020027
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020028 mutex_lock(&pHddCtx->tdls_lock);
20029 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20030 if ( NULL == pTdlsPeer ) {
20031 mutex_unlock(&pHddCtx->tdls_lock);
20032 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20033 "%s: " MAC_ADDRESS_STR
20034 " (oper %d) peer got freed in other context. ignored",
20035 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20036 return -EINVAL;
20037 }
20038
Atul Mittal115287b2014-07-08 13:26:33 +053020039 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
20040 eTDLS_LINK_CONNECTED,
20041 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053020042 staDesc.ucSTAId = pTdlsPeer->staId;
20043 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053020044
20045 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20046 "%s: tdlsLinkEstablishParams of peer "
20047 MAC_ADDRESS_STR "uapsdQueues: %d"
20048 "qos: %d maxSp: %d isBufSta: %d isOffChannelSupported: %d"
20049 "isResponder: %d peerstaId: %d",
20050 __func__,
20051 MAC_ADDR_ARRAY(tdlsLinkEstablishParams.peerMac),
20052 tdlsLinkEstablishParams.uapsdQueues,
20053 tdlsLinkEstablishParams.qos,
20054 tdlsLinkEstablishParams.maxSp,
20055 tdlsLinkEstablishParams.isBufSta,
20056 tdlsLinkEstablishParams.isOffChannelSupported,
20057 tdlsLinkEstablishParams.isResponder,
20058 pTdlsPeer->staId);
20059
20060 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20061 "%s: StaDesc ucSTAId: %d ucQosEnabled: %d",
20062 __func__,
20063 staDesc.ucSTAId,
20064 staDesc.ucQosEnabled);
20065
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020066 ret = WLANTL_UpdateTdlsSTAClient(
20067 pHddCtx->pvosContext,
20068 &staDesc);
20069 if (ret != VOS_STATUS_SUCCESS) {
20070 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
20071 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053020072
Gopichand Nakkala471708b2013-06-04 20:03:01 +053020073 /* Mark TDLS client Authenticated .*/
20074 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
20075 pTdlsPeer->staId,
20076 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070020077 if (VOS_STATUS_SUCCESS == status)
20078 {
Hoonki Lee14621352013-04-16 17:51:19 -070020079 if (pTdlsPeer->is_responder == 0)
20080 {
20081 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053020082 tdlsConnInfo_t *tdlsInfo;
20083
20084 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
20085
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053020086 if (!vos_timer_is_initialized(
20087 &pTdlsPeer->initiatorWaitTimeoutTimer))
20088 {
20089 /* Initialize initiator wait callback */
20090 vos_timer_init(
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053020091 &pTdlsPeer->initiatorWaitTimeoutTimer,
20092 VOS_TIMER_TYPE_SW,
20093 wlan_hdd_tdls_initiator_wait_cb,
20094 tdlsInfo);
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053020095 }
Hoonki Lee14621352013-04-16 17:51:19 -070020096 wlan_hdd_tdls_timer_restart(pAdapter,
20097 &pTdlsPeer->initiatorWaitTimeoutTimer,
20098 WAIT_TIME_TDLS_INITIATOR);
20099 /* suspend initiator TX until it receives direct packet from the
20100 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020101 ret = WLANTL_SuspendDataTx(
20102 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
20103 &staId, NULL);
20104 if (ret != VOS_STATUS_SUCCESS) {
20105 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
20106 }
Hoonki Lee14621352013-04-16 17:51:19 -070020107 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020108
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020109 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020110 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020111 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020112 suppChannelLen =
20113 tdlsLinkEstablishParams.supportedChannelsLen;
20114
20115 if ((suppChannelLen > 0) &&
20116 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
20117 {
20118 tANI_U8 suppPeerChannel = 0;
20119 int i = 0;
20120 for (i = 0U; i < suppChannelLen; i++)
20121 {
20122 suppPeerChannel =
20123 tdlsLinkEstablishParams.supportedChannels[i];
20124
20125 pTdlsPeer->isOffChannelSupported = FALSE;
20126 if (suppPeerChannel ==
20127 pTdlsPeer->peerParams.channel)
20128 {
20129 pTdlsPeer->isOffChannelSupported = TRUE;
20130 break;
20131 }
20132 }
20133 }
20134 else
20135 {
20136 pTdlsPeer->isOffChannelSupported = FALSE;
20137 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020138 }
20139 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20140 "%s: TDLS channel switch request for channel "
20141 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020142 "%d isOffChannelSupported %d", __func__,
20143 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020144 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020145 suppChannelLen,
20146 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020147
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020148 /* TDLS Off Channel, Enable tdls channel switch,
20149 when their is only one tdls link and it supports */
20150 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
20151 if ((numCurrTdlsPeers == 1) &&
20152 (TRUE == pTdlsPeer->isOffChannelSupported) &&
20153 (TRUE == pTdlsPeer->isOffChannelConfigured))
20154 {
20155 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20156 "%s: Send TDLS channel switch request for channel %d",
20157 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053020158
20159 pTdlsPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020160 vos_mem_copy(peerMac, pTdlsPeer->peerMac, sizeof (tSirMacAddr));
20161 channel = pTdlsPeer->peerParams.channel;
20162
20163 mutex_unlock(&pHddCtx->tdls_lock);
20164
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020165 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
20166 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020167 peerMac,
20168 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020169 TDLS_OFF_CHANNEL_BW_OFFSET,
20170 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020171 if (ret != VOS_STATUS_SUCCESS) {
20172 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
20173 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020174 }
20175 else
20176 {
20177 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20178 "%s: TDLS channel switch request not sent"
20179 " numCurrTdlsPeers %d "
20180 "isOffChannelSupported %d "
20181 "isOffChannelConfigured %d",
20182 __func__, numCurrTdlsPeers,
20183 pTdlsPeer->isOffChannelSupported,
20184 pTdlsPeer->isOffChannelConfigured);
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020185 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020186 }
20187
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070020188 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020189 else
20190 mutex_unlock(&pHddCtx->tdls_lock);
20191
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020192 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020193
20194 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053020195 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
20196 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020197 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053020198 int ac;
20199 uint8 ucAc[4] = { WLANTL_AC_VO,
20200 WLANTL_AC_VI,
20201 WLANTL_AC_BK,
20202 WLANTL_AC_BE };
20203 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
20204 for(ac=0; ac < 4; ac++)
20205 {
20206 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
20207 pTdlsPeer->staId, ucAc[ac],
20208 tlTid[ac], tlTid[ac], 0, 0,
20209 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020210 if (status != VOS_STATUS_SUCCESS) {
20211 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
20212 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053020213 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020214 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020215 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020216
Bhargav Shah66896792015-10-01 18:17:37 +053020217 /* stop TCP delack timer if TDLS is enable */
20218 set_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
20219 hdd_manage_delack_timer(pHddCtx);
Abhishek Singh67fa6bc2016-01-05 15:57:19 +053020220 hdd_wlan_tdls_enable_link_event(peer,
20221 pTdlsPeer->isOffChannelSupported,
20222 pTdlsPeer->isOffChannelConfigured,
20223 pTdlsPeer->isOffChannelEstablished);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020224 }
20225 break;
20226 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080020227 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020228 tANI_U16 numCurrTdlsPeers = 0;
20229 hddTdlsPeer_t *connPeer = NULL;
20230
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020231 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20232 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
20233 __func__, MAC_ADDR_ARRAY(peer));
20234
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020235 mutex_lock(&pHddCtx->tdls_lock);
20236 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020237
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020238
Sunil Dutt41de4e22013-11-14 18:09:02 +053020239 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020240 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020241 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
20242 " (oper %d) not exsting. ignored",
20243 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20244 return -EINVAL;
20245 }
20246
20247 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20248 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
20249 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
20250 "NL80211_TDLS_DISABLE_LINK");
20251
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020252 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080020253 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020254 long status;
20255
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053020256 /* set tdls off channel status to false for this peer */
20257 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053020258 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
20259 eTDLS_LINK_TEARING,
20260 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
20261 eTDLS_LINK_UNSPECIFIED:
20262 eTDLS_LINK_DROPPED_BY_REMOTE);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020263 mutex_unlock(&pHddCtx->tdls_lock);
20264
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020265 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
20266
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020267 status = sme_DeleteTdlsPeerSta(
20268 WLAN_HDD_GET_HAL_CTX(pAdapter),
20269 pAdapter->sessionId, peer );
20270 if (status != VOS_STATUS_SUCCESS) {
20271 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
20272 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020273
20274 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
20275 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020276
20277 mutex_lock(&pHddCtx->tdls_lock);
20278 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20279 if ( NULL == pTdlsPeer ) {
20280 mutex_unlock(&pHddCtx->tdls_lock);
20281 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
20282 " peer was freed in other context",
20283 __func__, MAC_ADDR_ARRAY(peer));
20284 return -EINVAL;
20285 }
20286
Atul Mittal271a7652014-09-12 13:18:22 +053020287 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053020288 eTDLS_LINK_IDLE,
20289 eTDLS_LINK_UNSPECIFIED);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020290 mutex_unlock(&pHddCtx->tdls_lock);
20291
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020292 if (status <= 0)
20293 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020294 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20295 "%s: Del station failed status %ld",
20296 __func__, status);
20297 return -EPERM;
20298 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020299
20300 /* TDLS Off Channel, Enable tdls channel switch,
20301 when their is only one tdls link and it supports */
20302 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
20303 if (numCurrTdlsPeers == 1)
20304 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020305 tSirMacAddr peerMac;
20306 int channel;
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053020307
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020308 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020309 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053020310
20311 if (connPeer == NULL) {
20312 mutex_unlock(&pHddCtx->tdls_lock);
20313 hddLog(VOS_TRACE_LEVEL_ERROR,
20314 "%s connPeer is NULL", __func__);
20315 return -EINVAL;
20316 }
20317
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020318 vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr));
20319 channel = connPeer->peerParams.channel;
20320
20321 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20322 "%s: TDLS channel switch "
20323 "isOffChannelSupported %d "
20324 "isOffChannelConfigured %d "
20325 "isOffChannelEstablished %d",
20326 __func__,
20327 (connPeer ? connPeer->isOffChannelSupported : -1),
20328 (connPeer ? connPeer->isOffChannelConfigured : -1),
20329 (connPeer ? connPeer->isOffChannelEstablished : -1));
20330
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020331 if ((connPeer) &&
20332 (connPeer->isOffChannelSupported == TRUE) &&
20333 (connPeer->isOffChannelConfigured == TRUE))
20334 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053020335 connPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020336 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020337 status = sme_SendTdlsChanSwitchReq(
20338 WLAN_HDD_GET_HAL_CTX(pAdapter),
20339 pAdapter->sessionId,
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020340 peerMac,
20341 channel,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020342 TDLS_OFF_CHANNEL_BW_OFFSET,
20343 TDLS_CHANNEL_SWITCH_ENABLE);
20344 if (status != VOS_STATUS_SUCCESS) {
20345 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
20346 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020347 }
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020348 else
20349 mutex_unlock(&pHddCtx->tdls_lock);
20350 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020351 else
20352 {
20353 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20354 "%s: TDLS channel switch request not sent "
20355 "numCurrTdlsPeers %d ",
20356 __func__, numCurrTdlsPeers);
20357 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080020358 }
20359 else
20360 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020361 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020362 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20363 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080020364 }
Bhargav Shah66896792015-10-01 18:17:37 +053020365 if (numCurrTdlsPeers == 0) {
20366 /* start TCP delack timer if TDLS is disable */
20367 clear_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
20368 hdd_manage_delack_timer(pHddCtx);
20369 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080020370 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020371 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020372 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053020373 {
Atul Mittal115287b2014-07-08 13:26:33 +053020374 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020375
Atul Mittal115287b2014-07-08 13:26:33 +053020376 if (0 != status)
20377 {
20378 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020379 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053020380 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053020381 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053020382 break;
20383 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020384 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053020385 {
Atul Mittal115287b2014-07-08 13:26:33 +053020386 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
20387 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020388 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053020389 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020390
Atul Mittal115287b2014-07-08 13:26:33 +053020391 if (0 != status)
20392 {
20393 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020394 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053020395 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053020396 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053020397 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053020398 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020399 case NL80211_TDLS_DISCOVERY_REQ:
20400 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020401 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020402 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020403 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020404 return -ENOTSUPP;
20405 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020406 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20407 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020408 return -ENOTSUPP;
20409 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020410
20411 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020412 return 0;
20413}
Chilam NG571c65a2013-01-19 12:27:36 +053020414
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020415static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020416#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20417 const u8 *peer,
20418#else
20419 u8 *peer,
20420#endif
20421 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020422{
20423 int ret;
20424
20425 vos_ssr_protect(__func__);
20426 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
20427 vos_ssr_unprotect(__func__);
20428
20429 return ret;
20430}
20431
Chilam NG571c65a2013-01-19 12:27:36 +053020432int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
20433 struct net_device *dev, u8 *peer)
20434{
Arif Hussaina7c8e412013-11-20 11:06:42 -080020435 hddLog(VOS_TRACE_LEVEL_INFO,
20436 "tdls send discover req: "MAC_ADDRESS_STR,
20437 MAC_ADDR_ARRAY(peer));
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020438#if TDLS_MGMT_VERSION2
20439 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20440 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
20441#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020442#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
20443 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20444 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
20445#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
20446 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20447 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
20448#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
20449 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20450 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
20451#else
Chilam NG571c65a2013-01-19 12:27:36 +053020452 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20453 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020454#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020455#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053020456}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020457#endif
20458
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020459#ifdef WLAN_FEATURE_GTK_OFFLOAD
20460/*
20461 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
20462 * Callback rountine called upon receiving response for
20463 * get offload info
20464 */
20465void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
20466 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
20467{
20468
20469 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020470 tANI_U8 tempReplayCounter[8];
20471 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020472
20473 ENTER();
20474
20475 if (NULL == pAdapter)
20476 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053020477 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020478 "%s: HDD adapter is Null", __func__);
20479 return ;
20480 }
20481
20482 if (NULL == pGtkOffloadGetInfoRsp)
20483 {
20484 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20485 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
20486 return ;
20487 }
20488
20489 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
20490 {
20491 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20492 "%s: wlan Failed to get replay counter value",
20493 __func__);
20494 return ;
20495 }
20496
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020497 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
20498 /* Update replay counter */
20499 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
20500 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
20501
20502 {
20503 /* changing from little to big endian since supplicant
20504 * works on big endian format
20505 */
20506 int i;
20507 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
20508
20509 for (i = 0; i < 8; i++)
20510 {
20511 tempReplayCounter[7-i] = (tANI_U8)p[i];
20512 }
20513 }
20514
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020515 /* Update replay counter to NL */
20516 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020517 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020518}
20519
20520/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020521 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020522 * This function is used to offload GTK rekeying job to the firmware.
20523 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020524int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020525 struct cfg80211_gtk_rekey_data *data)
20526{
20527 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20528 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
20529 hdd_station_ctx_t *pHddStaCtx;
20530 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020531 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020532 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020533 eHalStatus status = eHAL_STATUS_FAILURE;
20534
20535 ENTER();
20536
20537 if (NULL == pAdapter)
20538 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053020539 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020540 "%s: HDD adapter is Null", __func__);
20541 return -ENODEV;
20542 }
20543
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053020544 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20545 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
20546 pAdapter->sessionId, pAdapter->device_mode));
20547
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020548 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020549 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020550 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020551 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020552 }
20553
20554 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
20555 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
20556 if (NULL == hHal)
20557 {
20558 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20559 "%s: HAL context is Null!!!", __func__);
20560 return -EAGAIN;
20561 }
20562
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020563 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
20564 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
20565 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
20566 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020567 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020568 {
20569 /* changing from big to little endian since driver
20570 * works on little endian format
20571 */
20572 tANI_U8 *p =
20573 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
20574 int i;
20575
20576 for (i = 0; i < 8; i++)
20577 {
20578 p[7-i] = data->replay_ctr[i];
20579 }
20580 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020581
20582 if (TRUE == pHddCtx->hdd_wlan_suspended)
20583 {
20584 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020585 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
20586 sizeof (tSirGtkOffloadParams));
20587 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020588 pAdapter->sessionId);
20589
20590 if (eHAL_STATUS_SUCCESS != status)
20591 {
20592 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20593 "%s: sme_SetGTKOffload failed, returned %d",
20594 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053020595
20596 /* Need to clear any trace of key value in the memory.
20597 * Thus zero out the memory even though it is local
20598 * variable.
20599 */
20600 vos_mem_zero(&hddGtkOffloadReqParams,
20601 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020602 return status;
20603 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020604 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20605 "%s: sme_SetGTKOffload successfull", __func__);
20606 }
20607 else
20608 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020609 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20610 "%s: wlan not suspended GTKOffload request is stored",
20611 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020612 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020613
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053020614 /* Need to clear any trace of key value in the memory.
20615 * Thus zero out the memory even though it is local
20616 * variable.
20617 */
20618 vos_mem_zero(&hddGtkOffloadReqParams,
20619 sizeof(hddGtkOffloadReqParams));
20620
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020621 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020622 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020623}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020624
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020625int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
20626 struct cfg80211_gtk_rekey_data *data)
20627{
20628 int ret;
20629
20630 vos_ssr_protect(__func__);
20631 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
20632 vos_ssr_unprotect(__func__);
20633
20634 return ret;
20635}
20636#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020637/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020638 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020639 * This function is used to set access control policy
20640 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020641static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
20642 struct net_device *dev,
20643 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020644{
20645 int i;
20646 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20647 hdd_hostapd_state_t *pHostapdState;
20648 tsap_Config_t *pConfig;
20649 v_CONTEXT_t pVosContext = NULL;
20650 hdd_context_t *pHddCtx;
20651 int status;
20652
20653 ENTER();
20654
20655 if (NULL == pAdapter)
20656 {
20657 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20658 "%s: HDD adapter is Null", __func__);
20659 return -ENODEV;
20660 }
20661
20662 if (NULL == params)
20663 {
20664 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20665 "%s: params is Null", __func__);
20666 return -EINVAL;
20667 }
20668
20669 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
20670 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020671 if (0 != status)
20672 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020673 return status;
20674 }
20675
20676 pVosContext = pHddCtx->pvosContext;
20677 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
20678
20679 if (NULL == pHostapdState)
20680 {
20681 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20682 "%s: pHostapdState is Null", __func__);
20683 return -EINVAL;
20684 }
20685
20686 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
20687 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053020688 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20689 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
20690 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020691
20692 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
20693 {
20694 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
20695
20696 /* default value */
20697 pConfig->num_accept_mac = 0;
20698 pConfig->num_deny_mac = 0;
20699
20700 /**
20701 * access control policy
20702 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
20703 * listed in hostapd.deny file.
20704 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
20705 * listed in hostapd.accept file.
20706 */
20707 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
20708 {
20709 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
20710 }
20711 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
20712 {
20713 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
20714 }
20715 else
20716 {
20717 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20718 "%s:Acl Policy : %d is not supported",
20719 __func__, params->acl_policy);
20720 return -ENOTSUPP;
20721 }
20722
20723 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
20724 {
20725 pConfig->num_accept_mac = params->n_acl_entries;
20726 for (i = 0; i < params->n_acl_entries; i++)
20727 {
20728 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20729 "** Add ACL MAC entry %i in WhiletList :"
20730 MAC_ADDRESS_STR, i,
20731 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
20732
20733 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
20734 sizeof(qcmacaddr));
20735 }
20736 }
20737 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
20738 {
20739 pConfig->num_deny_mac = params->n_acl_entries;
20740 for (i = 0; i < params->n_acl_entries; i++)
20741 {
20742 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20743 "** Add ACL MAC entry %i in BlackList :"
20744 MAC_ADDRESS_STR, i,
20745 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
20746
20747 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
20748 sizeof(qcmacaddr));
20749 }
20750 }
20751
20752 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
20753 {
20754 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20755 "%s: SAP Set Mac Acl fail", __func__);
20756 return -EINVAL;
20757 }
20758 }
20759 else
20760 {
20761 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053020762 "%s: Invalid device_mode = %s (%d)",
20763 __func__, hdd_device_modetoString(pAdapter->device_mode),
20764 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020765 return -EINVAL;
20766 }
20767
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020768 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020769 return 0;
20770}
20771
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020772static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
20773 struct net_device *dev,
20774 const struct cfg80211_acl_data *params)
20775{
20776 int ret;
20777 vos_ssr_protect(__func__);
20778 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
20779 vos_ssr_unprotect(__func__);
20780
20781 return ret;
20782}
20783
Leo Chang9056f462013-08-01 19:21:11 -070020784#ifdef WLAN_NL80211_TESTMODE
20785#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070020786void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070020787(
20788 void *pAdapter,
20789 void *indCont
20790)
20791{
Leo Changd9df8aa2013-09-26 13:32:26 -070020792 tSirLPHBInd *lphbInd;
20793 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053020794 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070020795
20796 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070020797 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070020798
c_hpothu73f35e62014-04-18 13:40:08 +053020799 if (pAdapter == NULL)
20800 {
20801 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20802 "%s: pAdapter is NULL\n",__func__);
20803 return;
20804 }
20805
Leo Chang9056f462013-08-01 19:21:11 -070020806 if (NULL == indCont)
20807 {
20808 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070020809 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070020810 return;
20811 }
20812
c_hpothu73f35e62014-04-18 13:40:08 +053020813 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070020814 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070020815 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053020816 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070020817 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070020818 GFP_ATOMIC);
20819 if (!skb)
20820 {
20821 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20822 "LPHB timeout, NL buffer alloc fail");
20823 return;
20824 }
20825
Leo Changac3ba772013-10-07 09:47:04 -070020826 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070020827 {
20828 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20829 "WLAN_HDD_TM_ATTR_CMD put fail");
20830 goto nla_put_failure;
20831 }
Leo Changac3ba772013-10-07 09:47:04 -070020832 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070020833 {
20834 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20835 "WLAN_HDD_TM_ATTR_TYPE put fail");
20836 goto nla_put_failure;
20837 }
Leo Changac3ba772013-10-07 09:47:04 -070020838 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070020839 sizeof(tSirLPHBInd), lphbInd))
20840 {
20841 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20842 "WLAN_HDD_TM_ATTR_DATA put fail");
20843 goto nla_put_failure;
20844 }
Leo Chang9056f462013-08-01 19:21:11 -070020845 cfg80211_testmode_event(skb, GFP_ATOMIC);
20846 return;
20847
20848nla_put_failure:
20849 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20850 "NLA Put fail");
20851 kfree_skb(skb);
20852
20853 return;
20854}
20855#endif /* FEATURE_WLAN_LPHB */
20856
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020857static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070020858{
20859 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
20860 int err = 0;
20861#ifdef FEATURE_WLAN_LPHB
20862 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070020863 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020864
20865 ENTER();
20866
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053020867 err = wlan_hdd_validate_context(pHddCtx);
20868 if (0 != err)
20869 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053020870 return err;
20871 }
Leo Chang9056f462013-08-01 19:21:11 -070020872#endif /* FEATURE_WLAN_LPHB */
20873
20874 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
20875 if (err)
20876 {
20877 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20878 "%s Testmode INV ATTR", __func__);
20879 return err;
20880 }
20881
20882 if (!tb[WLAN_HDD_TM_ATTR_CMD])
20883 {
20884 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20885 "%s Testmode INV CMD", __func__);
20886 return -EINVAL;
20887 }
20888
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053020889 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20890 TRACE_CODE_HDD_CFG80211_TESTMODE,
20891 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070020892 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
20893 {
20894#ifdef FEATURE_WLAN_LPHB
20895 /* Low Power Heartbeat configuration request */
20896 case WLAN_HDD_TM_CMD_WLAN_HB:
20897 {
20898 int buf_len;
20899 void *buf;
20900 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080020901 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070020902
20903 if (!tb[WLAN_HDD_TM_ATTR_DATA])
20904 {
20905 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20906 "%s Testmode INV DATA", __func__);
20907 return -EINVAL;
20908 }
20909
20910 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
20911 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080020912
Manjeet Singh3c577442017-02-10 19:03:38 +053020913 if (buf_len > sizeof(*hb_params)) {
20914 hddLog(LOGE, FL("buf_len=%d exceeded hb_params size limit"),
20915 buf_len);
20916 return -ERANGE;
20917 }
20918
Amar Singhal05852702014-02-04 14:40:00 -080020919 hb_params_temp =(tSirLPHBReq *)buf;
20920 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
20921 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
20922 return -EINVAL;
20923
Leo Chang9056f462013-08-01 19:21:11 -070020924 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
20925 if (NULL == hb_params)
20926 {
20927 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20928 "%s Request Buffer Alloc Fail", __func__);
20929 return -EINVAL;
20930 }
20931
Ashish Kumar Dhanotiya3a8c0a72017-07-13 18:58:59 +053020932 vos_mem_zero(hb_params, sizeof(tSirLPHBReq));
Leo Chang9056f462013-08-01 19:21:11 -070020933 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070020934 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
20935 hb_params,
20936 wlan_hdd_cfg80211_lphb_ind_handler);
20937 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070020938 {
Leo Changd9df8aa2013-09-26 13:32:26 -070020939 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20940 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070020941 vos_mem_free(hb_params);
20942 }
Leo Chang9056f462013-08-01 19:21:11 -070020943 return 0;
20944 }
20945#endif /* FEATURE_WLAN_LPHB */
20946 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020947 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20948 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070020949 return -EOPNOTSUPP;
20950 }
20951
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020952 EXIT();
20953 return err;
Leo Chang9056f462013-08-01 19:21:11 -070020954}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020955
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053020956static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
20957#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
20958 struct wireless_dev *wdev,
20959#endif
20960 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020961{
20962 int ret;
20963
20964 vos_ssr_protect(__func__);
20965 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
20966 vos_ssr_unprotect(__func__);
20967
20968 return ret;
20969}
Leo Chang9056f462013-08-01 19:21:11 -070020970#endif /* CONFIG_NL80211_TESTMODE */
20971
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053020972extern void hdd_set_wlan_suspend_mode(bool suspend);
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020973static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020974 struct net_device *dev,
20975 int idx, struct survey_info *survey)
20976{
20977 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20978 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053020979 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020980 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053020981 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020982 v_S7_t snr,rssi;
20983 int status, i, j, filled = 0;
20984
20985 ENTER();
20986
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020987 if (NULL == pAdapter)
20988 {
20989 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20990 "%s: HDD adapter is Null", __func__);
20991 return -ENODEV;
20992 }
20993
20994 if (NULL == wiphy)
20995 {
20996 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20997 "%s: wiphy is Null", __func__);
20998 return -ENODEV;
20999 }
21000
21001 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
21002 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021003 if (0 != status)
21004 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021005 return status;
21006 }
21007
Mihir Sheted9072e02013-08-21 17:02:29 +053021008 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
21009
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021010 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053021011 0 != pAdapter->survey_idx ||
21012 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021013 {
21014 /* The survey dump ops when implemented completely is expected to
21015 * return a survey of all channels and the ops is called by the
21016 * kernel with incremental values of the argument 'idx' till it
21017 * returns -ENONET. But we can only support the survey for the
21018 * operating channel for now. survey_idx is used to track
21019 * that the ops is called only once and then return -ENONET for
21020 * the next iteration
21021 */
21022 pAdapter->survey_idx = 0;
21023 return -ENONET;
21024 }
21025
Mukul Sharma9d5233b2015-06-11 20:28:20 +053021026 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
21027 {
21028 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21029 "%s: Roaming in progress, hence return ", __func__);
21030 return -ENONET;
21031 }
21032
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021033 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
21034
21035 wlan_hdd_get_snr(pAdapter, &snr);
21036 wlan_hdd_get_rssi(pAdapter, &rssi);
21037
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021038 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21039 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
21040 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021041 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
21042 hdd_wlan_get_freq(channel, &freq);
21043
21044
21045 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
21046 {
21047 if (NULL == wiphy->bands[i])
21048 {
21049 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
21050 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
21051 continue;
21052 }
21053
21054 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
21055 {
21056 struct ieee80211_supported_band *band = wiphy->bands[i];
21057
21058 if (band->channels[j].center_freq == (v_U16_t)freq)
21059 {
21060 survey->channel = &band->channels[j];
21061 /* The Rx BDs contain SNR values in dB for the received frames
21062 * while the supplicant expects noise. So we calculate and
21063 * return the value of noise (dBm)
21064 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
21065 */
21066 survey->noise = rssi - snr;
21067 survey->filled = SURVEY_INFO_NOISE_DBM;
21068 filled = 1;
21069 }
21070 }
21071 }
21072
21073 if (filled)
21074 pAdapter->survey_idx = 1;
21075 else
21076 {
21077 pAdapter->survey_idx = 0;
21078 return -ENONET;
21079 }
21080
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021081 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021082 return 0;
21083}
21084
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021085static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
21086 struct net_device *dev,
21087 int idx, struct survey_info *survey)
21088{
21089 int ret;
21090
21091 vos_ssr_protect(__func__);
21092 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
21093 vos_ssr_unprotect(__func__);
21094
21095 return ret;
21096}
21097
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021098/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021099 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021100 * this is called when cfg80211 driver resume
21101 * driver updates latest sched_scan scan result(if any) to cfg80211 database
21102 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021103int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021104{
21105 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
21106 hdd_adapter_t *pAdapter;
21107 hdd_adapter_list_node_t *pAdapterNode, *pNext;
21108 VOS_STATUS status = VOS_STATUS_SUCCESS;
21109
21110 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021111
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053021112 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021113 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021114 return 0;
21115 }
21116
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021117 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
21118 NO_SESSION, pHddCtx->isWiphySuspended));
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021119
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053021120 if (pHddCtx->is_ap_mode_wow_supported)
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021121 {
21122 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21123 "%s: Resume SoftAP", __func__);
21124 hdd_set_wlan_suspend_mode(false);
21125 }
21126
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021127 spin_lock(&pHddCtx->schedScan_lock);
21128 pHddCtx->isWiphySuspended = FALSE;
21129 if (TRUE != pHddCtx->isSchedScanUpdatePending)
21130 {
21131 spin_unlock(&pHddCtx->schedScan_lock);
21132 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21133 "%s: Return resume is not due to PNO indication", __func__);
21134 return 0;
21135 }
21136 // Reset flag to avoid updatating cfg80211 data old results again
21137 pHddCtx->isSchedScanUpdatePending = FALSE;
21138 spin_unlock(&pHddCtx->schedScan_lock);
21139
21140 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
21141
21142 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
21143 {
21144 pAdapter = pAdapterNode->pAdapter;
21145 if ( (NULL != pAdapter) &&
21146 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
21147 {
21148 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021149 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021150 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
21151 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021152 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021153 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021154 {
21155 /* Acquire wakelock to handle the case where APP's tries to
21156 * suspend immediately after updating the scan results. Whis
21157 * results in app's is in suspended state and not able to
21158 * process the connect request to AP
21159 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053021160 hdd_prevent_suspend_timeout(2000,
21161 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021162 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021163 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021164
21165 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21166 "%s : cfg80211 scan result database updated", __func__);
21167
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021168 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021169 return 0;
21170
21171 }
21172 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
21173 pAdapterNode = pNext;
21174 }
21175
21176 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21177 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021178 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021179 return 0;
21180}
21181
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021182int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
21183{
21184 int ret;
21185
21186 vos_ssr_protect(__func__);
21187 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
21188 vos_ssr_unprotect(__func__);
21189
21190 return ret;
21191}
21192
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021193/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021194 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021195 * this is called when cfg80211 driver suspends
21196 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021197int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021198 struct cfg80211_wowlan *wow)
21199{
21200 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021201 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021202
21203 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021204
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021205 ret = wlan_hdd_validate_context(pHddCtx);
21206 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021207 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021208 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021209 }
21210
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053021211 if (pHddCtx->is_ap_mode_wow_supported) {
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021212 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21213 "%s: Suspend SoftAP", __func__);
21214 hdd_set_wlan_suspend_mode(true);
21215 }
21216
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021217
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021218 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21219 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
21220 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021221 pHddCtx->isWiphySuspended = TRUE;
21222
21223 EXIT();
21224
21225 return 0;
21226}
21227
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021228int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
21229 struct cfg80211_wowlan *wow)
21230{
21231 int ret;
21232
21233 vos_ssr_protect(__func__);
21234 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
21235 vos_ssr_unprotect(__func__);
21236
21237 return ret;
21238}
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021239
21240#ifdef FEATURE_OEM_DATA_SUPPORT
21241static void wlan_hdd_cfg80211_oem_data_rsp_ind_new(void *ctx,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021242 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021243{
21244 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
21245
21246 ENTER();
21247
21248 if (wlan_hdd_validate_context(pHddCtx)) {
21249 return;
21250 }
21251 if (!pMsg)
21252 {
21253 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
21254 return;
21255 }
21256
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021257 send_oem_data_rsp_msg(evLen, pMsg);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021258
21259 EXIT();
21260 return;
21261
21262}
21263
21264void wlan_hdd_cfg80211_oemdata_callback(void *ctx, const tANI_U16 evType,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021265 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021266{
21267 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
21268
21269 ENTER();
21270
21271 if (wlan_hdd_validate_context(pHddCtx)) {
21272 return;
21273 }
21274
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021275 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d) evLen %d"), evType, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021276
21277 switch(evType) {
21278 case SIR_HAL_START_OEM_DATA_RSP_IND_NEW:
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021279 wlan_hdd_cfg80211_oem_data_rsp_ind_new(ctx, pMsg, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021280 break;
21281 default:
21282 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
21283 break;
21284 }
21285 EXIT();
21286}
21287#endif
21288
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053021289#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
21290 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053021291/**
21292 * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api
21293 * @wiphy: Pointer to wiphy
21294 * @wdev: Pointer to wireless device structure
21295 *
21296 * This function is used to abort an ongoing scan
21297 *
21298 * Return: None
21299 */
21300static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
21301 struct wireless_dev *wdev)
21302{
21303 struct net_device *dev = wdev->netdev;
21304 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
21305 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
21306 int ret;
21307
21308 ENTER();
21309
21310 if (NULL == adapter) {
21311 hddLog(VOS_TRACE_LEVEL_FATAL, FL("HDD adapter is NULL"));
21312 return;
21313 }
21314
21315 ret = wlan_hdd_validate_context(hdd_ctx);
21316 if (0 != ret)
21317 return;
21318
21319 wlan_hdd_scan_abort(adapter);
21320
21321 return;
21322}
21323
21324/**
21325 * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api
21326 * @wiphy: Pointer to wiphy
21327 * @wdev: Pointer to wireless device structure
21328 *
21329 * Return: None
21330 */
21331void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
21332 struct wireless_dev *wdev)
21333{
21334 vos_ssr_protect(__func__);
21335 __wlan_hdd_cfg80211_abort_scan(wiphy, wdev);
21336 vos_ssr_unprotect(__func__);
21337
21338 return;
21339}
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053021340#endif
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053021341
Abhishek Singh936c6932017-11-07 17:28:23 +053021342#ifdef CHANNEL_SWITCH_SUPPORTED
21343/**
21344 * __wlan_hdd_cfg80211_channel_switch()- function to switch
21345 * channel in SAP/GO
21346 * @wiphy: wiphy pointer
21347 * @dev: dev pointer.
21348 * @csa_params: Change channel params
21349 *
21350 * This function is called to switch channel in SAP/GO
21351 *
21352 * Return: 0 if success else return non zero
21353 */
21354static int __wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
21355 struct net_device *dev, struct cfg80211_csa_settings *csa_params)
21356{
21357 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
21358 hdd_context_t *hdd_ctx;
21359 uint8_t channel;
21360 int ret;
21361 v_CONTEXT_t vos_ctx;
21362
21363 hddLog(LOGE, FL("Set Freq %d"), csa_params->chandef.chan->center_freq);
21364
21365 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
21366 ret = wlan_hdd_validate_context(hdd_ctx);
21367 if (ret)
21368 return ret;
21369
21370 vos_ctx = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
21371 if (!vos_ctx) {
21372 hddLog(LOGE, FL("Vos ctx is null"));
21373 return -EINVAL;
21374 }
21375
21376 if ((WLAN_HDD_SOFTAP != adapter->device_mode) &&
21377 (WLAN_HDD_P2P_GO != adapter->device_mode))
21378 return -ENOTSUPP;
21379
21380 channel = vos_freq_to_chan(csa_params->chandef.chan->center_freq);
Abhishek Singhceb6fe22017-11-27 13:53:18 +053021381 ret = wlansap_set_channel_change(vos_ctx, channel, false);
Abhishek Singh936c6932017-11-07 17:28:23 +053021382
21383 return ret;
21384}
21385
21386/**
21387 * wlan_hdd_cfg80211_channel_switch()- function to switch
21388 * channel in SAP/GO
21389 * @wiphy: wiphy pointer
21390 * @dev: dev pointer.
21391 * @csa_params: Change channel params
21392 *
21393 * This function is called to switch channel in SAP/GO
21394 *
21395 * Return: 0 if success else return non zero
21396 */
21397static int wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
21398 struct net_device *dev, struct cfg80211_csa_settings *csa_params)
21399{
21400 int ret;
21401
21402 vos_ssr_protect(__func__);
21403 ret = __wlan_hdd_cfg80211_channel_switch(wiphy, dev, csa_params);
21404 vos_ssr_unprotect(__func__);
21405
21406 return ret;
21407}
21408#endif
21409
Jeff Johnson295189b2012-06-20 16:38:30 -070021410/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053021411static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070021412{
21413 .add_virtual_intf = wlan_hdd_add_virtual_intf,
21414 .del_virtual_intf = wlan_hdd_del_virtual_intf,
21415 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
21416 .change_station = wlan_hdd_change_station,
21417#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
21418 .add_beacon = wlan_hdd_cfg80211_add_beacon,
21419 .del_beacon = wlan_hdd_cfg80211_del_beacon,
21420 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070021421#else
21422 .start_ap = wlan_hdd_cfg80211_start_ap,
21423 .change_beacon = wlan_hdd_cfg80211_change_beacon,
21424 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070021425#endif
21426 .change_bss = wlan_hdd_cfg80211_change_bss,
21427 .add_key = wlan_hdd_cfg80211_add_key,
21428 .get_key = wlan_hdd_cfg80211_get_key,
21429 .del_key = wlan_hdd_cfg80211_del_key,
21430 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080021431#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070021432 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080021433#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070021434 .scan = wlan_hdd_cfg80211_scan,
21435 .connect = wlan_hdd_cfg80211_connect,
21436 .disconnect = wlan_hdd_cfg80211_disconnect,
21437 .join_ibss = wlan_hdd_cfg80211_join_ibss,
21438 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
21439 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
21440 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
21441 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070021442 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
21443 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053021444 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070021445#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
21446 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
21447 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
21448 .set_txq_params = wlan_hdd_set_txq_params,
21449#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070021450 .get_station = wlan_hdd_cfg80211_get_station,
21451 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
21452 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070021453 .add_station = wlan_hdd_cfg80211_add_station,
21454#ifdef FEATURE_WLAN_LFR
21455 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
21456 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
21457 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
21458#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070021459#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
21460 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
21461#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021462#ifdef FEATURE_WLAN_TDLS
21463 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
21464 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
21465#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021466#ifdef WLAN_FEATURE_GTK_OFFLOAD
21467 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
21468#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053021469#ifdef FEATURE_WLAN_SCAN_PNO
21470 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
21471 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
21472#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021473 .resume = wlan_hdd_cfg80211_resume_wlan,
21474 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021475 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070021476#ifdef WLAN_NL80211_TESTMODE
21477 .testmode_cmd = wlan_hdd_cfg80211_testmode,
21478#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021479 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053021480#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
21481 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053021482 .abort_scan = wlan_hdd_cfg80211_abort_scan,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053021483#endif
Abhishek Singh936c6932017-11-07 17:28:23 +053021484#ifdef CHANNEL_SWITCH_SUPPORTED
21485 .channel_switch = wlan_hdd_cfg80211_channel_switch,
21486#endif
21487
Jeff Johnson295189b2012-06-20 16:38:30 -070021488};
21489