blob: aa54a44f0c98b2c5c47dc766b0a49e0b1f561366 [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
Jeff Johnson295189b2012-06-20 16:38:30 -070010263#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10264static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
10265 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010266#else
10267static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
10268 struct cfg80211_beacon_data *params,
10269 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010270 enum nl80211_hidden_ssid hidden_ssid,
10271 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010272#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010273{
10274 tsap_Config_t *pConfig;
10275 beacon_data_t *pBeacon = NULL;
10276 struct ieee80211_mgmt *pMgmt_frame;
10277 v_U8_t *pIe=NULL;
10278 v_U16_t capab_info;
10279 eCsrAuthType RSNAuthType;
10280 eCsrEncryptionType RSNEncryptType;
10281 eCsrEncryptionType mcRSNEncryptType;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010282 int status = VOS_STATUS_SUCCESS, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010283 tpWLAN_SAPEventCB pSapEventCallback;
10284 hdd_hostapd_state_t *pHostapdState;
Jeff Johnson295189b2012-06-20 16:38:30 -070010285 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010286 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010287 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010288 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -070010289 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -080010290 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +053010291 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -070010292 v_BOOL_t MFPCapable = VOS_FALSE;
10293 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +053010294 v_BOOL_t sapEnable11AC =
10295 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Kapil Gupta137ef892016-12-13 19:38:00 +053010296 u_int16_t prev_rsn_length = 0;
10297
Jeff Johnson295189b2012-06-20 16:38:30 -070010298 ENTER();
10299
Nitesh Shah9b066282017-06-06 18:05:52 +053010300 wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010301 iniConfig = pHddCtx->cfg_ini;
10302
Jeff Johnson295189b2012-06-20 16:38:30 -070010303 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
10304
10305 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
10306
10307 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
10308
10309 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
10310
10311 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
10312
10313 //channel is already set in the set_channel Call back
10314 //pConfig->channel = pCommitConfig->channel;
10315
10316 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010317 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -070010318 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
10319
10320 pConfig->dtim_period = pBeacon->dtim_period;
10321
Arif Hussain6d2a3322013-11-17 19:50:10 -080010322 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -070010323 pConfig->dtim_period);
10324
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -080010325 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -070010326 {
10327 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070010328 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +053010329 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
10330 {
10331 tANI_BOOLEAN restartNeeded;
10332 pConfig->ieee80211d = 1;
10333 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
10334 sme_setRegInfo(hHal, pConfig->countryCode);
10335 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
10336 }
10337 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -070010338 {
Jeff Johnson32d95a32012-09-10 13:15:23 -070010339 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -070010340 pConfig->ieee80211d = 1;
10341 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
10342 sme_setRegInfo(hHal, pConfig->countryCode);
10343 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -070010344 }
Jeff Johnson32d95a32012-09-10 13:15:23 -070010345 else
10346 {
10347 pConfig->ieee80211d = 0;
10348 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010349 /*
10350 * If auto channel is configured i.e. channel is 0,
10351 * so skip channel validation.
10352 */
10353 if( AUTO_CHANNEL_SELECT != pConfig->channel )
10354 {
10355 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
10356 {
10357 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010358 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010359 return -EINVAL;
10360 }
10361 }
10362 else
10363 {
10364 if(1 != pHddCtx->is_dynamic_channel_range_set)
10365 {
10366 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
10367 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
10368 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
10369 }
10370 pHddCtx->is_dynamic_channel_range_set = 0;
10371 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010372 }
Jeff Johnson32d95a32012-09-10 13:15:23 -070010373 else
Jeff Johnson295189b2012-06-20 16:38:30 -070010374 {
10375 pConfig->ieee80211d = 0;
10376 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010377
10378#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10379 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
10380 pConfig->authType = eSAP_OPEN_SYSTEM;
10381 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
10382 pConfig->authType = eSAP_SHARED_KEY;
10383 else
10384 pConfig->authType = eSAP_AUTO_SWITCH;
10385#else
10386 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
10387 pConfig->authType = eSAP_OPEN_SYSTEM;
10388 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
10389 pConfig->authType = eSAP_SHARED_KEY;
10390 else
10391 pConfig->authType = eSAP_AUTO_SWITCH;
10392#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010393
10394 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010395
10396 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -070010397 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
Agrawal Ashisha8e8a722016-10-18 19:07:45 +053010398#ifdef SAP_AUTH_OFFLOAD
10399 /* In case of sap offload, hostapd.conf is configuted with open mode and
10400 * security is configured from ini file. Due to open mode in hostapd.conf
10401 * privacy bit is set to false which will result in not sending,
10402 * data packets as encrypted.
10403 * If enable_sap_auth_offload is enabled in ini and
10404 * sap_auth_offload_sec_type is type of WPA2-PSK,
10405 * driver will set privacy bit to 1.
10406 */
10407 if (pHddCtx->cfg_ini->enable_sap_auth_offload &&
10408 pHddCtx->cfg_ini->sap_auth_offload_sec_type)
10409 pConfig->privacy = VOS_TRUE;
10410#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010411
10412 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
10413
10414 /*Set wps station to configured*/
10415 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
10416
10417 if(pIe)
10418 {
10419 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
10420 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010421 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -070010422 return -EINVAL;
10423 }
10424 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
10425 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -070010426 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -070010427 /* Check 15 bit of WPS IE as it contain information for wps state
10428 * WPS state
10429 */
10430 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
10431 {
10432 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
10433 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
10434 {
10435 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
10436 }
10437 }
10438 }
10439 else
10440 {
10441 pConfig->wps_state = SAP_WPS_DISABLED;
10442 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010443 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -070010444
c_hpothufe599e92014-06-16 11:38:55 +053010445 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
10446 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
10447 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
10448 eCSR_ENCRYPT_TYPE_NONE;
10449
Jeff Johnson295189b2012-06-20 16:38:30 -070010450 pConfig->RSNWPAReqIELength = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +053010451 memset(&pConfig->RSNWPAReqIE[0], 0, sizeof(pConfig->RSNWPAReqIE));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010452 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070010453 WLAN_EID_RSN);
10454 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010455 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010456 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053010457 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
10458 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
10459 pConfig->RSNWPAReqIELength);
10460 else
10461 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
10462 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010463 /* The actual processing may eventually be more extensive than
10464 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -070010465 * by the app.
10466 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010467 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070010468 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
10469 &RSNEncryptType,
10470 &mcRSNEncryptType,
10471 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080010472 &MFPCapable,
10473 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053010474 pConfig->RSNWPAReqIE[1]+2,
10475 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010476
10477 if( VOS_STATUS_SUCCESS == status )
10478 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010479 /* Now copy over all the security attributes you have
10480 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070010481 * */
10482 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
10483 pConfig->mcRSNEncryptType = mcRSNEncryptType;
10484 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
10485 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010486 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080010487 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070010488 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
10489 }
10490 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010491
Jeff Johnson295189b2012-06-20 16:38:30 -070010492 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
10493 pBeacon->tail, pBeacon->tail_len);
10494
10495 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
10496 {
Kapil Gupta137ef892016-12-13 19:38:00 +053010497 if (pConfig->RSNWPAReqIE[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070010498 {
10499 /*Mixed mode WPA/WPA2*/
Kapil Gupta137ef892016-12-13 19:38:00 +053010500 prev_rsn_length = pConfig->RSNWPAReqIELength;
Jeff Johnson295189b2012-06-20 16:38:30 -070010501 pConfig->RSNWPAReqIELength += pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053010502 if (pConfig->RSNWPAReqIELength <=
10503 (sizeof(pConfig->RSNWPAReqIE) - prev_rsn_length))
10504 memcpy(&pConfig->RSNWPAReqIE[0] + prev_rsn_length, pIe,
10505 pIe[1] + 2);
10506 else
10507 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
10508 pConfig->RSNWPAReqIELength);
10509
Jeff Johnson295189b2012-06-20 16:38:30 -070010510 }
10511 else
10512 {
10513 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053010514 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
10515 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
10516 pConfig->RSNWPAReqIELength);
10517 else
10518 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
10519 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010520 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070010521 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
10522 &RSNEncryptType,
10523 &mcRSNEncryptType,
10524 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080010525 &MFPCapable,
10526 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053010527 pConfig->RSNWPAReqIE[1]+2,
10528 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010529
10530 if( VOS_STATUS_SUCCESS == status )
10531 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010532 /* Now copy over all the security attributes you have
10533 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070010534 * */
10535 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
10536 pConfig->mcRSNEncryptType = mcRSNEncryptType;
10537 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
10538 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010539 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080010540 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070010541 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
10542 }
10543 }
10544 }
10545
Kapil Gupta137ef892016-12-13 19:38:00 +053010546 if (pConfig->RSNWPAReqIELength > sizeof(pConfig->RSNWPAReqIE)) {
Jeff Johnson4416a782013-03-25 14:17:50 -070010547 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
10548 return -EINVAL;
10549 }
10550
Jeff Johnson295189b2012-06-20 16:38:30 -070010551 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
10552
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010553#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010554 if (params->ssid != NULL)
10555 {
10556 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
10557 pConfig->SSIDinfo.ssid.length = params->ssid_len;
10558 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
10559 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
10560 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010561#else
10562 if (ssid != NULL)
10563 {
10564 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
10565 pConfig->SSIDinfo.ssid.length = ssid_len;
10566 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
10567 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
10568 }
10569#endif
10570
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010571 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -070010572 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010573
Jeff Johnson295189b2012-06-20 16:38:30 -070010574 /* default value */
10575 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
10576 pConfig->num_accept_mac = 0;
10577 pConfig->num_deny_mac = 0;
10578
10579 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
10580 pBeacon->tail, pBeacon->tail_len);
10581
10582 /* pIe for black list is following form:
10583 type : 1 byte
10584 length : 1 byte
10585 OUI : 4 bytes
10586 acl type : 1 byte
10587 no of mac addr in black list: 1 byte
10588 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010589 */
10590 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010591 {
10592 pConfig->SapMacaddr_acl = pIe[6];
10593 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080010594 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010595 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053010596 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
10597 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010598 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
10599 for (i = 0; i < pConfig->num_deny_mac; i++)
10600 {
10601 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
10602 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010603 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010604 }
10605 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
10606 pBeacon->tail, pBeacon->tail_len);
10607
10608 /* pIe for white list is following form:
10609 type : 1 byte
10610 length : 1 byte
10611 OUI : 4 bytes
10612 acl type : 1 byte
10613 no of mac addr in white list: 1 byte
10614 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010615 */
10616 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010617 {
10618 pConfig->SapMacaddr_acl = pIe[6];
10619 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080010620 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010621 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053010622 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
10623 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010624 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
10625 for (i = 0; i < pConfig->num_accept_mac; i++)
10626 {
10627 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
10628 acl_entry++;
10629 }
10630 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053010631
Jeff Johnson295189b2012-06-20 16:38:30 -070010632 wlan_hdd_set_sapHwmode(pHostapdAdapter);
10633
Jeff Johnsone7245742012-09-05 17:12:55 -070010634#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080010635 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +053010636 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
10637 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +053010638 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
10639 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080010640 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
10641 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +053010642 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
10643 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -070010644 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053010645 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -070010646 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +053010647 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070010648
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010649 /* If ACS disable and selected channel <= 14
10650 * OR
10651 * ACS enabled and ACS operating band is choosen as 2.4
10652 * AND
10653 * VHT in 2.4G Disabled
10654 * THEN
10655 * Fallback to 11N mode
10656 */
10657 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
10658 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +053010659 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010660 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -070010661 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053010662 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
10663 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070010664 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
10665 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010666 }
10667#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010668
Jeff Johnson295189b2012-06-20 16:38:30 -070010669 // ht_capab is not what the name conveys,this is used for protection bitmap
10670 pConfig->ht_capab =
10671 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
10672
Kapil Gupta137ef892016-12-13 19:38:00 +053010673 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -070010674 {
10675 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
10676 return -EINVAL;
10677 }
10678
10679 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010680 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -070010681 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
10682 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010683 pConfig->obssProtEnabled =
10684 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -070010685
Chet Lanctot8cecea22014-02-11 19:09:36 -080010686#ifdef WLAN_FEATURE_11W
10687 pConfig->mfpCapable = MFPCapable;
10688 pConfig->mfpRequired = MFPRequired;
10689 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
10690 pConfig->mfpCapable, pConfig->mfpRequired);
10691#endif
10692
Arif Hussain6d2a3322013-11-17 19:50:10 -080010693 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -070010694 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -080010695 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
10696 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
10697 (int)pConfig->channel);
10698 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
10699 pConfig->SapHw_mode, pConfig->privacy,
10700 pConfig->authType);
10701 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
10702 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
10703 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
10704 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -070010705
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010706 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -070010707 {
10708 //Bss already started. just return.
10709 //TODO Probably it should update some beacon params.
10710 hddLog( LOGE, "Bss Already started...Ignore the request");
10711 EXIT();
10712 return 0;
10713 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010714
Agarwal Ashish51325b52014-06-16 16:50:49 +053010715 if (vos_max_concurrent_connections_reached()) {
10716 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10717 return -EINVAL;
10718 }
10719
Jeff Johnson295189b2012-06-20 16:38:30 -070010720 pConfig->persona = pHostapdAdapter->device_mode;
10721
Peng Xu2446a892014-09-05 17:21:18 +053010722 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
10723 if ( NULL != psmeConfig)
10724 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053010725 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +053010726 sme_GetConfigParam(hHal, psmeConfig);
10727 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053010728#ifdef WLAN_FEATURE_AP_HT40_24G
10729 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
10730 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
10731 && pHddCtx->cfg_ini->apHT40_24GEnabled)
10732 {
10733 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
10734 sme_UpdateConfig (hHal, psmeConfig);
10735 }
10736#endif
Peng Xu2446a892014-09-05 17:21:18 +053010737 vos_mem_free(psmeConfig);
10738 }
Peng Xuafc34e32014-09-25 13:23:55 +053010739 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +053010740
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010741 set_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
10742
Jeff Johnson295189b2012-06-20 16:38:30 -070010743 pSapEventCallback = hdd_hostapd_SAPEventCB;
10744 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
10745 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
10746 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010747 hddLog(LOGE,FL("SAP Start Bss fail"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010748 ret = -EINVAL;
10749 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070010750 }
10751
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010752 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -070010753 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
10754
10755 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010756
Jeff Johnson295189b2012-06-20 16:38:30 -070010757 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010758 {
10759 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010760 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -070010761 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070010762 VOS_ASSERT(0);
10763 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010764
Jeff Johnson295189b2012-06-20 16:38:30 -070010765 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053010766 if (WLANSAP_get_sessionId(pVosContext, &pHostapdAdapter->sessionId) !=
10767 VOS_STATUS_SUCCESS)
10768 {
10769 hddLog(LOGE,FL("Fail to get Softap sessionID"));
10770 VOS_ASSERT(0);
10771 }
Kaushik, Sushantf6070802014-10-15 15:09:23 +053010772 /* Initialize WMM configuation */
10773 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010774 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010775
Anurag Chouhan83026002016-12-13 22:46:21 +053010776#ifdef DHCP_SERVER_OFFLOAD
10777 /* set dhcp server offload */
10778 if (iniConfig->enable_dhcp_srv_offload &&
10779 sme_IsFeatureSupportedByFW(SAP_OFFLOADS)) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010780 vos_event_reset(&pHostapdAdapter->dhcp_status.vos_event);
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010781 status = wlan_hdd_set_dhcp_server_offload(pHostapdAdapter, false);
Anurag Chouhan83026002016-12-13 22:46:21 +053010782 if (!VOS_IS_STATUS_SUCCESS(status))
10783 {
10784 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10785 ("HDD DHCP Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010786 vos_event_reset(&pHostapdState->vosEvent);
10787 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
10788 status = vos_wait_single_event(&pHostapdState->vosEvent,
10789 10000);
10790 if (!VOS_IS_STATUS_SUCCESS(status)) {
10791 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010792 ret = -EINVAL;
10793 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010794 }
10795 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010796 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010797 status = vos_wait_single_event(&pHostapdAdapter->dhcp_status.vos_event, 2000);
10798 if (!VOS_IS_STATUS_SUCCESS(status) || pHostapdAdapter->dhcp_status.dhcp_offload_status)
10799 {
10800 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10801 ("ERROR: DHCP HDD vos wait for single_event failed!! %d"),
10802 pHostapdAdapter->dhcp_status.dhcp_offload_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010803 vos_event_reset(&pHostapdState->vosEvent);
10804 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
10805 status = vos_wait_single_event(&pHostapdState->vosEvent,
10806 10000);
10807 if (!VOS_IS_STATUS_SUCCESS(status)) {
10808 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010809 ret = -EINVAL;
10810 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010811 }
10812 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010813 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010814#ifdef MDNS_OFFLOAD
10815 if (iniConfig->enable_mdns_offload) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010816 vos_event_reset(&pHostapdAdapter->mdns_status.vos_event);
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010817 status = wlan_hdd_set_mdns_offload(pHostapdAdapter);
10818 if (VOS_IS_STATUS_SUCCESS(status))
10819 {
10820 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10821 ("HDD MDNS Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010822 vos_event_reset(&pHostapdState->vosEvent);
10823 if (VOS_STATUS_SUCCESS ==
10824 WLANSAP_StopBss(pHddCtx->pvosContext)) {
10825 status = vos_wait_single_event(&pHostapdState->vosEvent,
10826 10000);
10827 if (!VOS_IS_STATUS_SUCCESS(status)) {
10828 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010829 ret = -EINVAL;
10830 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010831 }
10832 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010833 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010834 status = vos_wait_single_event(&pHostapdAdapter->
10835 mdns_status.vos_event, 2000);
10836 if (!VOS_IS_STATUS_SUCCESS(status) ||
10837 pHostapdAdapter->mdns_status.mdns_enable_status ||
10838 pHostapdAdapter->mdns_status.mdns_fqdn_status ||
10839 pHostapdAdapter->mdns_status.mdns_resp_status)
10840 {
10841 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10842 ("MDNS HDD vos wait for single_event failed!! enable %d fqdn %d resp %d"),
10843 pHostapdAdapter->mdns_status.mdns_enable_status,
10844 pHostapdAdapter->mdns_status.mdns_fqdn_status,
10845 pHostapdAdapter->mdns_status.mdns_resp_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010846 vos_event_reset(&pHostapdState->vosEvent);
10847 if (VOS_STATUS_SUCCESS ==
10848 WLANSAP_StopBss(pHddCtx->pvosContext)) {
10849 status = vos_wait_single_event(&pHostapdState->vosEvent,
10850 10000);
10851 if (!VOS_IS_STATUS_SUCCESS(status)) {
10852 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010853 ret = -EINVAL;
10854 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010855 }
10856 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010857 }
10858 }
10859#endif /* MDNS_OFFLOAD */
10860 } else {
10861 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10862 ("DHCP Disabled ini %d, FW %d"),
10863 iniConfig->enable_dhcp_srv_offload,
10864 sme_IsFeatureSupportedByFW(SAP_OFFLOADS));
Anurag Chouhan83026002016-12-13 22:46:21 +053010865 }
10866#endif /* DHCP_SERVER_OFFLOAD */
10867
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010868#ifdef WLAN_FEATURE_P2P_DEBUG
10869 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
10870 {
10871 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
10872 {
10873 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
10874 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -080010875 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010876 }
10877 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
10878 {
10879 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
10880 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -080010881 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010882 }
10883 }
10884#endif
Ashish Kumar Dhanotiya42aa5152017-01-03 20:25:57 +053010885 /* Check and restart SAP if it is on Unsafe channel */
10886 hdd_check_for_unsafe_ch(pHostapdAdapter, pHddCtx);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010887
Jeff Johnson295189b2012-06-20 16:38:30 -070010888 pHostapdState->bCommit = TRUE;
10889 EXIT();
10890
10891 return 0;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010892error:
10893 clear_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
10894 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010895}
10896
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010897#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010898static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010899 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070010900 struct beacon_parameters *params)
10901{
10902 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010903 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010904 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010905
10906 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010907
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010908 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10909 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
10910 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010911 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
10912 hdd_device_modetoString(pAdapter->device_mode),
10913 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010914
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010915 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10916 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010917 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010918 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010919 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010920 }
10921
Agarwal Ashish51325b52014-06-16 16:50:49 +053010922 if (vos_max_concurrent_connections_reached()) {
10923 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10924 return -EINVAL;
10925 }
10926
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010927 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010928 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070010929 )
10930 {
10931 beacon_data_t *old,*new;
10932
10933 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010934
Jeff Johnson295189b2012-06-20 16:38:30 -070010935 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010936 {
10937 hddLog(VOS_TRACE_LEVEL_WARN,
10938 FL("already beacon info added to session(%d)"),
10939 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070010940 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010941 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010942
10943 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
10944
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010945 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -070010946 {
10947 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010948 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010949 return -EINVAL;
10950 }
10951
10952 pAdapter->sessionCtx.ap.beacon = new;
10953
10954 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
10955 }
10956
10957 EXIT();
10958 return status;
10959}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010960
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010961static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
10962 struct net_device *dev,
10963 struct beacon_parameters *params)
10964{
10965 int ret;
10966
10967 vos_ssr_protect(__func__);
10968 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
10969 vos_ssr_unprotect(__func__);
10970
10971 return ret;
10972}
10973
10974static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010975 struct net_device *dev,
10976 struct beacon_parameters *params)
10977{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010978 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010979 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10980 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010981 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010982
10983 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010984
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010985 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10986 TRACE_CODE_HDD_CFG80211_SET_BEACON,
10987 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
10988 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10989 __func__, hdd_device_modetoString(pAdapter->device_mode),
10990 pAdapter->device_mode);
10991
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010992 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10993 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010994 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010995 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010996 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010997 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010998
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010999 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011000 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011001 )
Jeff Johnson295189b2012-06-20 16:38:30 -070011002 {
11003 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011004
Jeff Johnson295189b2012-06-20 16:38:30 -070011005 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011006
Jeff Johnson295189b2012-06-20 16:38:30 -070011007 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011008 {
11009 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11010 FL("session(%d) old and new heads points to NULL"),
11011 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011012 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011013 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011014
11015 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
11016
11017 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011018 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011019 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011020 return -EINVAL;
11021 }
11022
11023 pAdapter->sessionCtx.ap.beacon = new;
11024
11025 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
11026 }
11027
11028 EXIT();
11029 return status;
11030}
11031
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011032static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
11033 struct net_device *dev,
11034 struct beacon_parameters *params)
11035{
11036 int ret;
11037
11038 vos_ssr_protect(__func__);
11039 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
11040 vos_ssr_unprotect(__func__);
11041
11042 return ret;
11043}
11044
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011045#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11046
11047#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011048static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011049 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011050#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011051static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011052 struct net_device *dev)
11053#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011054{
11055 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -070011056 hdd_context_t *pHddCtx = NULL;
11057 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011058 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011059 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011060
11061 ENTER();
11062
11063 if (NULL == pAdapter)
11064 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011065 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011066 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011067 return -ENODEV;
11068 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011069
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011070 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11071 TRACE_CODE_HDD_CFG80211_STOP_AP,
11072 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011073 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11074 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011075 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011076 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011077 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -070011078 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011079
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011080 pScanInfo = &pHddCtx->scan_info;
11081
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011082 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11083 __func__, hdd_device_modetoString(pAdapter->device_mode),
11084 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011085
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011086 ret = wlan_hdd_scan_abort(pAdapter);
11087
Girish Gowli4bf7a632014-06-12 13:42:11 +053011088 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -070011089 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011090 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11091 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011092
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011093 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -070011094 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011095 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11096 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -080011097
Jeff Johnsone7245742012-09-05 17:12:55 -070011098 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011099 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -070011100 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011101 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070011102 }
11103
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053011104 /* Delete all associated STAs before stopping AP/P2P GO */
11105 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +053011106 hdd_hostapd_stop(dev);
11107
Jeff Johnson295189b2012-06-20 16:38:30 -070011108 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011109 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011110 )
11111 {
11112 beacon_data_t *old;
11113
11114 old = pAdapter->sessionCtx.ap.beacon;
11115
11116 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011117 {
11118 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11119 FL("session(%d) beacon data points to NULL"),
11120 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011121 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011122 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011123
Jeff Johnson295189b2012-06-20 16:38:30 -070011124 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011125
11126 mutex_lock(&pHddCtx->sap_lock);
11127 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
11128 {
Jeff Johnson4416a782013-03-25 14:17:50 -070011129 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011130 {
11131 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11132
11133 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
11134
11135 if (!VOS_IS_STATUS_SUCCESS(status))
11136 {
11137 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011138 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -070011139 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011140 }
11141 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011142 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011143 /* BSS stopped, clear the active sessions for this device mode */
11144 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011145 }
11146 mutex_unlock(&pHddCtx->sap_lock);
11147
11148 if(status != VOS_STATUS_SUCCESS)
11149 {
11150 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011151 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011152 return -EINVAL;
11153 }
11154
Jeff Johnson4416a782013-03-25 14:17:50 -070011155 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070011156 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
11157 ==eHAL_STATUS_FAILURE)
11158 {
11159 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011160 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070011161 }
11162
Jeff Johnson4416a782013-03-25 14:17:50 -070011163 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070011164 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
11165 eANI_BOOLEAN_FALSE) )
11166 {
11167 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011168 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070011169 }
11170
11171 // Reset WNI_CFG_PROBE_RSP Flags
11172 wlan_hdd_reset_prob_rspies(pAdapter);
11173
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011174 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
11175
Jeff Johnson295189b2012-06-20 16:38:30 -070011176 pAdapter->sessionCtx.ap.beacon = NULL;
11177 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011178#ifdef WLAN_FEATURE_P2P_DEBUG
11179 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
11180 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
11181 {
11182 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
11183 "GO got removed");
11184 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
11185 }
11186#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011187 }
11188 EXIT();
11189 return status;
11190}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011191
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011192#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11193static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
11194 struct net_device *dev)
11195{
11196 int ret;
11197
11198 vos_ssr_protect(__func__);
11199 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
11200 vos_ssr_unprotect(__func__);
11201
11202 return ret;
11203}
11204#else
11205static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
11206 struct net_device *dev)
11207{
11208 int ret;
11209
11210 vos_ssr_protect(__func__);
11211 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
11212 vos_ssr_unprotect(__func__);
11213
11214 return ret;
11215}
11216#endif
11217
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011218#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
11219
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011220static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011221 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011222 struct cfg80211_ap_settings *params)
11223{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011224 hdd_adapter_t *pAdapter;
11225 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011226 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011227
11228 ENTER();
11229
Girish Gowlib143d7a2015-02-18 19:39:55 +053011230 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070011231 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011232 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +053011233 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011234 return -ENODEV;
11235 }
11236
11237 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
11238 if (NULL == pAdapter)
11239 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011240 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011241 "%s: HDD adapter is Null", __func__);
11242 return -ENODEV;
11243 }
11244
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011245 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11246 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
11247 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011248 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
11249 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011250 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011251 "%s: HDD adapter magic is invalid", __func__);
11252 return -ENODEV;
11253 }
11254
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011255 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
11256
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011257 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011258 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011259 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011260 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011261 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011262 }
11263
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011264 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
11265 __func__, hdd_device_modetoString(pAdapter->device_mode),
11266 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011267
11268 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011269 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011270 )
11271 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011272 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011273
11274 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011275
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011276 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011277 {
11278 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
11279 FL("already beacon info added to session(%d)"),
11280 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011281 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011282 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011283
Girish Gowlib143d7a2015-02-18 19:39:55 +053011284#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11285 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
11286 &new,
11287 &params->beacon);
11288#else
11289 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
11290 &new,
11291 &params->beacon,
11292 params->dtim_period);
11293#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011294
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011295 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011296 {
11297 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011298 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011299 return -EINVAL;
11300 }
11301 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -080011302#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -070011303 wlan_hdd_cfg80211_set_channel(wiphy, dev,
11304#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
11305 params->channel, params->channel_type);
11306#else
11307 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
11308#endif
Viral Modi3a32cc52013-02-08 11:14:52 -080011309#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011310 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053011311 params->ssid_len, params->hidden_ssid,
11312 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011313 }
11314
11315 EXIT();
11316 return status;
11317}
11318
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011319static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
11320 struct net_device *dev,
11321 struct cfg80211_ap_settings *params)
11322{
11323 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011324
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011325 vos_ssr_protect(__func__);
11326 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
11327 vos_ssr_unprotect(__func__);
11328
11329 return ret;
11330}
11331
11332static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011333 struct net_device *dev,
11334 struct cfg80211_beacon_data *params)
11335{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011336 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011337 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011338 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011339
11340 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011341
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011342 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11343 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
11344 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -080011345 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011346 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011347
11348 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11349 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011350 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070011351 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011352 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070011353 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011354
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011355 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011356 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011357 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011358 {
11359 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011360
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011361 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011362
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011363 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011364 {
11365 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11366 FL("session(%d) beacon data points to NULL"),
11367 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011368 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011369 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011370
11371 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
11372
11373 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011374 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011375 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011376 return -EINVAL;
11377 }
11378
11379 pAdapter->sessionCtx.ap.beacon = new;
11380
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053011381 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
11382 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011383 }
11384
11385 EXIT();
11386 return status;
11387}
11388
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011389static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
11390 struct net_device *dev,
11391 struct cfg80211_beacon_data *params)
11392{
11393 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011394
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011395 vos_ssr_protect(__func__);
11396 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
11397 vos_ssr_unprotect(__func__);
11398
11399 return ret;
11400}
11401
11402#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011403
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011404static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011405 struct net_device *dev,
11406 struct bss_parameters *params)
11407{
11408 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011409 hdd_context_t *pHddCtx;
11410 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011411
11412 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011413
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011414 if (NULL == pAdapter)
11415 {
11416 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11417 "%s: HDD adapter is Null", __func__);
11418 return -ENODEV;
11419 }
11420 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011421 ret = wlan_hdd_validate_context(pHddCtx);
11422 if (0 != ret)
11423 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011424 return ret;
11425 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011426 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11427 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
11428 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011429 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11430 __func__, hdd_device_modetoString(pAdapter->device_mode),
11431 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011432
11433 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011434 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011435 )
Jeff Johnson295189b2012-06-20 16:38:30 -070011436 {
11437 /* ap_isolate == -1 means that in change bss, upper layer doesn't
11438 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011439 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -070011440 {
11441 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011442 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011443 }
11444
11445 EXIT();
11446 return 0;
11447}
11448
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011449static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
11450 struct net_device *dev,
11451 struct bss_parameters *params)
11452{
11453 int ret;
11454
11455 vos_ssr_protect(__func__);
11456 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
11457 vos_ssr_unprotect(__func__);
11458
11459 return ret;
11460}
Kiet Lam10841362013-11-01 11:36:50 +053011461/* FUNCTION: wlan_hdd_change_country_code_cd
11462* to wait for contry code completion
11463*/
11464void* wlan_hdd_change_country_code_cb(void *pAdapter)
11465{
11466 hdd_adapter_t *call_back_pAdapter = pAdapter;
11467 complete(&call_back_pAdapter->change_country_code);
11468 return NULL;
11469}
11470
Jeff Johnson295189b2012-06-20 16:38:30 -070011471/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053011472 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -070011473 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
11474 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053011475int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011476 struct net_device *ndev,
11477 enum nl80211_iftype type,
11478 u32 *flags,
11479 struct vif_params *params
11480 )
11481{
11482 struct wireless_dev *wdev;
11483 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011484 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -070011485 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011486 tCsrRoamProfile *pRoamProfile = NULL;
11487 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011488 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011489 eMib_dot11DesiredBssType connectedBssType;
11490 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011491 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011492
11493 ENTER();
11494
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011495 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011496 {
11497 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11498 "%s: Adapter context is null", __func__);
11499 return VOS_STATUS_E_FAILURE;
11500 }
11501
11502 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11503 if (!pHddCtx)
11504 {
11505 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11506 "%s: HDD context is null", __func__);
11507 return VOS_STATUS_E_FAILURE;
11508 }
11509
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011510 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11511 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
11512 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011513 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011514 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011515 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011516 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011517 }
11518
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011519 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11520 __func__, hdd_device_modetoString(pAdapter->device_mode),
11521 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011522
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053011523 if (pHddCtx->concurrency_mode == VOS_STA_MON) {
11524 hddLog(VOS_TRACE_LEVEL_FATAL,
11525 "%s: STA + MON is in progress, cannot change interface",
11526 __func__);
11527 }
11528
Agarwal Ashish51325b52014-06-16 16:50:49 +053011529 if (vos_max_concurrent_connections_reached()) {
11530 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11531 return -EINVAL;
11532 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011533 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070011534 wdev = ndev->ieee80211_ptr;
11535
11536#ifdef WLAN_BTAMP_FEATURE
11537 if((NL80211_IFTYPE_P2P_CLIENT == type)||
11538 (NL80211_IFTYPE_ADHOC == type)||
11539 (NL80211_IFTYPE_AP == type)||
11540 (NL80211_IFTYPE_P2P_GO == type))
11541 {
11542 pHddCtx->isAmpAllowed = VOS_FALSE;
11543 // stop AMP traffic
11544 status = WLANBAP_StopAmp();
11545 if(VOS_STATUS_SUCCESS != status )
11546 {
11547 pHddCtx->isAmpAllowed = VOS_TRUE;
11548 hddLog(VOS_TRACE_LEVEL_FATAL,
11549 "%s: Failed to stop AMP", __func__);
11550 return -EINVAL;
11551 }
11552 }
11553#endif //WLAN_BTAMP_FEATURE
11554 /* Reset the current device mode bit mask*/
11555 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
11556
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +053011557 if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
11558 ((type == NL80211_IFTYPE_P2P_CLIENT) ||
11559 (type == NL80211_IFTYPE_P2P_GO)))
11560 {
11561 /* Notify Mode change in case of concurrency.
11562 * Below function invokes TDLS teardown Functionality Since TDLS is
11563 * not Supported in case of concurrency i.e Once P2P session
11564 * is detected disable offchannel and teardown TDLS links
11565 */
11566 hddLog(LOG1,
11567 FL("Device mode = %d Interface type = %d"),
11568 pAdapter->device_mode, type);
11569 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
11570 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +053011571
Jeff Johnson295189b2012-06-20 16:38:30 -070011572 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070011573 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -070011574 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -070011575 )
11576 {
11577 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011578 if (!pWextState)
11579 {
11580 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11581 "%s: pWextState is null", __func__);
11582 return VOS_STATUS_E_FAILURE;
11583 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011584 pRoamProfile = &pWextState->roamProfile;
11585 LastBSSType = pRoamProfile->BSSType;
11586
11587 switch (type)
11588 {
11589 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070011590 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070011591 hddLog(VOS_TRACE_LEVEL_INFO,
11592 "%s: setting interface Type to INFRASTRUCTURE", __func__);
11593 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -070011594#ifdef WLAN_FEATURE_11AC
11595 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
11596 {
11597 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
11598 }
11599#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011600 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -070011601 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011602 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080011603 //Check for sub-string p2p to confirm its a p2p interface
11604 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011605 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +053011606#ifdef FEATURE_WLAN_TDLS
11607 mutex_lock(&pHddCtx->tdls_lock);
11608 wlan_hdd_tdls_exit(pAdapter, TRUE);
11609 mutex_unlock(&pHddCtx->tdls_lock);
11610#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -080011611 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
11612 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
11613 }
11614 else
11615 {
11616 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070011617 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080011618 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011619 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +053011620
Jeff Johnson295189b2012-06-20 16:38:30 -070011621 case NL80211_IFTYPE_ADHOC:
11622 hddLog(VOS_TRACE_LEVEL_INFO,
11623 "%s: setting interface Type to ADHOC", __func__);
11624 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
11625 pRoamProfile->phyMode =
11626 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -070011627 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011628 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +053011629 hdd_set_ibss_ops( pAdapter );
11630 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +053011631
11632 status = hdd_sta_id_hash_attach(pAdapter);
11633 if (VOS_STATUS_SUCCESS != status) {
11634 hddLog(VOS_TRACE_LEVEL_ERROR,
11635 FL("Failed to initialize hash for IBSS"));
11636 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011637 break;
11638
11639 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070011640 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070011641 {
11642 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
11643 "%s: setting interface Type to %s", __func__,
11644 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
11645
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080011646 //Cancel any remain on channel for GO mode
11647 if (NL80211_IFTYPE_P2P_GO == type)
11648 {
11649 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
11650 }
Mohit Khanna0f232092012-09-11 14:46:08 -070011651 if (NL80211_IFTYPE_AP == type)
11652 {
11653 /* As Loading WLAN Driver one interface being created for p2p device
11654 * address. This will take one HW STA and the max number of clients
11655 * that can connect to softAP will be reduced by one. so while changing
11656 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
11657 * interface as it is not required in SoftAP mode.
11658 */
11659
11660 // Get P2P Adapter
11661 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
11662
11663 if (pP2pAdapter)
11664 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053011665 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +053011666 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -070011667 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
11668 }
11669 }
Swaroop Goltia2e32212014-04-09 23:37:33 +053011670 //Disable IMPS & BMPS for SAP/GO
11671 if(VOS_STATUS_E_FAILURE ==
11672 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
11673 {
11674 //Fail to Exit BMPS
11675 VOS_ASSERT(0);
11676 }
Deepthi Gowri500fc472014-08-11 19:53:10 +053011677
11678 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
11679
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011680#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -070011681
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011682 /* A Mutex Lock is introduced while changing the mode to
11683 * protect the concurrent access for the Adapters by TDLS
11684 * module.
11685 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011686 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011687#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011688 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +053011689 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011690 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -070011691 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
11692 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011693#ifdef FEATURE_WLAN_TDLS
11694 mutex_unlock(&pHddCtx->tdls_lock);
11695#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070011696 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
11697 (pConfig->apRandomBssidEnabled))
11698 {
11699 /* To meet Android requirements create a randomized
11700 MAC address of the form 02:1A:11:Fx:xx:xx */
11701 get_random_bytes(&ndev->dev_addr[3], 3);
11702 ndev->dev_addr[0] = 0x02;
11703 ndev->dev_addr[1] = 0x1A;
11704 ndev->dev_addr[2] = 0x11;
11705 ndev->dev_addr[3] |= 0xF0;
11706 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
11707 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -080011708 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
11709 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070011710 }
11711
Jeff Johnson295189b2012-06-20 16:38:30 -070011712 hdd_set_ap_ops( pAdapter->dev );
11713
Kiet Lam10841362013-11-01 11:36:50 +053011714 /* This is for only SAP mode where users can
11715 * control country through ini.
11716 * P2P GO follows station country code
11717 * acquired during the STA scanning. */
11718 if((NL80211_IFTYPE_AP == type) &&
11719 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
11720 {
11721 int status = 0;
11722 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
11723 "%s: setting country code from INI ", __func__);
11724 init_completion(&pAdapter->change_country_code);
11725 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
11726 (void *)(tSmeChangeCountryCallback)
11727 wlan_hdd_change_country_code_cb,
11728 pConfig->apCntryCode, pAdapter,
11729 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053011730 eSIR_FALSE,
11731 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +053011732 if (eHAL_STATUS_SUCCESS == status)
11733 {
11734 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011735 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +053011736 &pAdapter->change_country_code,
11737 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011738 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +053011739 {
11740 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011741 FL("SME Timed out while setting country code %ld"),
11742 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -080011743
11744 if (pHddCtx->isLogpInProgress)
11745 {
11746 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11747 "%s: LOGP in Progress. Ignore!!!", __func__);
11748 return -EAGAIN;
11749 }
Kiet Lam10841362013-11-01 11:36:50 +053011750 }
11751 }
11752 else
11753 {
11754 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011755 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +053011756 return -EINVAL;
11757 }
11758 }
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +053011759 status = hdd_init_ap_mode(pAdapter, false);
Jeff Johnson295189b2012-06-20 16:38:30 -070011760 if(status != VOS_STATUS_SUCCESS)
11761 {
11762 hddLog(VOS_TRACE_LEVEL_FATAL,
11763 "%s: Error initializing the ap mode", __func__);
11764 return -EINVAL;
11765 }
11766 hdd_set_conparam(1);
11767
Nirav Shah7e3c8132015-06-22 23:51:42 +053011768 status = hdd_sta_id_hash_attach(pAdapter);
11769 if (VOS_STATUS_SUCCESS != status)
11770 {
11771 hddLog(VOS_TRACE_LEVEL_ERROR,
11772 FL("Failed to initialize hash for AP"));
11773 return -EINVAL;
11774 }
11775
Jeff Johnson295189b2012-06-20 16:38:30 -070011776 /*interface type changed update in wiphy structure*/
11777 if(wdev)
11778 {
11779 wdev->iftype = type;
11780 pHddCtx->change_iface = type;
11781 }
11782 else
11783 {
11784 hddLog(VOS_TRACE_LEVEL_ERROR,
11785 "%s: ERROR !!!! Wireless dev is NULL", __func__);
11786 return -EINVAL;
11787 }
11788 goto done;
11789 }
11790
11791 default:
11792 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
11793 __func__);
11794 return -EOPNOTSUPP;
11795 }
11796 }
11797 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011798 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011799 )
11800 {
11801 switch(type)
11802 {
11803 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070011804 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070011805 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +053011806
11807 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011808#ifdef FEATURE_WLAN_TDLS
11809
11810 /* A Mutex Lock is introduced while changing the mode to
11811 * protect the concurrent access for the Adapters by TDLS
11812 * module.
11813 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011814 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011815#endif
c_hpothu002231a2015-02-05 14:58:51 +053011816 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011817 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080011818 //Check for sub-string p2p to confirm its a p2p interface
11819 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -080011820 {
11821 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
11822 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
11823 }
11824 else
11825 {
11826 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070011827 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080011828 }
Agrawal Ashishcfe83282016-09-29 13:03:45 +053011829
11830 /* set con_mode to STA only when no SAP concurrency mode */
11831 if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO)))
11832 hdd_set_conparam(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070011833 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070011834 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
11835 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011836#ifdef FEATURE_WLAN_TDLS
11837 mutex_unlock(&pHddCtx->tdls_lock);
11838#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +053011839 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -070011840 if( VOS_STATUS_SUCCESS != status )
11841 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -070011842 /* In case of JB, for P2P-GO, only change interface will be called,
11843 * This is the right place to enable back bmps_imps()
11844 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053011845 if (pHddCtx->hdd_wlan_suspended)
11846 {
11847 hdd_set_pwrparams(pHddCtx);
11848 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011849 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070011850 goto done;
11851 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070011852 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070011853 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070011854 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
11855 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -070011856 goto done;
11857 default:
11858 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
11859 __func__);
11860 return -EOPNOTSUPP;
11861
11862 }
11863
11864 }
11865 else
11866 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011867 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
11868 __func__, hdd_device_modetoString(pAdapter->device_mode),
11869 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011870 return -EOPNOTSUPP;
11871 }
11872
11873
11874 if(pRoamProfile)
11875 {
11876 if ( LastBSSType != pRoamProfile->BSSType )
11877 {
11878 /*interface type changed update in wiphy structure*/
11879 wdev->iftype = type;
11880
11881 /*the BSS mode changed, We need to issue disconnect
11882 if connected or in IBSS disconnect state*/
11883 if ( hdd_connGetConnectedBssType(
11884 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
11885 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
11886 {
11887 /*need to issue a disconnect to CSR.*/
11888 INIT_COMPLETION(pAdapter->disconnect_comp_var);
11889 if( eHAL_STATUS_SUCCESS ==
11890 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
11891 pAdapter->sessionId,
11892 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
11893 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011894 ret = wait_for_completion_interruptible_timeout(
11895 &pAdapter->disconnect_comp_var,
11896 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
11897 if (ret <= 0)
11898 {
11899 hddLog(VOS_TRACE_LEVEL_ERROR,
11900 FL("wait on disconnect_comp_var failed %ld"), ret);
11901 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011902 }
11903 }
11904 }
11905 }
11906
11907done:
11908 /*set bitmask based on updated value*/
11909 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -070011910
11911 /* Only STA mode support TM now
11912 * all other mode, TM feature should be disabled */
11913 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
11914 (~VOS_STA & pHddCtx->concurrency_mode) )
11915 {
11916 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
11917 }
11918
Jeff Johnson295189b2012-06-20 16:38:30 -070011919#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011920 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053011921 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -070011922 {
11923 //we are ok to do AMP
11924 pHddCtx->isAmpAllowed = VOS_TRUE;
11925 }
11926#endif //WLAN_BTAMP_FEATURE
11927 EXIT();
11928 return 0;
11929}
11930
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053011931/*
11932 * FUNCTION: wlan_hdd_cfg80211_change_iface
11933 * wrapper function to protect the actual implementation from SSR.
11934 */
11935int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
11936 struct net_device *ndev,
11937 enum nl80211_iftype type,
11938 u32 *flags,
11939 struct vif_params *params
11940 )
11941{
11942 int ret;
11943
11944 vos_ssr_protect(__func__);
11945 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
11946 vos_ssr_unprotect(__func__);
11947
11948 return ret;
11949}
11950
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011951#ifdef FEATURE_WLAN_TDLS
11952static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011953 struct net_device *dev,
11954#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
11955 const u8 *mac,
11956#else
11957 u8 *mac,
11958#endif
11959 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011960{
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011961 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011962 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011963 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011964 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053011965 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053011966 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011967
11968 ENTER();
11969
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053011970 if (!dev) {
11971 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
11972 return -EINVAL;
11973 }
11974
11975 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
11976 if (!pAdapter) {
11977 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
11978 return -EINVAL;
11979 }
11980
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053011981 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011982 {
11983 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11984 "Invalid arguments");
11985 return -EINVAL;
11986 }
Hoonki Lee27511902013-03-14 18:19:06 -070011987
11988 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
11989 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
11990 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011991 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070011992 "%s: TDLS mode is disabled OR not enabled in FW."
11993 MAC_ADDRESS_STR " Request declined.",
11994 __func__, MAC_ADDR_ARRAY(mac));
11995 return -ENOTSUPP;
11996 }
11997
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011998 if (pHddCtx->isLogpInProgress)
11999 {
12000 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12001 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053012002 wlan_hdd_tdls_set_link_status(pAdapter,
12003 mac,
12004 eTDLS_LINK_IDLE,
12005 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012006 return -EBUSY;
12007 }
12008
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053012009 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +053012010 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012011
12012 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012013 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012014 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
12015 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053012016 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012017 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012018 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012019
12020 /* in add station, we accept existing valid staId if there is */
12021 if ((0 == update) &&
12022 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
12023 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012024 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012025 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012026 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012027 " link_status %d. staId %d. add station ignored.",
12028 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012029 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012030 return 0;
12031 }
12032 /* in change station, we accept only when staId is valid */
12033 if ((1 == update) &&
12034 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
12035 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
12036 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012037 tANI_U16 staId = pTdlsPeer->staId;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012038 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012039 "%s: " MAC_ADDRESS_STR
12040 " link status %d. staId %d. change station %s.",
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012041 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, staId,
12042 (TDLS_STA_INDEX_VALID(staId)) ? "ignored" : "declined");
12043 mutex_unlock(&pHddCtx->tdls_lock);
12044 return (TDLS_STA_INDEX_VALID(staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012045 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012046 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012047
12048 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053012049 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012050 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012051 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12052 "%s: " MAC_ADDRESS_STR
12053 " TDLS setup is ongoing. Request declined.",
12054 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -070012055 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012056 }
12057
12058 /* first to check if we reached to maximum supported TDLS peer.
12059 TODO: for now, return -EPERM looks working fine,
12060 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012061 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
12062 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012063 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012064 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12065 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012066 " TDLS Max peer already connected. Request declined."
12067 " Num of peers (%d), Max allowed (%d).",
12068 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
12069 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012070 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012071 }
12072 else
12073 {
12074 hddTdlsPeer_t *pTdlsPeer;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012075 mutex_lock(&pHddCtx->tdls_lock);
12076 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012077 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012078 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012079 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012080 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12081 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
12082 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012083 return -EPERM;
12084 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012085 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012086 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012087 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +053012088 wlan_hdd_tdls_set_link_status(pAdapter,
12089 mac,
12090 eTDLS_LINK_CONNECTING,
12091 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012092
Jeff Johnsond75fe012013-04-06 10:53:06 -070012093 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012094 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012095 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012096 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012097 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -070012098 if(StaParams->htcap_present)
12099 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012100 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012101 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012102 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012103 "ht_capa->extended_capabilities: %0x",
12104 StaParams->HTCap.extendedHtCapInfo);
12105 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012106 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012107 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012108 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012109 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -070012110 if(StaParams->vhtcap_present)
12111 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012112 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012113 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
12114 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
12115 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
12116 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012117 {
12118 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012119 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012120 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012121 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012122 "[%d]: %x ", i, StaParams->supported_rates[i]);
12123 }
Jeff Johnsond75fe012013-04-06 10:53:06 -070012124 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012125 else if ((1 == update) && (NULL == StaParams))
12126 {
12127 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12128 "%s : update is true, but staParams is NULL. Error!", __func__);
12129 return -EPERM;
12130 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012131
12132 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
12133
12134 if (!update)
12135 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012136 /*Before adding sta make sure that device exited from BMPS*/
12137 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
12138 {
12139 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12140 "%s: Adding tdls peer sta. Disable BMPS", __func__);
12141 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
12142 if (status != VOS_STATUS_SUCCESS) {
12143 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
12144 }
12145 }
12146
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012147 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012148 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012149 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012150 hddLog(VOS_TRACE_LEVEL_ERROR,
12151 FL("Failed to add TDLS peer STA. Enable Bmps"));
12152 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012153 return -EPERM;
12154 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012155 }
12156 else
12157 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012158 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012159 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012160 if (ret != eHAL_STATUS_SUCCESS) {
12161 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
12162 return -EPERM;
12163 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012164 }
12165
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012166 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012167 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
12168
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053012169 mutex_lock(&pHddCtx->tdls_lock);
12170 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
12171
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012172 if ((pTdlsPeer != NULL) &&
12173 (pTdlsPeer->link_status == eTDLS_LINK_TEARING))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012174 {
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012175 hddLog(VOS_TRACE_LEVEL_ERROR,
12176 FL("peer link status %u"), pTdlsPeer->link_status);
12177 mutex_unlock(&pHddCtx->tdls_lock);
12178 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012179 }
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053012180 mutex_unlock(&pHddCtx->tdls_lock);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012181
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012182 if (ret <= 0)
12183 {
12184 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12185 "%s: timeout waiting for tdls add station indication %ld",
12186 __func__, ret);
12187 goto error;
12188 }
12189
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012190 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
12191 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012192 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012193 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012194 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012195 }
12196
12197 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -070012198
12199error:
Atul Mittal115287b2014-07-08 13:26:33 +053012200 wlan_hdd_tdls_set_link_status(pAdapter,
12201 mac,
12202 eTDLS_LINK_IDLE,
12203 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012204 return -EPERM;
12205
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012206}
12207#endif
12208
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012209static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012210 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012211#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12212 const u8 *mac,
12213#else
Jeff Johnson295189b2012-06-20 16:38:30 -070012214 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012215#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012216 struct station_parameters *params)
12217{
12218 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053012219 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +053012220 hdd_context_t *pHddCtx;
12221 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012222 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012223 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070012224#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012225 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012226 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012227 tANI_U8 isOffChannelSupported = 0;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053012228 tANI_U8 isQosWmmSta = FALSE;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070012229#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070012230
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053012231 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012232
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053012233 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +053012234 if ((NULL == pAdapter))
12235 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012236 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053012237 "invalid adapter ");
12238 return -EINVAL;
12239 }
12240
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012241 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12242 TRACE_CODE_HDD_CHANGE_STATION,
12243 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +053012244 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +053012245
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012246 ret = wlan_hdd_validate_context(pHddCtx);
12247 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +053012248 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012249 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +053012250 }
12251
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012252 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12253
12254 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012255 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012256 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12257 "invalid HDD station context");
12258 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012259 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012260 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
12261
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012262 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
12263 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -070012264 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012265 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -070012266 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012267 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -070012268 WLANTL_STA_AUTHENTICATED);
12269
Gopichand Nakkala29149562013-05-10 21:43:41 +053012270 if (status != VOS_STATUS_SUCCESS)
12271 {
12272 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12273 "%s: Not able to change TL state to AUTHENTICATED", __func__);
12274 return -EINVAL;
12275 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012276 }
12277 }
Hoonki Leea6d49be2013-04-05 09:43:25 -070012278 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
12279 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +053012280#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012281 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
12282 StaParams.capability = params->capability;
12283 StaParams.uapsd_queues = params->uapsd_queues;
12284 StaParams.max_sp = params->max_sp;
12285
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012286 /* Convert (first channel , number of channels) tuple to
12287 * the total list of channels. This goes with the assumption
12288 * that if the first channel is < 14, then the next channels
12289 * are an incremental of 1 else an incremental of 4 till the number
12290 * of channels.
12291 */
12292 if (0 != params->supported_channels_len) {
12293 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
12294 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
12295 {
12296 int wifi_chan_index;
12297 StaParams.supported_channels[j] = params->supported_channels[i];
12298 wifi_chan_index =
12299 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
12300 no_of_channels = params->supported_channels[i+1];
12301 for(k=1; k <= no_of_channels; k++)
12302 {
12303 StaParams.supported_channels[j+1] =
12304 StaParams.supported_channels[j] + wifi_chan_index;
12305 j+=1;
12306 }
12307 }
12308 StaParams.supported_channels_len = j;
12309 }
SaidiReddy Yenuga0f1a1592017-04-05 13:18:26 +053012310 if (params->supported_oper_classes_len >
12311 SIR_MAC_MAX_SUPP_OPER_CLASSES) {
12312 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12313 "received oper classes:%d, resetting it to max supported %d",
12314 params->supported_oper_classes_len,
12315 SIR_MAC_MAX_SUPP_OPER_CLASSES);
12316 params->supported_oper_classes_len =
12317 SIR_MAC_MAX_SUPP_OPER_CLASSES;
12318 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012319 vos_mem_copy(StaParams.supported_oper_classes,
12320 params->supported_oper_classes,
12321 params->supported_oper_classes_len);
12322 StaParams.supported_oper_classes_len =
12323 params->supported_oper_classes_len;
12324
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053012325 if (params->ext_capab_len > sizeof(StaParams.extn_capability)) {
12326 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12327 "received extn capabilities:%d, resetting it to max supported",
12328 params->ext_capab_len);
12329 params->ext_capab_len = sizeof(StaParams.extn_capability);
12330 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012331 if (0 != params->ext_capab_len)
12332 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053012333 params->ext_capab_len);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012334
12335 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070012336 {
12337 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012338 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070012339 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012340
12341 StaParams.supported_rates_len = params->supported_rates_len;
12342
12343 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
12344 * The supported_rates array , for all the structures propogating till Add Sta
12345 * to the firmware has to be modified , if the supplicant (ieee80211) is
12346 * modified to send more rates.
12347 */
12348
12349 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
12350 */
12351 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
12352 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
12353
12354 if (0 != StaParams.supported_rates_len) {
12355 int i = 0;
12356 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
12357 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012358 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012359 "Supported Rates with Length %d", StaParams.supported_rates_len);
12360 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012361 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012362 "[%d]: %0x", i, StaParams.supported_rates[i]);
12363 }
12364
12365 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070012366 {
12367 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012368 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070012369 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012370
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012371 if (0 != params->ext_capab_len ) {
12372 /*Define A Macro : TODO Sunil*/
12373 if ((1<<4) & StaParams.extn_capability[3]) {
12374 isBufSta = 1;
12375 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012376 /* TDLS Channel Switching Support */
12377 if ((1<<6) & StaParams.extn_capability[3]) {
12378 isOffChannelSupported = 1;
12379 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012380 }
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053012381
12382 if (pHddCtx->cfg_ini->fEnableTDLSWmmMode &&
Nitesh Shah48df4c02016-08-12 16:27:33 +053012383 (params->ht_capa || params->vht_capa ||
12384 (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME))))
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053012385 /* TDLS Peer is WME/QoS capable */
12386 isQosWmmSta = TRUE;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053012387
12388 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12389 "%s: TDLS Peer is QOS capable isQosWmmSta= %d HTcapPresent= %d",
12390 __func__, isQosWmmSta, StaParams.htcap_present);
12391
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012392 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
12393 &StaParams, isBufSta,
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053012394 isOffChannelSupported,
12395 isQosWmmSta);
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012396
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053012397 if (VOS_STATUS_SUCCESS != status) {
12398 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12399 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
12400 return -EINVAL;
12401 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012402 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
12403
12404 if (VOS_STATUS_SUCCESS != status) {
12405 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12406 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
12407 return -EINVAL;
12408 }
12409 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -070012410#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +053012411 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012412 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012413 return status;
12414}
12415
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012416#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
12417static int wlan_hdd_change_station(struct wiphy *wiphy,
12418 struct net_device *dev,
12419 const u8 *mac,
12420 struct station_parameters *params)
12421#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012422static int wlan_hdd_change_station(struct wiphy *wiphy,
12423 struct net_device *dev,
12424 u8 *mac,
12425 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012426#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012427{
12428 int ret;
12429
12430 vos_ssr_protect(__func__);
12431 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
12432 vos_ssr_unprotect(__func__);
12433
12434 return ret;
12435}
12436
Jeff Johnson295189b2012-06-20 16:38:30 -070012437/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012438 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -070012439 * This function is used to initialize the key information
12440 */
12441#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012442static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012443 struct net_device *ndev,
12444 u8 key_index, bool pairwise,
12445 const u8 *mac_addr,
12446 struct key_params *params
12447 )
12448#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012449static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012450 struct net_device *ndev,
12451 u8 key_index, const u8 *mac_addr,
12452 struct key_params *params
12453 )
12454#endif
12455{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012456 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070012457 tCsrRoamSetKey setKey;
12458 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012459 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012460 v_U32_t roamId= 0xFF;
12461 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070012462 hdd_hostapd_state_t *pHostapdState;
12463 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012464 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012465 hdd_context_t *pHddCtx;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053012466 uint8_t i;
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053012467 v_MACADDR_t *peerMacAddr;
12468 u64 rsc_counter = 0;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053012469 uint8_t staid = HDD_MAX_STA_COUNT;
12470 bool pairwise_set_key = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070012471
12472 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012473
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012474 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12475 TRACE_CODE_HDD_CFG80211_ADD_KEY,
12476 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012477 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12478 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012479 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012480 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012481 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012482 }
12483
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012484 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12485 __func__, hdd_device_modetoString(pAdapter->device_mode),
12486 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012487
12488 if (CSR_MAX_NUM_KEY <= key_index)
12489 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012490 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012491 key_index);
12492
12493 return -EINVAL;
12494 }
12495
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012496 if (CSR_MAX_KEY_LEN < params->key_len)
12497 {
12498 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
12499 params->key_len);
12500
12501 return -EINVAL;
12502 }
12503
Jingxiang Gec438aea2017-10-26 16:44:00 +080012504 if (CSR_MAX_RSC_LEN < params->seq_len)
12505 {
12506 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Invalid seq length %d", __func__,
12507 params->seq_len);
Ashish Kumar Dhanotiya9783b182017-12-08 14:50:46 +053012508
12509 return -EINVAL;
Jingxiang Gec438aea2017-10-26 16:44:00 +080012510 }
12511
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012512 hddLog(VOS_TRACE_LEVEL_INFO,
Jingxiang Gec438aea2017-10-26 16:44:00 +080012513 "%s: called with key index = %d & key length %d & seq length %d",
12514 __func__, key_index, params->key_len, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070012515
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053012516 peerMacAddr = (v_MACADDR_t *)mac_addr;
12517
Jeff Johnson295189b2012-06-20 16:38:30 -070012518 /*extract key idx, key len and key*/
12519 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
12520 setKey.keyId = key_index;
12521 setKey.keyLength = params->key_len;
12522 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
Jingxiang Gec438aea2017-10-26 16:44:00 +080012523 vos_mem_copy(&setKey.keyRsc[0], params->seq, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070012524
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012525 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070012526 {
12527 case WLAN_CIPHER_SUITE_WEP40:
12528 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
12529 break;
12530
12531 case WLAN_CIPHER_SUITE_WEP104:
12532 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
12533 break;
12534
12535 case WLAN_CIPHER_SUITE_TKIP:
12536 {
12537 u8 *pKey = &setKey.Key[0];
12538 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
12539
12540 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
12541
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012542 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -070012543
12544 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012545 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070012546 |--------------|----------|----------|
12547 <---16bytes---><--8bytes--><--8bytes-->
12548
12549 */
12550 /*Sme expects the 32 bytes key to be in the below order
12551
12552 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012553 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070012554 |--------------|----------|----------|
12555 <---16bytes---><--8bytes--><--8bytes-->
12556 */
12557 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012558 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -070012559
12560 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012561 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070012562
12563 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012564 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070012565
12566
12567 break;
12568 }
12569
12570 case WLAN_CIPHER_SUITE_CCMP:
12571 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
12572 break;
12573
12574#ifdef FEATURE_WLAN_WAPI
12575 case WLAN_CIPHER_SUITE_SMS4:
12576 {
12577 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
12578 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
12579 params->key, params->key_len);
12580 return 0;
12581 }
12582#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070012583
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080012584#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070012585 case WLAN_CIPHER_SUITE_KRK:
12586 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
12587 break;
12588#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070012589
12590#ifdef WLAN_FEATURE_11W
12591 case WLAN_CIPHER_SUITE_AES_CMAC:
12592 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -070012593 break;
Chet Lanctot186b5732013-03-18 10:26:30 -070012594#endif
12595
Jeff Johnson295189b2012-06-20 16:38:30 -070012596 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012597 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070012598 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012599 status = -EOPNOTSUPP;
12600 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012601 }
12602
12603 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
12604 __func__, setKey.encType);
12605
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012606 if (
Jeff Johnson295189b2012-06-20 16:38:30 -070012607#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12608 (!pairwise)
12609#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012610 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -070012611#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012612 )
12613 {
12614 /* set group key*/
12615 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12616 "%s- %d: setting Broadcast key",
12617 __func__, __LINE__);
12618 setKey.keyDirection = eSIR_RX_ONLY;
12619 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
12620 }
12621 else
12622 {
12623 /* set pairwise key*/
12624 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12625 "%s- %d: setting pairwise key",
12626 __func__, __LINE__);
12627 setKey.keyDirection = eSIR_TX_RX;
12628 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053012629 pairwise_set_key = true;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012630 }
12631 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
12632 {
12633 setKey.keyDirection = eSIR_TX_RX;
12634 /*Set the group key*/
12635 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
12636 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -070012637
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012638 if ( 0 != status )
12639 {
12640 hddLog(VOS_TRACE_LEVEL_ERROR,
12641 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012642 status = -EINVAL;
12643 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012644 }
12645 /*Save the keys here and call sme_RoamSetKey for setting
12646 the PTK after peer joins the IBSS network*/
12647 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
12648 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012649 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012650 }
Gopichand Nakkala29149562013-05-10 21:43:41 +053012651 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
12652 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
12653 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012654 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012655 if( pHostapdState->bssState == BSS_START )
12656 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012657 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12658 vos_status = wlan_hdd_check_ula_done(pAdapter);
12659
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053012660 if (peerMacAddr && (pairwise_set_key == true))
12661 staid = hdd_sta_id_find_from_mac_addr(pAdapter, peerMacAddr);
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053012662
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012663 if ( vos_status != VOS_STATUS_SUCCESS )
12664 {
12665 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12666 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
12667 __LINE__, vos_status );
12668
12669 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
12670
12671 status = -EINVAL;
12672 goto end;
12673 }
12674
Jeff Johnson295189b2012-06-20 16:38:30 -070012675 status = WLANSAP_SetKeySta( pVosContext, &setKey);
12676
12677 if ( status != eHAL_STATUS_SUCCESS )
12678 {
12679 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12680 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
12681 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012682 status = -EINVAL;
12683 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012684 }
12685 }
12686
12687 /* Saving WEP keys */
12688 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
12689 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
12690 {
12691 //Save the wep key in ap context. Issue setkey after the BSS is started.
12692 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
12693 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
12694 }
12695 else
12696 {
12697 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012698 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012699 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
12700 }
12701 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012702 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
12703 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012704 {
12705 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12706 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12707
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012708#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12709 if (!pairwise)
12710#else
12711 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
12712#endif
12713 {
12714 /* set group key*/
12715 if (pHddStaCtx->roam_info.deferKeyComplete)
12716 {
12717 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12718 "%s- %d: Perform Set key Complete",
12719 __func__, __LINE__);
12720 hdd_PerformRoamSetKeyComplete(pAdapter);
12721 }
12722 }
12723
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053012724 if (pairwise_set_key == true)
12725 staid = pHddStaCtx->conn_info.staId[0];
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053012726
Jeff Johnson295189b2012-06-20 16:38:30 -070012727 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
12728
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -080012729 pWextState->roamProfile.Keys.defaultIndex = key_index;
12730
12731
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012732 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070012733 params->key, params->key_len);
12734
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012735
Jeff Johnson295189b2012-06-20 16:38:30 -070012736 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
12737
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012738 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070012739 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012740 __func__, setKey.peerMac[0], setKey.peerMac[1],
12741 setKey.peerMac[2], setKey.peerMac[3],
12742 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070012743 setKey.keyDirection);
12744
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012745 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +053012746
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012747 if ( vos_status != VOS_STATUS_SUCCESS )
12748 {
12749 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012750 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
12751 __LINE__, vos_status );
12752
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012753 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012754
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012755 status = -EINVAL;
12756 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012757
12758 }
12759
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012760#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012761 /* The supplicant may attempt to set the PTK once pre-authentication
12762 is done. Save the key in the UMAC and include it in the ADD BSS
12763 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012764 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012765 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012766 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012767 hddLog(VOS_TRACE_LEVEL_INFO_MED,
12768 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012769 status = 0;
12770 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012771 }
12772 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
12773 {
12774 hddLog(VOS_TRACE_LEVEL_ERROR,
12775 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012776 status = -EINVAL;
12777 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012778 }
12779#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070012780
12781 /* issue set key request to SME*/
12782 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
12783 pAdapter->sessionId, &setKey, &roamId );
12784
12785 if ( 0 != status )
12786 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012787 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012788 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
12789 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012790 status = -EINVAL;
12791 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012792 }
12793
12794
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012795 /* in case of IBSS as there was no information available about WEP keys during
12796 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070012797 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012798 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
12799 !( ( IW_AUTH_KEY_MGMT_802_1X
12800 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070012801 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
12802 )
12803 &&
12804 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
12805 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
12806 )
12807 )
12808 {
12809 setKey.keyDirection = eSIR_RX_ONLY;
12810 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
12811
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012812 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070012813 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012814 __func__, setKey.peerMac[0], setKey.peerMac[1],
12815 setKey.peerMac[2], setKey.peerMac[3],
12816 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070012817 setKey.keyDirection);
12818
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012819 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070012820 pAdapter->sessionId, &setKey, &roamId );
12821
12822 if ( 0 != status )
12823 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012824 hddLog(VOS_TRACE_LEVEL_ERROR,
12825 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012826 __func__, status);
12827 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012828 status = -EINVAL;
12829 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012830 }
12831 }
12832 }
12833
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053012834 if (pairwise_set_key == true) {
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053012835 for (i = 0; i < params->seq_len; i++) {
12836 rsc_counter |= (params->seq[i] << i*8);
12837 }
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053012838 WLANTL_SetKeySeqCounter(pVosContext, rsc_counter, staid);
12839 }
12840
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012841end:
12842 /* Need to clear any trace of key value in the memory.
12843 * Thus zero out the memory even though it is local
12844 * variable.
12845 */
12846 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012847 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012848 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012849}
12850
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012851#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12852static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
12853 struct net_device *ndev,
12854 u8 key_index, bool pairwise,
12855 const u8 *mac_addr,
12856 struct key_params *params
12857 )
12858#else
12859static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
12860 struct net_device *ndev,
12861 u8 key_index, const u8 *mac_addr,
12862 struct key_params *params
12863 )
12864#endif
12865{
12866 int ret;
12867 vos_ssr_protect(__func__);
12868#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12869 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
12870 mac_addr, params);
12871#else
12872 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
12873 params);
12874#endif
12875 vos_ssr_unprotect(__func__);
12876
12877 return ret;
12878}
12879
Jeff Johnson295189b2012-06-20 16:38:30 -070012880/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012881 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070012882 * This function is used to get the key information
12883 */
12884#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012885static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012886 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012887 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012888 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070012889 const u8 *mac_addr, void *cookie,
12890 void (*callback)(void *cookie, struct key_params*)
12891 )
12892#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012893static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012894 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012895 struct net_device *ndev,
12896 u8 key_index, const u8 *mac_addr, void *cookie,
12897 void (*callback)(void *cookie, struct key_params*)
12898 )
12899#endif
12900{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012901 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012902 hdd_wext_state_t *pWextState = NULL;
12903 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012904 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012905 hdd_context_t *pHddCtx;
12906 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012907
12908 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012909
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012910 if (NULL == pAdapter)
12911 {
12912 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12913 "%s: HDD adapter is Null", __func__);
12914 return -ENODEV;
12915 }
12916
12917 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12918 ret = wlan_hdd_validate_context(pHddCtx);
12919 if (0 != ret)
12920 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012921 return ret;
12922 }
12923
12924 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12925 pRoamProfile = &(pWextState->roamProfile);
12926
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012927 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12928 __func__, hdd_device_modetoString(pAdapter->device_mode),
12929 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012930
Jeff Johnson295189b2012-06-20 16:38:30 -070012931 memset(&params, 0, sizeof(params));
12932
12933 if (CSR_MAX_NUM_KEY <= key_index)
12934 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012935 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070012936 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012937 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012938
12939 switch(pRoamProfile->EncryptionType.encryptionType[0])
12940 {
12941 case eCSR_ENCRYPT_TYPE_NONE:
12942 params.cipher = IW_AUTH_CIPHER_NONE;
12943 break;
12944
12945 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
12946 case eCSR_ENCRYPT_TYPE_WEP40:
12947 params.cipher = WLAN_CIPHER_SUITE_WEP40;
12948 break;
12949
12950 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
12951 case eCSR_ENCRYPT_TYPE_WEP104:
12952 params.cipher = WLAN_CIPHER_SUITE_WEP104;
12953 break;
12954
12955 case eCSR_ENCRYPT_TYPE_TKIP:
12956 params.cipher = WLAN_CIPHER_SUITE_TKIP;
12957 break;
12958
12959 case eCSR_ENCRYPT_TYPE_AES:
12960 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
12961 break;
12962
12963 default:
12964 params.cipher = IW_AUTH_CIPHER_NONE;
12965 break;
12966 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012967
c_hpothuaaf19692014-05-17 17:01:48 +053012968 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12969 TRACE_CODE_HDD_CFG80211_GET_KEY,
12970 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012971
Jeff Johnson295189b2012-06-20 16:38:30 -070012972 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
12973 params.seq_len = 0;
12974 params.seq = NULL;
12975 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
12976 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012977 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012978 return 0;
12979}
12980
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012981#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12982static int wlan_hdd_cfg80211_get_key(
12983 struct wiphy *wiphy,
12984 struct net_device *ndev,
12985 u8 key_index, bool pairwise,
12986 const u8 *mac_addr, void *cookie,
12987 void (*callback)(void *cookie, struct key_params*)
12988 )
12989#else
12990static int wlan_hdd_cfg80211_get_key(
12991 struct wiphy *wiphy,
12992 struct net_device *ndev,
12993 u8 key_index, const u8 *mac_addr, void *cookie,
12994 void (*callback)(void *cookie, struct key_params*)
12995 )
12996#endif
12997{
12998 int ret;
12999
13000 vos_ssr_protect(__func__);
13001#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13002 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
13003 mac_addr, cookie, callback);
13004#else
13005 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
13006 callback);
13007#endif
13008 vos_ssr_unprotect(__func__);
13009
13010 return ret;
13011}
13012
Jeff Johnson295189b2012-06-20 16:38:30 -070013013/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013014 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013015 * This function is used to delete the key information
13016 */
13017#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013018static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013019 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013020 u8 key_index,
13021 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070013022 const u8 *mac_addr
13023 )
13024#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013025static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013026 struct net_device *ndev,
13027 u8 key_index,
13028 const u8 *mac_addr
13029 )
13030#endif
13031{
13032 int status = 0;
13033
13034 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013035 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070013036 //it is observed that this is invalidating peer
13037 //key index whenever re-key is done. This is affecting data link.
13038 //It should be ok to ignore del_key.
13039#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013040 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
13041 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070013042 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
13043 tCsrRoamSetKey setKey;
13044 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013045
Jeff Johnson295189b2012-06-20 16:38:30 -070013046 ENTER();
13047
13048 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
13049 __func__,pAdapter->device_mode);
13050
13051 if (CSR_MAX_NUM_KEY <= key_index)
13052 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013053 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013054 key_index);
13055
13056 return -EINVAL;
13057 }
13058
13059 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13060 setKey.keyId = key_index;
13061
13062 if (mac_addr)
13063 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
13064 else
13065 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
13066
13067 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
13068
13069 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070013070 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013071 )
13072 {
13073
13074 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070013075 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
13076 if( pHostapdState->bssState == BSS_START)
13077 {
13078 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013079
Jeff Johnson295189b2012-06-20 16:38:30 -070013080 if ( status != eHAL_STATUS_SUCCESS )
13081 {
13082 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13083 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
13084 __LINE__, status );
13085 }
13086 }
13087 }
13088 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013089 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070013090 )
13091 {
13092 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13093
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013094 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
13095
13096 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013097 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013098 __func__, setKey.peerMac[0], setKey.peerMac[1],
13099 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070013100 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013101 if(pAdapter->sessionCtx.station.conn_info.connState ==
13102 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070013103 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013104 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013105 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013106
Jeff Johnson295189b2012-06-20 16:38:30 -070013107 if ( 0 != status )
13108 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013109 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013110 "%s: sme_RoamSetKey failure, returned %d",
13111 __func__, status);
13112 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
13113 return -EINVAL;
13114 }
13115 }
13116 }
13117#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070013118 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013119 return status;
13120}
13121
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013122#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13123static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
13124 struct net_device *ndev,
13125 u8 key_index,
13126 bool pairwise,
13127 const u8 *mac_addr
13128 )
13129#else
13130static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
13131 struct net_device *ndev,
13132 u8 key_index,
13133 const u8 *mac_addr
13134 )
13135#endif
13136{
13137 int ret;
13138
13139 vos_ssr_protect(__func__);
13140#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13141 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
13142 mac_addr);
13143#else
13144 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
13145#endif
13146 vos_ssr_unprotect(__func__);
13147
13148 return ret;
13149}
13150
Jeff Johnson295189b2012-06-20 16:38:30 -070013151/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013152 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013153 * This function is used to set the default tx key index
13154 */
13155#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013156static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013157 struct net_device *ndev,
13158 u8 key_index,
13159 bool unicast, bool multicast)
13160#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013161static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013162 struct net_device *ndev,
13163 u8 key_index)
13164#endif
13165{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013166 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013167 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053013168 hdd_wext_state_t *pWextState;
13169 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013170 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013171
13172 ENTER();
13173
Gopichand Nakkala29149562013-05-10 21:43:41 +053013174 if ((NULL == pAdapter))
13175 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013176 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053013177 "invalid adapter");
13178 return -EINVAL;
13179 }
13180
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013181 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13182 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
13183 pAdapter->sessionId, key_index));
13184
Gopichand Nakkala29149562013-05-10 21:43:41 +053013185 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13186 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13187
13188 if ((NULL == pWextState) || (NULL == pHddStaCtx))
13189 {
13190 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13191 "invalid Wext state or HDD context");
13192 return -EINVAL;
13193 }
13194
Arif Hussain6d2a3322013-11-17 19:50:10 -080013195 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013196 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013197
Jeff Johnson295189b2012-06-20 16:38:30 -070013198 if (CSR_MAX_NUM_KEY <= key_index)
13199 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013200 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013201 key_index);
13202
13203 return -EINVAL;
13204 }
13205
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013206 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13207 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013208 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013209 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013210 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013211 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013212
Jeff Johnson295189b2012-06-20 16:38:30 -070013213 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070013214 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013215 )
Jeff Johnson295189b2012-06-20 16:38:30 -070013216 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053013217 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080013218 pHddStaCtx->conn_info.ucEncryptionType) &&
Hu Wangb1f68cb2017-08-23 20:01:49 +080013219#ifdef FEATURE_WLAN_WAPI
13220 (eCSR_ENCRYPT_TYPE_WPI !=
13221 pHddStaCtx->conn_info.ucEncryptionType) &&
13222#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013223 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080013224 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070013225 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013226 {
13227 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070013228 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013229
Jeff Johnson295189b2012-06-20 16:38:30 -070013230 tCsrRoamSetKey setKey;
13231 v_U32_t roamId= 0xFF;
13232 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013233
13234 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013235 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013236
Jeff Johnson295189b2012-06-20 16:38:30 -070013237 Keys->defaultIndex = (u8)key_index;
13238 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13239 setKey.keyId = key_index;
13240 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013241
13242 vos_mem_copy(&setKey.Key[0],
13243 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070013244 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013245
Gopichand Nakkala29149562013-05-10 21:43:41 +053013246 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013247
13248 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070013249 &pHddStaCtx->conn_info.bssId[0],
13250 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013251
Gopichand Nakkala29149562013-05-10 21:43:41 +053013252 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
13253 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
13254 eCSR_ENCRYPT_TYPE_WEP104)
13255 {
13256 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
13257 even though ap is configured for WEP-40 encryption. In this canse the key length
13258 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
13259 type(104) and switching encryption type to 40*/
13260 pWextState->roamProfile.EncryptionType.encryptionType[0] =
13261 eCSR_ENCRYPT_TYPE_WEP40;
13262 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
13263 eCSR_ENCRYPT_TYPE_WEP40;
13264 }
13265
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013266 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070013267 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013268
Jeff Johnson295189b2012-06-20 16:38:30 -070013269 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013270 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013271 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013272
Jeff Johnson295189b2012-06-20 16:38:30 -070013273 if ( 0 != status )
13274 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013275 hddLog(VOS_TRACE_LEVEL_ERROR,
13276 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013277 status);
13278 return -EINVAL;
13279 }
13280 }
13281 }
13282
13283 /* In SoftAp mode setting key direction for default mode */
13284 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
13285 {
13286 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
13287 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
13288 (eCSR_ENCRYPT_TYPE_AES !=
13289 pWextState->roamProfile.EncryptionType.encryptionType[0])
13290 )
13291 {
13292 /* Saving key direction for default key index to TX default */
13293 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
13294 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
13295 }
13296 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013297 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013298 return status;
13299}
13300
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013301#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13302static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
13303 struct net_device *ndev,
13304 u8 key_index,
13305 bool unicast, bool multicast)
13306#else
13307static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
13308 struct net_device *ndev,
13309 u8 key_index)
13310#endif
13311{
13312 int ret;
13313 vos_ssr_protect(__func__);
13314#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13315 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
13316 multicast);
13317#else
13318 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
13319#endif
13320 vos_ssr_unprotect(__func__);
13321
13322 return ret;
13323}
13324
Jeff Johnson295189b2012-06-20 16:38:30 -070013325/*
13326 * FUNCTION: wlan_hdd_cfg80211_inform_bss
13327 * This function is used to inform the BSS details to nl80211 interface.
13328 */
13329static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
13330 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
13331{
13332 struct net_device *dev = pAdapter->dev;
13333 struct wireless_dev *wdev = dev->ieee80211_ptr;
13334 struct wiphy *wiphy = wdev->wiphy;
13335 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
13336 int chan_no;
13337 int ie_length;
13338 const char *ie;
13339 unsigned int freq;
13340 struct ieee80211_channel *chan;
13341 int rssi = 0;
13342 struct cfg80211_bss *bss = NULL;
13343
Jeff Johnson295189b2012-06-20 16:38:30 -070013344 if( NULL == pBssDesc )
13345 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013346 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013347 return bss;
13348 }
13349
13350 chan_no = pBssDesc->channelId;
13351 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
13352 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
13353
13354 if( NULL == ie )
13355 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013356 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013357 return bss;
13358 }
13359
13360#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
13361 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
13362 {
13363 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
13364 }
13365 else
13366 {
13367 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
13368 }
13369#else
13370 freq = ieee80211_channel_to_frequency(chan_no);
13371#endif
13372
13373 chan = __ieee80211_get_channel(wiphy, freq);
13374
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053013375 if (!chan) {
13376 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
13377 return NULL;
13378 }
13379
Abhishek Singhaee43942014-06-16 18:55:47 +053013380 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070013381
Anand N Sunkad9f80b742015-07-30 20:05:51 +053013382 return cfg80211_inform_bss(wiphy, chan,
13383#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13384 CFG80211_BSS_FTYPE_UNKNOWN,
13385#endif
13386 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013387 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070013388 pBssDesc->capabilityInfo,
13389 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053013390 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070013391}
13392
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053013393/*
13394 * wlan_hdd_cfg80211_update_bss_list :to inform nl80211
13395 * interface that BSS might have been lost.
13396 * @pAdapter: adaptor
13397 * @bssid: bssid which might have been lost
13398 *
13399 * Return: bss which is unlinked from kernel cache
13400 */
13401struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_list(
13402 hdd_adapter_t *pAdapter, tSirMacAddr bssid)
13403{
13404 struct net_device *dev = pAdapter->dev;
13405 struct wireless_dev *wdev = dev->ieee80211_ptr;
13406 struct wiphy *wiphy = wdev->wiphy;
13407 struct cfg80211_bss *bss = NULL;
13408
Abhishek Singh5a597e62016-12-05 15:16:30 +053013409 bss = hdd_get_bss_entry(wiphy,
13410 NULL, bssid,
13411 NULL, 0);
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053013412 if (bss == NULL) {
13413 hddLog(LOGE, FL("BSS not present"));
13414 } else {
13415 hddLog(LOG1, FL("cfg80211_unlink_bss called for BSSID "
13416 MAC_ADDRESS_STR), MAC_ADDR_ARRAY(bssid));
13417 cfg80211_unlink_bss(wiphy, bss);
13418 }
13419 return bss;
13420}
Jeff Johnson295189b2012-06-20 16:38:30 -070013421
13422
13423/*
13424 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
13425 * This function is used to inform the BSS details to nl80211 interface.
13426 */
13427struct cfg80211_bss*
13428wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
13429 tSirBssDescription *bss_desc
13430 )
13431{
13432 /*
13433 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
13434 already exists in bss data base of cfg80211 for that particular BSS ID.
13435 Using cfg80211_inform_bss_frame to update the bss entry instead of
13436 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
13437 now there is no possibility to get the mgmt(probe response) frame from PE,
13438 converting bss_desc to ieee80211_mgmt(probe response) and passing to
13439 cfg80211_inform_bss_frame.
13440 */
13441 struct net_device *dev = pAdapter->dev;
13442 struct wireless_dev *wdev = dev->ieee80211_ptr;
13443 struct wiphy *wiphy = wdev->wiphy;
13444 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080013445#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
13446 qcom_ie_age *qie_age = NULL;
13447 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
13448#else
Jeff Johnson295189b2012-06-20 16:38:30 -070013449 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080013450#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013451 const char *ie =
13452 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
13453 unsigned int freq;
13454 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053013455 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013456 struct cfg80211_bss *bss_status = NULL;
13457 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
13458 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070013459 hdd_context_t *pHddCtx;
13460 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070013461#ifdef WLAN_OPEN_SOURCE
13462 struct timespec ts;
13463#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013464
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013465
Wilson Yangf80a0542013-10-07 13:02:37 -070013466 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13467 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070013468 if (0 != status)
13469 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070013470 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070013471 }
13472
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053013473 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070013474 if (!mgmt)
13475 {
13476 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13477 "%s: memory allocation failed ", __func__);
13478 return NULL;
13479 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070013480
Jeff Johnson295189b2012-06-20 16:38:30 -070013481 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070013482
13483#ifdef WLAN_OPEN_SOURCE
13484 /* Android does not want the timestamp from the frame.
13485 Instead it wants a monotonic increasing value */
13486 get_monotonic_boottime(&ts);
13487 mgmt->u.probe_resp.timestamp =
13488 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
13489#else
13490 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070013491 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
13492 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070013493
13494#endif
13495
Jeff Johnson295189b2012-06-20 16:38:30 -070013496 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
13497 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080013498
13499#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
13500 /* GPS Requirement: need age ie per entry. Using vendor specific. */
13501 /* Assuming this is the last IE, copy at the end */
13502 ie_length -=sizeof(qcom_ie_age);
13503 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
13504 qie_age->element_id = QCOM_VENDOR_IE_ID;
13505 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
13506 qie_age->oui_1 = QCOM_OUI1;
13507 qie_age->oui_2 = QCOM_OUI2;
13508 qie_age->oui_3 = QCOM_OUI3;
13509 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
Selvaraj, Sridhar4b3a8362016-10-12 12:34:08 +053013510 /* Lowi expects the timestamp of bss in units of 1/10 ms. In driver all
13511 * bss related timestamp is in units of ms. Due to this when scan results
13512 * are sent to lowi the scan age is high.To address this, send age in units
13513 * of 1/10 ms.
13514 */
13515 qie_age->age = (vos_timer_get_system_time() -
13516 bss_desc->nReceivedTime)/10;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080013517#endif
13518
Jeff Johnson295189b2012-06-20 16:38:30 -070013519 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053013520 if (bss_desc->fProbeRsp)
13521 {
13522 mgmt->frame_control |=
13523 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
13524 }
13525 else
13526 {
13527 mgmt->frame_control |=
13528 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
13529 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013530
13531#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013532 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070013533 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
13534 {
13535 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
13536 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013537 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070013538 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
13539
13540 {
13541 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
13542 }
13543 else
13544 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013545 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
13546 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070013547 kfree(mgmt);
13548 return NULL;
13549 }
13550#else
13551 freq = ieee80211_channel_to_frequency(chan_no);
13552#endif
13553 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080013554 /*when the band is changed on the fly using the GUI, three things are done
13555 * 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)
13556 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
13557 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
13558 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
13559 * and discards the channels correponding to previous band and calls back with zero bss results.
13560 * 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
13561 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
13562 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
13563 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
13564 * So drop the bss and continue to next bss.
13565 */
13566 if(chan == NULL)
13567 {
Deepthi Gowri306657b2016-04-28 17:10:41 +053013568 hddLog(VOS_TRACE_LEVEL_ERROR,
13569 FL("chan pointer is NULL, chan_no: %d freq: %d"),
13570 chan_no, freq);
Chilam Ngc4244af2013-04-01 15:37:32 -070013571 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080013572 return NULL;
13573 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053013574 /*To keep the rssi icon of the connected AP in the scan window
13575 *and the rssi icon of the wireless networks in sync
13576 * */
13577 if (( eConnectionState_Associated ==
13578 pAdapter->sessionCtx.station.conn_info.connState ) &&
13579 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
13580 pAdapter->sessionCtx.station.conn_info.bssId,
13581 WNI_CFG_BSSID_LEN)) &&
13582 (pHddCtx->hdd_wlan_suspended == FALSE))
13583 {
13584 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
13585 rssi = (pAdapter->rssi * 100);
13586 }
13587 else
13588 {
13589 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
13590 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013591
Nirav Shah20ac06f2013-12-12 18:14:06 +053013592 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053013593 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
13594 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053013595
Jeff Johnson295189b2012-06-20 16:38:30 -070013596 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
13597 frame_len, rssi, GFP_KERNEL);
13598 kfree(mgmt);
13599 return bss_status;
13600}
13601
13602/*
13603 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
13604 * This function is used to update the BSS data base of CFG8011
13605 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013606struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070013607 tCsrRoamInfo *pRoamInfo
13608 )
13609{
13610 tCsrRoamConnectedProfile roamProfile;
13611 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13612 struct cfg80211_bss *bss = NULL;
13613
13614 ENTER();
13615
13616 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
13617 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
13618
13619 if (NULL != roamProfile.pBssDesc)
13620 {
Girish Gowlif4b68022014-08-28 23:18:57 +053013621 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
13622 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070013623
13624 if (NULL == bss)
13625 {
13626 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
13627 __func__);
13628 }
13629
13630 sme_RoamFreeConnectProfile(hHal, &roamProfile);
13631 }
13632 else
13633 {
13634 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
13635 __func__);
13636 }
13637 return bss;
13638}
13639
13640/*
13641 * FUNCTION: wlan_hdd_cfg80211_update_bss
13642 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013643static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
13644 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070013645 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013646{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013647 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013648 tCsrScanResultInfo *pScanResult;
13649 eHalStatus status = 0;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013650 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013651 tScanResultHandle pResult;
13652 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070013653 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013654 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070013655 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013656
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013657 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13658 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
13659 NO_SESSION, pAdapter->sessionId));
13660
Wilson Yangf80a0542013-10-07 13:02:37 -070013661 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013662 ret = wlan_hdd_validate_context(pHddCtx);
13663 if (0 != ret)
Jeff Johnson295189b2012-06-20 16:38:30 -070013664 {
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013665 return ret;
Wilson Yangf80a0542013-10-07 13:02:37 -070013666 }
13667
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013668 if (pAdapter->request != NULL)
13669 {
13670 if ((pAdapter->request->n_ssids == 1)
13671 && (pAdapter->request->ssids != NULL)
13672 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
13673 is_p2p_scan = true;
13674 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013675 /*
13676 * start getting scan results and populate cgf80211 BSS database
13677 */
13678 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
13679
13680 /* no scan results */
13681 if (NULL == pResult)
13682 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013683 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
13684 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053013685 wlan_hdd_get_frame_logs(pAdapter,
13686 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070013687 return status;
13688 }
13689
13690 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
13691
13692 while (pScanResult)
13693 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013694 /*
13695 * cfg80211_inform_bss() is not updating ie field of bss entry, if
13696 * entry already exists in bss data base of cfg80211 for that
13697 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
13698 * bss entry instead of cfg80211_inform_bss, But this call expects
13699 * mgmt packet as input. As of now there is no possibility to get
13700 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070013701 * ieee80211_mgmt(probe response) and passing to c
13702 * fg80211_inform_bss_frame.
13703 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013704 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
13705 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
13706 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013707 pScanResult = sme_ScanResultGetNext(hHal, pResult);
13708 continue; //Skip the non p2p bss entries
13709 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013710 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
13711 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013712
Jeff Johnson295189b2012-06-20 16:38:30 -070013713
13714 if (NULL == bss_status)
13715 {
13716 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013717 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013718 }
13719 else
13720 {
Yue Maf49ba872013-08-19 12:04:25 -070013721 cfg80211_put_bss(
13722#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
13723 wiphy,
13724#endif
13725 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070013726 }
13727
13728 pScanResult = sme_ScanResultGetNext(hHal, pResult);
13729 }
13730
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013731 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013732 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013733 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013734}
13735
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013736void
13737hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
13738{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013739 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080013740 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013741} /****** end hddPrintMacAddr() ******/
13742
13743void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070013744hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013745{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013746 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013747 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070013748 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
13749 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
13750 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013751} /****** end hddPrintPmkId() ******/
13752
13753//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
13754//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
13755
13756//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
13757//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
13758
13759#define dump_bssid(bssid) \
13760 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070013761 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
13762 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013763 }
13764
13765#define dump_pmkid(pMac, pmkid) \
13766 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070013767 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
13768 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013769 }
13770
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070013771#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013772/*
13773 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
13774 * This function is used to notify the supplicant of a new PMKSA candidate.
13775 */
13776int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013777 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013778 int index, bool preauth )
13779{
Jeff Johnsone7245742012-09-05 17:12:55 -070013780#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013781 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070013782 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013783
13784 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070013785 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013786
13787 if( NULL == pRoamInfo )
13788 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013789 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013790 return -EINVAL;
13791 }
13792
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070013793 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
13794 {
13795 dump_bssid(pRoamInfo->bssid);
13796 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013797 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070013798 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013799#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013800 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013801}
13802#endif //FEATURE_WLAN_LFR
13803
Yue Maef608272013-04-08 23:09:17 -070013804#ifdef FEATURE_WLAN_LFR_METRICS
13805/*
13806 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
13807 * 802.11r/LFR metrics reporting function to report preauth initiation
13808 *
13809 */
13810#define MAX_LFR_METRICS_EVENT_LENGTH 100
13811VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
13812 tCsrRoamInfo *pRoamInfo)
13813{
13814 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
13815 union iwreq_data wrqu;
13816
13817 ENTER();
13818
13819 if (NULL == pAdapter)
13820 {
13821 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
13822 return VOS_STATUS_E_FAILURE;
13823 }
13824
13825 /* create the event */
13826 memset(&wrqu, 0, sizeof(wrqu));
13827 memset(metrics_notification, 0, sizeof(metrics_notification));
13828
13829 wrqu.data.pointer = metrics_notification;
13830 wrqu.data.length = scnprintf(metrics_notification,
13831 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
13832 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
13833
13834 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
13835
13836 EXIT();
13837
13838 return VOS_STATUS_SUCCESS;
13839}
13840
13841/*
13842 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
13843 * 802.11r/LFR metrics reporting function to report preauth completion
13844 * or failure
13845 */
13846VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
13847 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
13848{
13849 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
13850 union iwreq_data wrqu;
13851
13852 ENTER();
13853
13854 if (NULL == pAdapter)
13855 {
13856 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
13857 return VOS_STATUS_E_FAILURE;
13858 }
13859
13860 /* create the event */
13861 memset(&wrqu, 0, sizeof(wrqu));
13862 memset(metrics_notification, 0, sizeof(metrics_notification));
13863
13864 scnprintf(metrics_notification, sizeof(metrics_notification),
13865 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
13866 MAC_ADDR_ARRAY(pRoamInfo->bssid));
13867
13868 if (1 == preauth_status)
13869 strncat(metrics_notification, " TRUE", 5);
13870 else
13871 strncat(metrics_notification, " FALSE", 6);
13872
13873 wrqu.data.pointer = metrics_notification;
13874 wrqu.data.length = strlen(metrics_notification);
13875
13876 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
13877
13878 EXIT();
13879
13880 return VOS_STATUS_SUCCESS;
13881}
13882
13883/*
13884 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
13885 * 802.11r/LFR metrics reporting function to report handover initiation
13886 *
13887 */
13888VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
13889 tCsrRoamInfo *pRoamInfo)
13890{
13891 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
13892 union iwreq_data wrqu;
13893
13894 ENTER();
13895
13896 if (NULL == pAdapter)
13897 {
13898 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
13899 return VOS_STATUS_E_FAILURE;
13900 }
13901
13902 /* create the event */
13903 memset(&wrqu, 0, sizeof(wrqu));
13904 memset(metrics_notification, 0, sizeof(metrics_notification));
13905
13906 wrqu.data.pointer = metrics_notification;
13907 wrqu.data.length = scnprintf(metrics_notification,
13908 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
13909 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
13910
13911 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
13912
13913 EXIT();
13914
13915 return VOS_STATUS_SUCCESS;
13916}
13917#endif
13918
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013919
13920/**
13921 * wlan_hdd_cfg80211_validate_scan_req - validate scan request
13922 * @scan_req: scan request to be checked
13923 *
13924 * Return: true or false
13925 */
13926#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
13927static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
13928 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053013929 *scan_req, hdd_context_t
13930 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013931{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053013932 if (!scan_req || !scan_req->wiphy ||
13933 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013934 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
13935 return false;
13936 }
13937 if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HDD, NULL)) {
13938 hddLog(VOS_TRACE_LEVEL_ERROR, "Load/Unload in progress");
13939 return false;
13940 }
13941 return true;
13942}
13943#else
13944static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
13945 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053013946 *scan_req, hdd_context_t
13947 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013948{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053013949 if (!scan_req || !scan_req->wiphy ||
13950 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013951 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
13952 return false;
13953 }
13954 return true;
13955}
13956#endif
13957
Mukul Sharmab392b642017-08-17 17:45:29 +053013958#define NET_DEV_IS_IFF_UP(pAdapter) (pAdapter->dev->flags & IFF_UP)
Jeff Johnson295189b2012-06-20 16:38:30 -070013959/*
13960 * FUNCTION: hdd_cfg80211_scan_done_callback
13961 * scanning callback function, called after finishing scan
13962 *
13963 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013964static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070013965 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
13966{
13967 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013968 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070013969 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013970 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070013971 struct cfg80211_scan_request *req = NULL;
13972 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053013973 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013974 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013975 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013976 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013977
13978 ENTER();
13979
c_manjee1b4ab9a2016-10-26 11:36:55 +053013980 if (!pAdapter || pAdapter->magic != WLAN_HDD_ADAPTER_MAGIC ||
13981 !pAdapter->dev) {
13982 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Adapter is not valid"));
13983 return 0;
13984 }
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013985 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053013986 if (NULL == pHddCtx) {
13987 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013988 return 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013989 }
13990
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053013991#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053013992 if (!NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053013993 {
13994 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Interface is down"));
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053013995 }
13996#endif
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013997 pScanInfo = &pHddCtx->scan_info;
13998
Jeff Johnson295189b2012-06-20 16:38:30 -070013999 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014000 "%s called with halHandle = %pK, pContext = %pK,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080014001 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014002 __func__, halHandle, pContext, (int) scanId, (int) status);
14003
Kiet Lamac06e2c2013-10-23 16:25:07 +053014004 pScanInfo->mScanPendingCounter = 0;
14005
Jeff Johnson295189b2012-06-20 16:38:30 -070014006 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014007 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070014008 &pScanInfo->scan_req_completion_event,
14009 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014010 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070014011 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014012 hddLog(VOS_TRACE_LEVEL_ERROR,
14013 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070014014 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070014015 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014016 }
14017
Yue Maef608272013-04-08 23:09:17 -070014018 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070014019 {
14020 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070014021 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014022 }
14023
14024 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014025 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070014026 {
14027 hddLog(VOS_TRACE_LEVEL_INFO,
14028 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080014029 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070014030 (int) scanId);
14031 }
14032
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014033#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014034 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014035#endif
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014036 {
14037 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
14038 pAdapter);
14039 if (0 > ret)
14040 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014041 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014042
Jeff Johnson295189b2012-06-20 16:38:30 -070014043 /* If any client wait scan result through WEXT
14044 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014045 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070014046 {
14047 /* The other scan request waiting for current scan finish
14048 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014049 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070014050 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014051 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070014052 }
14053 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014054 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070014055 {
14056 struct net_device *dev = pAdapter->dev;
14057 union iwreq_data wrqu;
14058 int we_event;
14059 char *msg;
14060
14061 memset(&wrqu, '\0', sizeof(wrqu));
14062 we_event = SIOCGIWSCAN;
14063 msg = NULL;
14064 wireless_send_event(dev, we_event, &wrqu, msg);
14065 }
14066 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014067 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014068
14069 /* Get the Scan Req */
14070 req = pAdapter->request;
mukul sharmae7041822015-12-03 15:09:21 +053014071 pAdapter->request = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014072
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014073 /* Scan is no longer pending */
14074 pScanInfo->mScanPending = VOS_FALSE;
14075
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014076 if (!wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Jeff Johnson295189b2012-06-20 16:38:30 -070014077 {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014078#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
14079 hddLog(VOS_TRACE_LEVEL_ERROR, FL("interface state %s"),
Mukul Sharmab392b642017-08-17 17:45:29 +053014080 NET_DEV_IS_IFF_UP(pAdapter) ? "up" : "down");
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014081#endif
14082
14083 if (pAdapter->dev) {
14084 hddLog(VOS_TRACE_LEVEL_ERROR, FL("device name %s"),
14085 pAdapter->dev->name);
14086 }
mukul sharmae7041822015-12-03 15:09:21 +053014087 complete(&pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -070014088 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014089 }
14090
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014091 /* last_scan_timestamp is used to decide if new scan
14092 * is needed or not on station interface. If last station
14093 * scan time and new station scan time is less then
14094 * last_scan_timestamp ; driver will return cached scan.
14095 */
14096 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
14097 {
14098 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
14099
14100 if ( req->n_channels )
14101 {
14102 for (i = 0; i < req->n_channels ; i++ )
14103 {
14104 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
14105 }
14106 /* store no of channel scanned */
14107 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
14108 }
14109
14110 }
14111
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070014112 /*
14113 * cfg80211_scan_done informing NL80211 about completion
14114 * of scanning
14115 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014116 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
14117 {
14118 aborted = true;
14119 }
mukul sharmae7041822015-12-03 15:09:21 +053014120
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014121#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014122 if (NET_DEV_IS_IFF_UP(pAdapter) &&
14123 wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014124#endif
14125 cfg80211_scan_done(req, aborted);
mukul sharmae7041822015-12-03 15:09:21 +053014126
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080014127 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070014128
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014129allow_suspend:
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053014130 if ((pHddCtx->cfg_ini->enableMacSpoofing == MAC_ADDR_SPOOFING_FW_HOST_ENABLE
14131 ) && (pHddCtx->spoofMacAddr.isEnabled
14132 || pHddCtx->spoofMacAddr.isReqDeferred)) {
Siddharth Bhal76972212014-10-15 16:22:51 +053014133 /* Generate new random mac addr for next scan */
14134 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +053014135
14136 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
14137 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhal76972212014-10-15 16:22:51 +053014138 }
14139
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070014140 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014141 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070014142
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070014143 /* Acquire wakelock to handle the case where APP's tries to suspend
14144 * immediatly after the driver gets connect request(i.e after scan)
14145 * from supplicant, this result in app's is suspending and not able
14146 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014147 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070014148
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014149#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014150 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014151#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070014152#ifdef FEATURE_WLAN_TDLS
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014153 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070014154#endif
14155
Jeff Johnson295189b2012-06-20 16:38:30 -070014156 EXIT();
14157 return 0;
14158}
14159
14160/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053014161 * FUNCTION: hdd_isConnectionInProgress
14162 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014163 *
14164 */
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014165v_BOOL_t hdd_isConnectionInProgress(hdd_context_t *pHddCtx, v_U8_t *session_id,
14166 scan_reject_states *reason)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014167{
14168 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
14169 hdd_station_ctx_t *pHddStaCtx = NULL;
14170 hdd_adapter_t *pAdapter = NULL;
14171 VOS_STATUS status = 0;
14172 v_U8_t staId = 0;
14173 v_U8_t *staMac = NULL;
14174
14175 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
14176
14177 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
14178 {
14179 pAdapter = pAdapterNode->pAdapter;
14180
14181 if( pAdapter )
14182 {
14183 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014184 "%s: Adapter with device mode %s (%d) exists",
14185 __func__, hdd_device_modetoString(pAdapter->device_mode),
14186 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014187 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053014188 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
14189 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
14190 (eConnectionState_Connecting ==
14191 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
14192 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014193 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014194 "%s: %pK(%d) Connection is in progress", __func__,
Rashmi Ramannab1429032014-04-26 14:59:09 +053014195 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014196 if (session_id && reason)
14197 {
14198 *session_id = pAdapter->sessionId;
14199 *reason = eHDD_CONNECTION_IN_PROGRESS;
14200 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053014201 return VOS_TRUE;
14202 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014203 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053014204 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014205 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014206 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014207 "%s: %pK(%d) Reassociation is in progress", __func__,
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014208 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014209 if (session_id && reason)
14210 {
14211 *session_id = pAdapter->sessionId;
14212 *reason = eHDD_REASSOC_IN_PROGRESS;
14213 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014214 return VOS_TRUE;
14215 }
14216 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014217 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
14218 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014219 {
14220 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14221 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014222 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014223 {
14224 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014225 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080014226 "%s: client " MAC_ADDRESS_STR
14227 " is in the middle of WPS/EAPOL exchange.", __func__,
14228 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014229 if (session_id && reason)
14230 {
14231 *session_id = pAdapter->sessionId;
14232 *reason = eHDD_EAPOL_IN_PROGRESS;
14233 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053014234 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014235 }
14236 }
14237 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
14238 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
14239 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014240 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
14241 ptSapContext pSapCtx = NULL;
14242 pSapCtx = VOS_GET_SAP_CB(pVosContext);
14243 if(pSapCtx == NULL){
14244 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14245 FL("psapCtx is NULL"));
14246 return VOS_FALSE;
14247 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014248 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
14249 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014250 if ((pSapCtx->aStaInfo[staId].isUsed) &&
14251 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014252 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014253 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014254
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014255 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080014256 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
14257 "middle of WPS/EAPOL exchange.", __func__,
14258 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014259 if (session_id && reason)
14260 {
14261 *session_id = pAdapter->sessionId;
14262 *reason = eHDD_SAP_EAPOL_IN_PROGRESS;
14263 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053014264 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014265 }
14266 }
14267 }
14268 }
14269 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
14270 pAdapterNode = pNext;
14271 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053014272 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014273}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014274
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053014275/**
14276 * csr_scan_request_assign_bssid() - Set the BSSID received from Supplicant
14277 * to the Scan request
14278 * @scanRequest: Pointer to the csr scan request
14279 * @request: Pointer to the scan request from supplicant
14280 *
14281 * Return: None
14282 */
14283#ifdef CFG80211_SCAN_BSSID
14284static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
14285 struct cfg80211_scan_request *request)
14286{
14287 vos_mem_copy(scanRequest->bssid, request->bssid, VOS_MAC_ADDR_SIZE);
14288}
14289#else
14290static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
14291 struct cfg80211_scan_request *request)
14292{
14293}
14294#endif
14295
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014296/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014297 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070014298 * this scan respond to scan trigger and update cfg80211 scan database
14299 * later, scan dump command can be used to recieve scan results
14300 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014301int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080014302#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
14303 struct net_device *dev,
14304#endif
14305 struct cfg80211_scan_request *request)
14306{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053014307 hdd_adapter_t *pAdapter = NULL;
14308 hdd_context_t *pHddCtx = NULL;
14309 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014310 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014311 tCsrScanRequest scanRequest;
14312 tANI_U8 *channelList = NULL, i;
14313 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014314 int status;
14315 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014316 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014317 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053014318 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053014319 bool is_p2p_scan = false;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014320 v_U8_t curr_session_id;
14321 scan_reject_states curr_reason;
Jeff Johnson295189b2012-06-20 16:38:30 -070014322
Siddharth Bhal0c162d02014-05-06 19:50:42 +053014323#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
14324 struct net_device *dev = NULL;
14325 if (NULL == request)
14326 {
14327 hddLog(VOS_TRACE_LEVEL_ERROR,
14328 "%s: scan req param null", __func__);
14329 return -EINVAL;
14330 }
14331 dev = request->wdev->netdev;
14332#endif
14333
14334 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
14335 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
14336 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
14337
Jeff Johnson295189b2012-06-20 16:38:30 -070014338 ENTER();
14339
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014340 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
14341 __func__, hdd_device_modetoString(pAdapter->device_mode),
14342 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014343
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014344 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014345 if (0 != status)
14346 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014347 return status;
14348 }
14349
Siddharth Bhal0c162d02014-05-06 19:50:42 +053014350 if (NULL == pwextBuf)
14351 {
14352 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
14353 __func__);
14354 return -EIO;
14355 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014356 cfg_param = pHddCtx->cfg_ini;
14357 pScanInfo = &pHddCtx->scan_info;
14358
Jeff Johnson295189b2012-06-20 16:38:30 -070014359#ifdef WLAN_BTAMP_FEATURE
14360 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080014361 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070014362 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080014363 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014364 "%s: No scanning when AMP is on", __func__);
14365 return -EOPNOTSUPP;
14366 }
14367#endif
14368 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080014369 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070014370 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080014371 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014372 "%s: Not scanning on device_mode = %s (%d)",
14373 __func__, hdd_device_modetoString(pAdapter->device_mode),
14374 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070014375 return -EOPNOTSUPP;
14376 }
14377
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053014378 if (pAdapter->device_mode == WLAN_HDD_MONITOR) {
14379 hddLog(LOGE, FL("Scan is not supported for monitor adapter"));
14380 return -EOPNOTSUPP;
14381 }
14382
Jeff Johnson295189b2012-06-20 16:38:30 -070014383 if (TRUE == pScanInfo->mScanPending)
14384 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053014385 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
14386 {
14387 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
14388 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080014389 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070014390 }
14391
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053014392 // Don't allow scan if PNO scan is going on.
14393 if (pHddCtx->isPnoEnable)
14394 {
14395 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14396 FL("pno scan in progress"));
14397 return -EBUSY;
14398 }
14399
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014400 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070014401 //Channel and action frame is pending
14402 //Otherwise Cancel Remain On Channel and allow Scan
14403 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080014404 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070014405 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053014406 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070014407 return -EBUSY;
14408 }
14409
Jeff Johnson295189b2012-06-20 16:38:30 -070014410 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
14411 {
14412 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080014413 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014414 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014415 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014416 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
14417 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014418 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014419 "%s: MAX TM Level Scan not allowed", __func__);
14420 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014421 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070014422 }
14423 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
14424
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014425 /* Check if scan is allowed at this point of time.
14426 */
Hanumanth Reddy Pothulaec960842016-09-14 19:04:26 +053014427 if (TRUE == pHddCtx->btCoexModeSet)
14428 {
14429 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14430 FL("BTCoex Mode operation in progress"));
14431 return -EBUSY;
14432 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014433 if (hdd_isConnectionInProgress(pHddCtx, &curr_session_id, &curr_reason))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014434 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014435
14436 if (!(pHddCtx->scan_reject_cnt % HDD_SCAN_REJECT_RATE_LIMIT))
14437 hddLog(LOGE, FL("Scan not allowed Session %d reason %d"),
14438 curr_session_id, curr_reason);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014439 if (pHddCtx->last_scan_reject_session_id != curr_session_id ||
14440 pHddCtx->last_scan_reject_reason != curr_reason ||
14441 !pHddCtx->last_scan_reject_timestamp)
14442 {
14443 pHddCtx->last_scan_reject_session_id = curr_session_id;
14444 pHddCtx->last_scan_reject_reason = curr_reason;
Abhishek Singh3e500772017-07-17 10:13:43 +053014445 pHddCtx->last_scan_reject_timestamp =
14446 jiffies_to_msecs(jiffies) + SCAN_REJECT_THRESHOLD_TIME;
Abhishek Singhe4b12562017-06-20 16:53:39 +053014447 pHddCtx->scan_reject_cnt = 0;
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053014448 }
Abhishek Singhe4b12562017-06-20 16:53:39 +053014449 else
14450 {
14451 pHddCtx->scan_reject_cnt++;
14452
Abhishek Singhe4b12562017-06-20 16:53:39 +053014453 if ((pHddCtx->scan_reject_cnt >=
14454 SCAN_REJECT_THRESHOLD) &&
Abhishek Singh3e500772017-07-17 10:13:43 +053014455 vos_system_time_after(jiffies_to_msecs(jiffies),
14456 pHddCtx->last_scan_reject_timestamp))
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014457 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014458 hddLog(LOGE, FL("Session %d reason %d reject cnt %d threshold time has elapsed? %d"),
14459 curr_session_id, curr_reason, pHddCtx->scan_reject_cnt,
14460 vos_system_time_after(jiffies_to_msecs(jiffies),
14461 pHddCtx->last_scan_reject_timestamp));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014462 pHddCtx->last_scan_reject_timestamp = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053014463 pHddCtx->scan_reject_cnt = 0;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014464 if (pHddCtx->cfg_ini->enableFatalEvent)
14465 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
14466 WLAN_LOG_INDICATOR_HOST_DRIVER,
14467 WLAN_LOG_REASON_SCAN_NOT_ALLOWED,
14468 FALSE, FALSE);
14469 else
14470 {
14471 hddLog(LOGE, FL("Triggering SSR"));
14472 vos_wlanRestart();
14473 }
14474 }
14475 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014476 return -EBUSY;
14477 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014478 pHddCtx->last_scan_reject_timestamp = 0;
14479 pHddCtx->last_scan_reject_session_id = 0xFF;
14480 pHddCtx->last_scan_reject_reason = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053014481 pHddCtx->scan_reject_cnt = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014482
Jeff Johnson295189b2012-06-20 16:38:30 -070014483 vos_mem_zero( &scanRequest, sizeof(scanRequest));
14484
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014485 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
14486 * Becasue of this, driver is assuming that this is not wildcard scan and so
14487 * is not aging out the scan results.
14488 */
Hanumanth Reddy Pothula998efeb2017-10-31 15:43:19 +053014489 if ((request->ssids) && (request->n_ssids == 1) &&
14490 ('\0' == request->ssids->ssid[0])) {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014491 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014492 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014493
14494 if ((request->ssids) && (0 < request->n_ssids))
14495 {
14496 tCsrSSIDInfo *SsidInfo;
14497 int j;
14498 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
14499 /* Allocate num_ssid tCsrSSIDInfo structure */
14500 SsidInfo = scanRequest.SSIDs.SSIDList =
14501 ( tCsrSSIDInfo *)vos_mem_malloc(
14502 request->n_ssids*sizeof(tCsrSSIDInfo));
14503
14504 if(NULL == scanRequest.SSIDs.SSIDList)
14505 {
14506 hddLog(VOS_TRACE_LEVEL_ERROR,
14507 "%s: memory alloc failed SSIDInfo buffer", __func__);
14508 return -ENOMEM;
14509 }
14510
14511 /* copy all the ssid's and their length */
14512 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
14513 {
14514 /* get the ssid length */
14515 SsidInfo->SSID.length = request->ssids[j].ssid_len;
14516 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
14517 SsidInfo->SSID.length);
14518 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
14519 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
14520 j, SsidInfo->SSID.ssId);
14521 }
14522 /* set the scan type to active */
14523 scanRequest.scanType = eSIR_ACTIVE_SCAN;
14524 }
14525 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070014526 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053014527 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14528 TRACE_CODE_HDD_CFG80211_SCAN,
14529 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070014530 /* set the scan type to active */
14531 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070014532 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014533 else
14534 {
14535 /*Set the scan type to default type, in this case it is ACTIVE*/
14536 scanRequest.scanType = pScanInfo->scan_mode;
14537 }
14538 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
14539 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070014540
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053014541 csr_scan_request_assign_bssid(&scanRequest, request);
14542
Jeff Johnson295189b2012-06-20 16:38:30 -070014543 /* set BSSType to default type */
14544 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
14545
14546 /*TODO: scan the requested channels only*/
14547
14548 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014549 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070014550 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014551 hddLog(VOS_TRACE_LEVEL_WARN,
14552 "No of Scan Channels exceeded limit: %d", request->n_channels);
14553 request->n_channels = MAX_CHANNEL;
14554 }
14555
14556 hddLog(VOS_TRACE_LEVEL_INFO,
14557 "No of Scan Channels: %d", request->n_channels);
14558
14559
14560 if( request->n_channels )
14561 {
14562 char chList [(request->n_channels*5)+1];
14563 int len;
14564 channelList = vos_mem_malloc( request->n_channels );
14565 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053014566 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014567 hddLog(VOS_TRACE_LEVEL_ERROR,
14568 "%s: memory alloc failed channelList", __func__);
14569 status = -ENOMEM;
14570 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053014571 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014572
14573 for( i = 0, len = 0; i < request->n_channels ; i++ )
14574 {
14575 channelList[i] = request->channels[i]->hw_value;
14576 len += snprintf(chList+len, 5, "%d ", channelList[i]);
14577 }
14578
Nirav Shah20ac06f2013-12-12 18:14:06 +053014579 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014580 "Channel-List: %s ", chList);
14581 }
c_hpothu53512302014-04-15 18:49:53 +053014582
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014583 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
14584 scanRequest.ChannelInfo.ChannelList = channelList;
14585
14586 /* set requestType to full scan */
14587 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
14588
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014589 /* if there is back to back scan happening in driver with in
14590 * nDeferScanTimeInterval interval driver should defer new scan request
14591 * and should provide last cached scan results instead of new channel list.
14592 * This rule is not applicable if scan is p2p scan.
14593 * This condition will work only in case when last request no of channels
14594 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053014595 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053014596 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014597 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014598
Sushant Kaushik86592172015-04-27 16:35:03 +053014599 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
14600 /* if wps ie is NULL , then only defer scan */
14601 if ( pWpsIe == NULL &&
14602 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053014603 {
14604 if ( pScanInfo->last_scan_timestamp !=0 &&
14605 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
14606 {
14607 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
14608 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
14609 vos_mem_compare(pScanInfo->last_scan_channelList,
14610 channelList, pScanInfo->last_scan_numChannels))
14611 {
14612 hddLog(VOS_TRACE_LEVEL_WARN,
14613 " New and old station scan time differ is less then %u",
14614 pHddCtx->cfg_ini->nDeferScanTimeInterval);
14615
14616 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014617 pAdapter);
14618
Agarwal Ashish57e84372014-12-05 18:26:53 +053014619 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053014620 "Return old cached scan as all channels and no of channels are same");
14621
Agarwal Ashish57e84372014-12-05 18:26:53 +053014622 if (0 > ret)
14623 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014624
Agarwal Ashish57e84372014-12-05 18:26:53 +053014625 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053014626
14627 status = eHAL_STATUS_SUCCESS;
14628 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053014629 }
14630 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014631 }
14632
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014633 /* Flush the scan results(only p2p beacons) for STA scan and P2P
14634 * search (Flush on both full scan and social scan but not on single
14635 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
14636 */
14637
14638 /* Supplicant does single channel scan after 8-way handshake
14639 * and in that case driver shoudnt flush scan results. If
14640 * driver flushes the scan results here and unfortunately if
14641 * the AP doesnt respond to our probe req then association
14642 * fails which is not desired
14643 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053014644 if ((request->n_ssids == 1)
14645 && (request->ssids != NULL)
14646 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
14647 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014648
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053014649 if( is_p2p_scan ||
14650 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014651 {
14652 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
14653 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
14654 pAdapter->sessionId );
14655 }
14656
14657 if( request->ie_len )
14658 {
14659 /* save this for future association (join requires this) */
14660 /*TODO: Array needs to be converted to dynamic allocation,
14661 * as multiple ie.s can be sent in cfg80211_scan_request structure
14662 * CR 597966
14663 */
14664 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
14665 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
14666 pScanInfo->scanAddIE.length = request->ie_len;
14667
14668 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
14669 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
14670 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070014671 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014672 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070014673 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014674 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
14675 memcpy( pwextBuf->roamProfile.addIEScan,
14676 request->ie, request->ie_len);
14677 }
14678 else
14679 {
14680 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
14681 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070014682 }
14683
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014684 }
14685 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
14686 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
14687
14688 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
14689 request->ie_len);
14690 if (pP2pIe != NULL)
14691 {
14692#ifdef WLAN_FEATURE_P2P_DEBUG
14693 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
14694 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
14695 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053014696 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014697 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
14698 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
14699 "Go nego completed to Connection is started");
14700 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
14701 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053014702 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014703 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
14704 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070014705 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014706 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
14707 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
14708 "Disconnected state to Connection is started");
14709 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
14710 "for 4way Handshake");
14711 }
14712#endif
14713
14714 /* no_cck will be set during p2p find to disable 11b rates */
14715 if(TRUE == request->no_cck)
14716 {
14717 hddLog(VOS_TRACE_LEVEL_INFO,
14718 "%s: This is a P2P Search", __func__);
14719 scanRequest.p2pSearch = 1;
14720
14721 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053014722 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014723 /* set requestType to P2P Discovery */
14724 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
14725 }
14726
14727 /*
14728 Skip Dfs Channel in case of P2P Search
14729 if it is set in ini file
14730 */
14731 if(cfg_param->skipDfsChnlInP2pSearch)
14732 {
14733 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053014734 }
14735 else
14736 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014737 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053014738 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014739
Agarwal Ashish4f616132013-12-30 23:32:50 +053014740 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014741 }
14742 }
14743
14744 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
14745
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014746#ifdef FEATURE_WLAN_TDLS
14747 /* if tdls disagree scan right now, return immediately.
14748 tdls will schedule the scan when scan is allowed. (return SUCCESS)
14749 or will reject the scan if any TDLS is in progress. (return -EBUSY)
14750 */
14751 status = wlan_hdd_tdls_scan_callback (pAdapter,
14752 wiphy,
14753#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
14754 dev,
14755#endif
14756 request);
Abhishek Singhe2b63952016-01-05 18:27:29 +053014757 if (status <= 0)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014758 {
Abhishek Singhe2b63952016-01-05 18:27:29 +053014759 if (!status)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014760 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
14761 "scan rejected %d", __func__, status);
14762 else
14763 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
14764 __func__, status);
Abhishek Singhe2b63952016-01-05 18:27:29 +053014765 hdd_wlan_block_scan_by_tdls();
Gupta, Kapil2ebf3e02016-03-17 19:45:19 +053014766 goto free_mem;
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014767 }
14768#endif
14769
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070014770 /* acquire the wakelock to avoid the apps suspend during the scan. To
14771 * address the following issues.
14772 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
14773 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
14774 * for long time, this result in apps running at full power for long time.
14775 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
14776 * be stuck in full power because of resume BMPS
14777 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014778 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070014779
Nirav Shah20ac06f2013-12-12 18:14:06 +053014780 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
14781 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014782 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
14783 scanRequest.requestType, scanRequest.scanType,
14784 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053014785 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
14786
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053014787 if (pHddCtx->spoofMacAddr.isEnabled &&
14788 pHddCtx->cfg_ini->enableMacSpoofing == 1)
Siddharth Bhal76972212014-10-15 16:22:51 +053014789 {
14790 hddLog(VOS_TRACE_LEVEL_INFO,
14791 "%s: MAC Spoofing enabled for current scan", __func__);
14792 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
14793 * to fill TxBds for probe request during current scan
14794 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053014795 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053014796 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053014797
14798 if(status != VOS_STATUS_SUCCESS)
14799 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014800 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053014801 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053014802#ifdef FEATURE_WLAN_TDLS
14803 wlan_hdd_tdls_scan_done_callback(pAdapter);
14804#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053014805 goto free_mem;
14806 }
Siddharth Bhal76972212014-10-15 16:22:51 +053014807 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053014808 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070014809 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070014810 pAdapter->sessionId, &scanRequest, &scanId,
14811 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070014812
Jeff Johnson295189b2012-06-20 16:38:30 -070014813 if (eHAL_STATUS_SUCCESS != status)
14814 {
14815 hddLog(VOS_TRACE_LEVEL_ERROR,
14816 "%s: sme_ScanRequest returned error %d", __func__, status);
14817 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070014818 if(eHAL_STATUS_RESOURCES == status)
14819 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014820 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
14821 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070014822 status = -EBUSY;
14823 } else {
14824 status = -EIO;
14825 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014826 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014827
14828#ifdef FEATURE_WLAN_TDLS
14829 wlan_hdd_tdls_scan_done_callback(pAdapter);
14830#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014831 goto free_mem;
14832 }
14833
14834 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053014835 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070014836 pAdapter->request = request;
14837 pScanInfo->scanId = scanId;
14838
14839 complete(&pScanInfo->scan_req_completion_event);
14840
14841free_mem:
14842 if( scanRequest.SSIDs.SSIDList )
14843 {
14844 vos_mem_free(scanRequest.SSIDs.SSIDList);
14845 }
14846
14847 if( channelList )
14848 vos_mem_free( channelList );
14849
14850 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014851 return status;
14852}
14853
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014854int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
14855#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
14856 struct net_device *dev,
14857#endif
14858 struct cfg80211_scan_request *request)
14859{
14860 int ret;
14861
14862 vos_ssr_protect(__func__);
14863 ret = __wlan_hdd_cfg80211_scan(wiphy,
14864#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
14865 dev,
14866#endif
14867 request);
14868 vos_ssr_unprotect(__func__);
14869
14870 return ret;
14871}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014872
14873void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
14874{
14875 v_U8_t iniDot11Mode =
14876 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
14877 eHddDot11Mode hddDot11Mode = iniDot11Mode;
14878
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014879 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
14880 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014881 switch ( iniDot11Mode )
14882 {
14883 case eHDD_DOT11_MODE_AUTO:
14884 case eHDD_DOT11_MODE_11ac:
14885 case eHDD_DOT11_MODE_11ac_ONLY:
14886#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053014887 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
14888 sme_IsFeatureSupportedByFW(DOT11AC) )
14889 hddDot11Mode = eHDD_DOT11_MODE_11ac;
14890 else
14891 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014892#else
14893 hddDot11Mode = eHDD_DOT11_MODE_11n;
14894#endif
14895 break;
14896 case eHDD_DOT11_MODE_11n:
14897 case eHDD_DOT11_MODE_11n_ONLY:
14898 hddDot11Mode = eHDD_DOT11_MODE_11n;
14899 break;
14900 default:
14901 hddDot11Mode = iniDot11Mode;
14902 break;
14903 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053014904#ifdef WLAN_FEATURE_AP_HT40_24G
14905 if (operationChannel > SIR_11B_CHANNEL_END)
14906#endif
14907 {
14908 /* This call decides required channel bonding mode */
14909 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014910 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
Abhishek Singh02b823e2017-10-30 17:53:20 +053014911 operationChannel, eHT_MAX_CHANNEL_WIDTH);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053014912 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014913}
14914
Jeff Johnson295189b2012-06-20 16:38:30 -070014915/*
14916 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014917 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070014918 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014919int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053014920 const u8 *ssid, size_t ssid_len, const u8 *bssid,
14921 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070014922{
14923 int status = 0;
14924 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080014925 hdd_context_t *pHddCtx;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053014926 hdd_station_ctx_t *hdd_sta_ctx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014927 v_U32_t roamId;
14928 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070014929 eCsrAuthType RSNAuthType;
14930
14931 ENTER();
14932
14933 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080014934 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053014935 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080014936
14937 status = wlan_hdd_validate_context(pHddCtx);
14938 if (status)
14939 {
Yue Mae36e3552014-03-05 17:06:20 -080014940 return status;
14941 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014942
Jeff Johnson295189b2012-06-20 16:38:30 -070014943 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
14944 {
14945 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
14946 return -EINVAL;
14947 }
14948
Nitesh Shah9b066282017-06-06 18:05:52 +053014949 wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
14950
Jeff Johnson295189b2012-06-20 16:38:30 -070014951 pRoamProfile = &pWextState->roamProfile;
14952
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014953 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070014954 {
Jeff Johnsone7245742012-09-05 17:12:55 -070014955 hdd_station_ctx_t *pHddStaCtx;
14956 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Abhishek Singh6782c9e2017-06-06 13:37:45 +053014957 pHddStaCtx->get_mgmt_log_sent = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014958
Siddharth Bhalda0d1622015-04-24 15:47:49 +053014959 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
14960
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014961 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070014962 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
14963 {
14964 /*QoS not enabled in cfg file*/
14965 pRoamProfile->uapsd_mask = 0;
14966 }
14967 else
14968 {
14969 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014970 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070014971 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
14972 }
14973
14974 pRoamProfile->SSIDs.numOfSSIDs = 1;
14975 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
14976 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014977 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070014978 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
14979 ssid, ssid_len);
14980
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014981 vos_mem_zero(pRoamProfile->BSSIDs.bssid, WNI_CFG_BSSID_LEN);
14982 vos_mem_zero(pRoamProfile->bssid_hint, WNI_CFG_BSSID_LEN);
14983
Jeff Johnson295189b2012-06-20 16:38:30 -070014984 if (bssid)
14985 {
14986 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014987 vos_mem_copy(pRoamProfile->BSSIDs.bssid, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070014988 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014989 /* Save BSSID in seperate variable as well, as RoamProfile
14990 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070014991 case of join failure we should send valid BSSID to supplicant
14992 */
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014993 vos_mem_copy(pWextState->req_bssId, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070014994 WNI_CFG_BSSID_LEN);
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014995
Jeff Johnson295189b2012-06-20 16:38:30 -070014996 }
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014997 else if (bssid_hint)
Dhanashri Atre51981c62013-06-13 11:47:57 -070014998 {
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014999 /* Store bssid_hint to use in the scan filter. */
15000 vos_mem_copy(pRoamProfile->bssid_hint, bssid_hint,
15001 WNI_CFG_BSSID_LEN);
15002 /*
15003 * Save BSSID in seperate variable as well, as RoamProfile
15004 * BSSID is getting zeroed out in the association process. And in
15005 * case of join failure we should send valid BSSID to supplicant
15006 */
15007 vos_mem_copy(pWextState->req_bssId, bssid_hint,
15008 WNI_CFG_BSSID_LEN);
15009 hddLog(LOG1, FL(" bssid_hint: "MAC_ADDRESS_STR),
15010 MAC_ADDR_ARRAY(pRoamProfile->bssid_hint));
Dhanashri Atre51981c62013-06-13 11:47:57 -070015011 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015012
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015013
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015014 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
15015 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070015016 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
15017 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015018 {
Jeff Johnson295189b2012-06-20 16:38:30 -070015019 /*set gen ie*/
15020 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
15021 /*set auth*/
15022 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
15023 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015024#ifdef FEATURE_WLAN_WAPI
15025 if (pAdapter->wapi_info.nWapiMode)
15026 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015027 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015028 switch (pAdapter->wapi_info.wapiAuthMode)
15029 {
15030 case WAPI_AUTH_MODE_PSK:
15031 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015032 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015033 pAdapter->wapi_info.wapiAuthMode);
15034 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
15035 break;
15036 }
15037 case WAPI_AUTH_MODE_CERT:
15038 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015039 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015040 pAdapter->wapi_info.wapiAuthMode);
15041 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
15042 break;
15043 }
15044 } // End of switch
15045 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
15046 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
15047 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015048 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015049 pRoamProfile->AuthType.numEntries = 1;
15050 pRoamProfile->EncryptionType.numEntries = 1;
15051 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
15052 pRoamProfile->mcEncryptionType.numEntries = 1;
15053 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
15054 }
15055 }
15056#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015057#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015058 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015059 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
15060 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
15061 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015062 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
15063 sizeof (tSirGtkOffloadParams));
15064 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015065 }
15066#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015067 pRoamProfile->csrPersona = pAdapter->device_mode;
15068
Jeff Johnson32d95a32012-09-10 13:15:23 -070015069 if( operatingChannel )
15070 {
15071 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
15072 pRoamProfile->ChannelInfo.numOfChannels = 1;
15073 }
Chet Lanctot186b5732013-03-18 10:26:30 -070015074 else
15075 {
15076 pRoamProfile->ChannelInfo.ChannelList = NULL;
15077 pRoamProfile->ChannelInfo.numOfChannels = 0;
15078 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015079 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
15080 {
15081 hdd_select_cbmode(pAdapter,operatingChannel);
15082 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015083
Agarwal Ashish40f9b872015-09-01 16:17:35 +053015084 /*
15085 * Change conn_state to connecting before sme_RoamConnect(),
15086 * because sme_RoamConnect() has a direct path to call
15087 * hdd_smeRoamCallback(), which will change the conn_state
15088 * If direct path, conn_state will be accordingly changed
15089 * to NotConnected or Associated by either
15090 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
15091 * in sme_RoamCallback()
15092 * if sme_RomConnect is to be queued,
15093 * Connecting state will remain until it is completed.
15094 * If connection state is not changed,
15095 * connection state will remain in eConnectionState_NotConnected state.
15096 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
15097 * if conn state is eConnectionState_NotConnected.
15098 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
15099 * informed of connect result indication which is an issue.
15100 */
15101
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053015102 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
15103 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053015104 {
15105 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053015106 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080015107 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
15108 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053015109 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015110 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070015111 pAdapter->sessionId, pRoamProfile, &roamId);
15112
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053015113 if ((eHAL_STATUS_SUCCESS != status) &&
15114 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
15115 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053015116
15117 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053015118 hddLog(VOS_TRACE_LEVEL_ERROR,
15119 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
15120 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080015121 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053015122 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080015123 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053015124 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080015125
15126 pRoamProfile->ChannelInfo.ChannelList = NULL;
15127 pRoamProfile->ChannelInfo.numOfChannels = 0;
15128
Jeff Johnson295189b2012-06-20 16:38:30 -070015129 }
15130 else
15131 {
15132 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
15133 return -EINVAL;
15134 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080015135 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015136 return status;
15137}
15138
15139/*
15140 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
15141 * This function is used to set the authentication type (OPEN/SHARED).
15142 *
15143 */
15144static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
15145 enum nl80211_auth_type auth_type)
15146{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015147 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070015148 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15149
15150 ENTER();
15151
15152 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015153 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070015154 {
Jeff Johnson295189b2012-06-20 16:38:30 -070015155 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053015156 hddLog(VOS_TRACE_LEVEL_INFO,
15157 "%s: set authentication type to AUTOSWITCH", __func__);
15158 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
15159 break;
15160
15161 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015162#ifdef WLAN_FEATURE_VOWIFI_11R
15163 case NL80211_AUTHTYPE_FT:
15164#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015165 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070015166 "%s: set authentication type to OPEN", __func__);
15167 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
15168 break;
15169
15170 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015171 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070015172 "%s: set authentication type to SHARED", __func__);
15173 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
15174 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080015175#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070015176 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015177 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070015178 "%s: set authentication type to CCKM WPA", __func__);
15179 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
15180 break;
15181#endif
15182
15183
15184 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015185 hddLog(VOS_TRACE_LEVEL_ERROR,
15186 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015187 auth_type);
15188 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
15189 return -EINVAL;
15190 }
15191
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015192 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070015193 pHddStaCtx->conn_info.authType;
15194 return 0;
15195}
15196
15197/*
15198 * FUNCTION: wlan_hdd_set_akm_suite
15199 * This function is used to set the key mgmt type(PSK/8021x).
15200 *
15201 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015202static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070015203 u32 key_mgmt
15204 )
15205{
15206 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15207 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053015208 /* Should be in ieee802_11_defs.h */
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053015209#ifndef WLAN_AKM_SUITE_8021X_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053015210#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053015211#endif
15212#ifndef WLAN_AKM_SUITE_PSK_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053015213#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053015214#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015215 /*set key mgmt type*/
15216 switch(key_mgmt)
15217 {
15218 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053015219 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053015220#ifdef WLAN_FEATURE_VOWIFI_11R
15221 case WLAN_AKM_SUITE_FT_PSK:
15222#endif
15223 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070015224 __func__);
15225 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
15226 break;
15227
15228 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053015229 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053015230#ifdef WLAN_FEATURE_VOWIFI_11R
15231 case WLAN_AKM_SUITE_FT_8021X:
15232#endif
15233 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070015234 __func__);
15235 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
15236 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080015237#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070015238#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
15239#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
15240 case WLAN_AKM_SUITE_CCKM:
15241 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
15242 __func__);
15243 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
15244 break;
15245#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070015246#ifndef WLAN_AKM_SUITE_OSEN
15247#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
15248 case WLAN_AKM_SUITE_OSEN:
15249 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
15250 __func__);
15251 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
15252 break;
15253#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015254
15255 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015256 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015257 __func__, key_mgmt);
15258 return -EINVAL;
15259
15260 }
15261 return 0;
15262}
15263
15264/*
15265 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015266 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070015267 * (NONE/WEP40/WEP104/TKIP/CCMP).
15268 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015269static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
15270 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070015271 bool ucast
15272 )
15273{
15274 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015275 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070015276 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15277
15278 ENTER();
15279
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015280 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070015281 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053015282 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070015283 __func__, cipher);
15284 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
15285 }
15286 else
15287 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015288
Jeff Johnson295189b2012-06-20 16:38:30 -070015289 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015290 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070015291 {
15292 case IW_AUTH_CIPHER_NONE:
15293 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
15294 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015295
Jeff Johnson295189b2012-06-20 16:38:30 -070015296 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053015297 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070015298 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015299
Jeff Johnson295189b2012-06-20 16:38:30 -070015300 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053015301 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070015302 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015303
Jeff Johnson295189b2012-06-20 16:38:30 -070015304 case WLAN_CIPHER_SUITE_TKIP:
15305 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
15306 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015307
Jeff Johnson295189b2012-06-20 16:38:30 -070015308 case WLAN_CIPHER_SUITE_CCMP:
15309 encryptionType = eCSR_ENCRYPT_TYPE_AES;
15310 break;
15311#ifdef FEATURE_WLAN_WAPI
15312 case WLAN_CIPHER_SUITE_SMS4:
15313 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
15314 break;
15315#endif
15316
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080015317#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070015318 case WLAN_CIPHER_SUITE_KRK:
15319 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
15320 break;
15321#endif
15322 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015323 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015324 __func__, cipher);
15325 return -EOPNOTSUPP;
15326 }
15327 }
15328
15329 if (ucast)
15330 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015331 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015332 __func__, encryptionType);
15333 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
15334 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015335 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070015336 encryptionType;
15337 }
15338 else
15339 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015340 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015341 __func__, encryptionType);
15342 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
15343 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
15344 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
15345 }
15346
15347 return 0;
15348}
15349
15350
15351/*
15352 * FUNCTION: wlan_hdd_cfg80211_set_ie
15353 * This function is used to parse WPA/RSN IE's.
15354 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015355int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015356#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15357 const u8 *ie,
15358#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015359 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015360#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015361 size_t ie_len
15362 )
15363{
15364 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015365#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15366 const u8 *genie = ie;
15367#else
Jeff Johnson295189b2012-06-20 16:38:30 -070015368 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015369#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015370 v_U16_t remLen = ie_len;
15371#ifdef FEATURE_WLAN_WAPI
15372 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
15373 u16 *tmp;
15374 v_U16_t akmsuiteCount;
15375 int *akmlist;
15376#endif
15377 ENTER();
15378
15379 /* clear previous assocAddIE */
15380 pWextState->assocAddIE.length = 0;
15381 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070015382 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015383
15384 while (remLen >= 2)
15385 {
15386 v_U16_t eLen = 0;
15387 v_U8_t elementId;
15388 elementId = *genie++;
15389 eLen = *genie++;
15390 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015391
Nachiket Kukade4aba5f02017-06-09 15:43:48 +053015392 /* Sanity check on eLen */
15393 if (eLen > remLen) {
15394 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid IE length[%d] for IE[0x%X]",
15395 __func__, eLen, elementId);
15396 VOS_ASSERT(0);
15397 return -EINVAL;
15398 }
15399
Arif Hussain6d2a3322013-11-17 19:50:10 -080015400 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070015401 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015402
15403 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070015404 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015405 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015406 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 -070015407 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015408 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015409 "%s: Invalid WPA IE", __func__);
15410 return -EINVAL;
15411 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015412 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070015413 {
15414 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015415 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070015416 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015417
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015418 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015419 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015420 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
15421 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070015422 VOS_ASSERT(0);
15423 return -ENOMEM;
15424 }
15425 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
15426 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15427 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015428
Jeff Johnson295189b2012-06-20 16:38:30 -070015429 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
15430 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15431 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15432 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015433 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
15434 {
Nachiket Kukade3d72b7e2017-06-09 16:58:24 +053015435 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
15436 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d]",
15437 __func__, eLen);
15438 VOS_ASSERT(0);
15439 return -EINVAL;
15440 }
15441
Jeff Johnson295189b2012-06-20 16:38:30 -070015442 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
15443 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
15444 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
15445 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
15446 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
15447 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015448 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053015449 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070015450 {
15451 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015452 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070015453 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015454
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015455 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015456 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015457 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15458 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070015459 VOS_ASSERT(0);
15460 return -ENOMEM;
15461 }
15462 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
15463 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15464 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015465
Jeff Johnson295189b2012-06-20 16:38:30 -070015466 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15467 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15468 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015469#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015470 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
15471 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015472 /*Consider WFD IE, only for P2P Client */
15473 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
15474 {
15475 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015476 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070015477 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015478
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015479 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015480 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015481 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15482 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070015483 VOS_ASSERT(0);
15484 return -ENOMEM;
15485 }
15486 // WFD IE is saved to Additional IE ; it should be accumulated to handle
15487 // WPS IE + P2P IE + WFD IE
15488 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15489 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015490
Jeff Johnson295189b2012-06-20 16:38:30 -070015491 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15492 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15493 }
15494#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015495 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015496 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015497 HS20_OUI_TYPE_SIZE)) )
15498 {
15499 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015500 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015501 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015502
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015503 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015504 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015505 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15506 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015507 VOS_ASSERT(0);
15508 return -ENOMEM;
15509 }
15510 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15511 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015512
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015513 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15514 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15515 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070015516 /* Appending OSEN Information Element in Assiciation Request */
15517 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
15518 OSEN_OUI_TYPE_SIZE)) )
15519 {
15520 v_U16_t curAddIELen = pWextState->assocAddIE.length;
15521 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
15522 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015523
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015524 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070015525 {
15526 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15527 "Need bigger buffer space");
15528 VOS_ASSERT(0);
15529 return -ENOMEM;
15530 }
15531 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15532 pWextState->assocAddIE.length += eLen + 2;
15533
15534 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
15535 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15536 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15537 }
15538
Abhishek Singh4322e622015-06-10 15:42:54 +053015539 /* Update only for WPA IE */
15540 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
15541 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070015542
15543 /* populating as ADDIE in beacon frames */
15544 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015545 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070015546 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
15547 {
15548 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
15549 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
15550 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
15551 {
15552 hddLog(LOGE,
15553 "Coldn't pass "
15554 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
15555 }
15556 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
15557 else
15558 hddLog(LOGE,
15559 "Could not pass on "
15560 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
15561
15562 /* IBSS mode doesn't contain params->proberesp_ies still
15563 beaconIE's need to be populated in probe response frames */
15564 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
15565 {
15566 u16 rem_probe_resp_ie_len = eLen + 2;
15567 u8 probe_rsp_ie_len[3] = {0};
15568 u8 counter = 0;
15569
15570 /* Check Probe Resp Length if it is greater then 255 then
15571 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
15572 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
15573 not able Store More then 255 bytes into One Variable */
15574
15575 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
15576 {
15577 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
15578 {
15579 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
15580 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
15581 }
15582 else
15583 {
15584 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
15585 rem_probe_resp_ie_len = 0;
15586 }
15587 }
15588
15589 rem_probe_resp_ie_len = 0;
15590
15591 if (probe_rsp_ie_len[0] > 0)
15592 {
15593 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
15594 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
15595 (tANI_U8*)(genie - 2),
15596 probe_rsp_ie_len[0], NULL,
15597 eANI_BOOLEAN_FALSE)
15598 == eHAL_STATUS_FAILURE)
15599 {
15600 hddLog(LOGE,
15601 "Could not pass"
15602 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
15603 }
15604 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
15605 }
15606
15607 if (probe_rsp_ie_len[1] > 0)
15608 {
15609 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
15610 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
15611 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
15612 probe_rsp_ie_len[1], NULL,
15613 eANI_BOOLEAN_FALSE)
15614 == eHAL_STATUS_FAILURE)
15615 {
15616 hddLog(LOGE,
15617 "Could not pass"
15618 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
15619 }
15620 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
15621 }
15622
15623 if (probe_rsp_ie_len[2] > 0)
15624 {
15625 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
15626 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
15627 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
15628 probe_rsp_ie_len[2], NULL,
15629 eANI_BOOLEAN_FALSE)
15630 == eHAL_STATUS_FAILURE)
15631 {
15632 hddLog(LOGE,
15633 "Could not pass"
15634 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
15635 }
15636 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
15637 }
15638
15639 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
15640 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
15641 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
15642 {
15643 hddLog(LOGE,
15644 "Could not pass"
15645 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
15646 }
15647 }
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070015648 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070015649 break;
15650 case DOT11F_EID_RSN:
15651 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
15652 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
15653 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
15654 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
15655 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
15656 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053015657
Abhishek Singhb16f3562016-01-20 11:08:32 +053015658 /* Appending extended capabilities with Interworking or
15659 * bsstransition bit set in Assoc Req.
Abhishek Singh15d95602015-03-24 15:52:57 +053015660 *
15661 * In assoc req this EXT Cap will only be taken into account if
Abhishek Singhb16f3562016-01-20 11:08:32 +053015662 * interworkingService or bsstransition bit is set to 1.
15663 * Driver is only interested in interworkingService and
15664 * bsstransition capability from supplicant.
15665 * If in future any other EXT Cap info is
Abhishek Singh15d95602015-03-24 15:52:57 +053015666 * required from supplicat, it needs to be handled while
15667 * sending Assoc Req in LIM.
15668 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015669 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015670 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015671 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015672 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015673 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015674
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015675 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015676 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015677 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15678 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015679 VOS_ASSERT(0);
15680 return -ENOMEM;
15681 }
15682 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15683 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015684
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015685 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15686 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15687 break;
15688 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015689#ifdef FEATURE_WLAN_WAPI
15690 case WLAN_EID_WAPI:
15691 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070015692 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070015693 pAdapter->wapi_info.nWapiMode);
15694 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015695 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070015696 akmsuiteCount = WPA_GET_LE16(tmp);
15697 tmp = tmp + 1;
15698 akmlist = (int *)(tmp);
15699 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
15700 {
15701 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
15702 }
15703 else
15704 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015705 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070015706 VOS_ASSERT(0);
15707 return -EINVAL;
15708 }
15709
15710 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
15711 {
15712 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015713 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015714 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015715 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015716 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015717 {
Jeff Johnson295189b2012-06-20 16:38:30 -070015718 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015719 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015720 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
15721 }
15722 break;
15723#endif
15724 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015725 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015726 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015727 /* when Unknown IE is received we should break and continue
15728 * to the next IE in the buffer instead we were returning
15729 * so changing this to break */
15730 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070015731 }
15732 genie += eLen;
15733 remLen -= eLen;
15734 }
15735 EXIT();
15736 return 0;
15737}
15738
15739/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053015740 * FUNCTION: hdd_isWPAIEPresent
15741 * Parse the received IE to find the WPA IE
15742 *
15743 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015744static bool hdd_isWPAIEPresent(
15745#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
15746 const u8 *ie,
15747#else
15748 u8 *ie,
15749#endif
15750 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053015751{
15752 v_U8_t eLen = 0;
15753 v_U16_t remLen = ie_len;
15754 v_U8_t elementId = 0;
15755
15756 while (remLen >= 2)
15757 {
15758 elementId = *ie++;
15759 eLen = *ie++;
15760 remLen -= 2;
15761 if (eLen > remLen)
15762 {
15763 hddLog(VOS_TRACE_LEVEL_ERROR,
15764 "%s: IE length is wrong %d", __func__, eLen);
15765 return FALSE;
15766 }
15767 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
15768 {
15769 /* OUI - 0x00 0X50 0XF2
15770 WPA Information Element - 0x01
15771 WPA version - 0x01*/
15772 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
15773 return TRUE;
15774 }
15775 ie += eLen;
15776 remLen -= eLen;
15777 }
15778 return FALSE;
15779}
15780
15781/*
Jeff Johnson295189b2012-06-20 16:38:30 -070015782 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015783 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070015784 * parameters during connect operation.
15785 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015786int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070015787 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015788 )
Jeff Johnson295189b2012-06-20 16:38:30 -070015789{
15790 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015791 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070015792 ENTER();
15793
15794 /*set wpa version*/
15795 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
15796
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015797 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070015798 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053015799 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070015800 {
15801 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
15802 }
15803 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
15804 {
15805 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
15806 }
15807 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015808
15809 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015810 pWextState->wpaVersion);
15811
15812 /*set authentication type*/
15813 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
15814
15815 if (0 > status)
15816 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015817 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015818 "%s: failed to set authentication type ", __func__);
15819 return status;
15820 }
15821
15822 /*set key mgmt type*/
15823 if (req->crypto.n_akm_suites)
15824 {
15825 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
15826 if (0 > status)
15827 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015828 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070015829 __func__);
15830 return status;
15831 }
15832 }
15833
15834 /*set pairwise cipher type*/
15835 if (req->crypto.n_ciphers_pairwise)
15836 {
15837 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
15838 req->crypto.ciphers_pairwise[0], true);
15839 if (0 > status)
15840 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015841 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015842 "%s: failed to set unicast cipher type", __func__);
15843 return status;
15844 }
15845 }
15846 else
15847 {
15848 /*Reset previous cipher suite to none*/
15849 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
15850 if (0 > status)
15851 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015852 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015853 "%s: failed to set unicast cipher type", __func__);
15854 return status;
15855 }
15856 }
15857
15858 /*set group cipher type*/
15859 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
15860 false);
15861
15862 if (0 > status)
15863 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015864 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070015865 __func__);
15866 return status;
15867 }
15868
Chet Lanctot186b5732013-03-18 10:26:30 -070015869#ifdef WLAN_FEATURE_11W
15870 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
15871#endif
15872
Jeff Johnson295189b2012-06-20 16:38:30 -070015873 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
15874 if (req->ie_len)
15875 {
15876 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
15877 if ( 0 > status)
15878 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015879 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070015880 __func__);
15881 return status;
15882 }
15883 }
15884
15885 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015886 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070015887 {
15888 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
15889 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
15890 )
15891 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015892 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070015893 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
15894 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015895 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070015896 __func__);
15897 return -EOPNOTSUPP;
15898 }
15899 else
15900 {
15901 u8 key_len = req->key_len;
15902 u8 key_idx = req->key_idx;
15903
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015904 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070015905 && (CSR_MAX_NUM_KEY > key_idx)
15906 )
15907 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015908 hddLog(VOS_TRACE_LEVEL_INFO,
15909 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015910 __func__, key_idx, key_len);
15911 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015912 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070015913 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015914 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070015915 (u8)key_len;
15916 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
15917 }
15918 }
15919 }
15920 }
15921
15922 return status;
15923}
15924
15925/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015926 * FUNCTION: wlan_hdd_try_disconnect
15927 * This function is used to disconnect from previous
15928 * connection
15929 */
Agrawal Ashishc407f192017-01-23 17:18:35 +053015930int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015931{
15932 long ret = 0;
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015933 int status, result = 0;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015934 hdd_station_ctx_t *pHddStaCtx;
15935 eMib_dot11DesiredBssType connectedBssType;
Abhishek Singh19a7dd92015-12-30 16:31:51 +053015936 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015937
Abhishek Singh19a7dd92015-12-30 16:31:51 +053015938 ret = wlan_hdd_validate_context(pHddCtx);
15939 if (0 != ret)
15940 {
15941 return ret;
15942 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015943 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15944
15945 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
15946
15947 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
15948 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
Abhishek Singh630ff592016-01-07 18:15:53 +053015949 (eConnectionState_Connecting == pHddStaCtx->conn_info.connState) ||
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015950 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
15951 {
Abhishek Singh9f4df782017-03-15 17:29:10 +053015952 /* Indicate disconnect to SME so that in-progress connection or preauth
15953 * can be aborted
15954 */
15955 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
15956 pAdapter->sessionId);
Abhishek Singh19a7dd92015-12-30 16:31:51 +053015957 spin_lock_bh(&pAdapter->lock_for_active_session);
15958 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
15959 {
15960 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
15961 }
15962 spin_unlock_bh(&pAdapter->lock_for_active_session);
Abhishek Singhf7962582015-10-23 10:54:06 +053015963 hdd_connSetConnectionState(pHddStaCtx,
15964 eConnectionState_Disconnecting);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015965 /* Issue disconnect to CSR */
15966 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015967 status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015968 pAdapter->sessionId,
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015969 eCSR_DISCONNECT_REASON_UNSPECIFIED);
15970 if(eHAL_STATUS_CMD_NOT_QUEUED == status) {
15971 hddLog(LOG1,
15972 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
15973 } else if ( 0 != status ) {
15974 hddLog(LOGE,
15975 FL("csrRoamDisconnect failure, returned %d"),
15976 (int)status );
15977 result = -EINVAL;
15978 goto disconnected;
15979 }
15980 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015981 &pAdapter->disconnect_comp_var,
15982 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015983 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status)) {
15984 hddLog(LOGE,
15985 "%s: Failed to disconnect, timed out", __func__);
15986 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015987 }
15988 }
15989 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
15990 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015991 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015992 &pAdapter->disconnect_comp_var,
15993 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015994 if (!ret)
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015995 {
15996 hddLog(LOGE, FL("Failed to receive disconnect event"));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015997 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015998 }
15999 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016000disconnected:
16001 hddLog(LOG1,
16002 FL("Set HDD connState to eConnectionState_NotConnected"));
16003 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
16004 return result;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016005}
16006
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053016007/**
16008 * wlan_hdd_reassoc_bssid_hint() - Start reassociation if bssid is present
16009 * @adapter: Pointer to the HDD adapter
16010 * @req: Pointer to the structure cfg_connect_params receieved from user space
16011 *
16012 * This function will start reassociation if bssid hint, channel hint and
16013 * previous bssid parameters are present in the connect request
16014 *
16015 * Return: success if reassociation is happening
16016 * Error code if reassociation is not permitted or not happening
16017 */
16018#ifdef CFG80211_CONNECT_PREV_BSSID
16019static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
16020 struct cfg80211_connect_params *req)
16021{
16022 int status = -EPERM;
16023 if (req->bssid_hint && req->channel_hint && req->prev_bssid) {
16024 hddLog(VOS_TRACE_LEVEL_INFO,
16025 FL("REASSOC Attempt on channel %d to "MAC_ADDRESS_STR),
16026 req->channel_hint->hw_value,
16027 MAC_ADDR_ARRAY(req->bssid_hint));
16028 status = hdd_reassoc(adapter, req->bssid_hint,
16029 req->channel_hint->hw_value,
16030 CONNECT_CMD_USERSPACE);
16031 }
16032 return status;
16033}
16034#else
16035static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
16036 struct cfg80211_connect_params *req)
16037{
16038 return -EPERM;
16039}
16040#endif
16041
Abhishek Singhe3beee22017-07-31 15:35:40 +053016042/**
16043 * wlan_hdd_check_ht20_ht40_ind() - check if Supplicant has indicated to
16044 * connect in HT20 mode
16045 * @hdd_ctx: hdd context
16046 * @adapter: Pointer to the HDD adapter
16047 * @req: Pointer to the structure cfg_connect_params receieved from user space
16048 *
16049 * This function will check if supplicant has indicated to to connect in HT20
16050 * mode. this is currently applicable only for 2.4Ghz mode only.
16051 * if feature is enabled and supplicant indicate HT20 set
16052 * force_24ghz_in_ht20 to true to force 2.4Ghz in HT20 else set it to false.
16053 *
16054 * Return: void
16055 */
16056#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
16057static void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
16058 hdd_adapter_t *adapter,
16059 struct cfg80211_connect_params *req)
16060{
16061 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
16062 tCsrRoamProfile *roam_profile;
16063
16064 roam_profile = &wext_state->roamProfile;
16065 roam_profile->force_24ghz_in_ht20 = false;
16066 if (hdd_ctx->cfg_ini->override_ht20_40_24g &&
16067 !(req->ht_capa.cap_info &
16068 IEEE80211_HT_CAP_SUP_WIDTH_20_40))
16069 roam_profile->force_24ghz_in_ht20 = true;
16070
16071 hddLog(LOG1, FL("req->ht_capa.cap_info %x override_ht20_40_24g %d"),
16072 req->ht_capa.cap_info, hdd_ctx->cfg_ini->override_ht20_40_24g);
16073}
16074#else
16075static inline void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
16076 hdd_adapter_t *adapter,
16077 struct cfg80211_connect_params *req)
16078{
16079 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
16080 tCsrRoamProfile *roam_profile;
16081
16082 roam_profile = &wext_state->roamProfile;
16083 roam_profile->force_24ghz_in_ht20 = false;
16084}
16085#endif
16086
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016087/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053016088 * FUNCTION: __wlan_hdd_cfg80211_connect
16089 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070016090 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016091static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016092 struct net_device *ndev,
16093 struct cfg80211_connect_params *req
16094 )
16095{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016096 int status;
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016097 u16 channel;
Edhar, Mahesh Kumar496c7f72016-03-18 12:47:44 +053016098#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) || \
16099 defined(CFG80211_BSSID_HINT_BACKPORT)
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016100 const u8 *bssid_hint = req->bssid_hint;
16101#else
16102 const u8 *bssid_hint = NULL;
16103#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016104 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070016105 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053016106 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070016107
16108 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016109
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016110 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16111 TRACE_CODE_HDD_CFG80211_CONNECT,
16112 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016113 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016114 "%s: device_mode = %s (%d)", __func__,
16115 hdd_device_modetoString(pAdapter->device_mode),
16116 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070016117
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016118 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080016119 if (!pHddCtx)
16120 {
16121 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16122 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053016123 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080016124 }
16125
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016126 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016127 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070016128 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016129 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016130 }
16131
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053016132 if (wlan_hdd_check_and_stop_mon(pAdapter, true))
16133 return -EINVAL;
16134
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053016135 status = wlan_hdd_reassoc_bssid_hint(pAdapter, req);
16136 if (0 == status)
16137 return status;
16138
Agarwal Ashish51325b52014-06-16 16:50:49 +053016139
Jeff Johnson295189b2012-06-20 16:38:30 -070016140#ifdef WLAN_BTAMP_FEATURE
16141 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016142 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070016143 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016144 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016145 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080016146 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070016147 }
16148#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016149
16150 //If Device Mode is Station Concurrent Sessions Exit BMps
16151 //P2P Mode will be taken care in Open/close adapter
16152 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053016153 (vos_concurrent_open_sessions_running())) {
16154 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
16155 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016156 }
16157
16158 /*Try disconnecting if already in connected state*/
16159 status = wlan_hdd_try_disconnect(pAdapter);
16160 if ( 0 > status)
16161 {
16162 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
16163 " connection"));
16164 return -EALREADY;
16165 }
Agrawal Ashish559530c2015-12-01 18:04:20 +053016166 /* Check for max concurrent connections after doing disconnect if any*/
16167 if (vos_max_concurrent_connections_reached()) {
16168 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
16169 return -ECONNREFUSED;
16170 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016171
Jeff Johnson295189b2012-06-20 16:38:30 -070016172 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016173 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070016174
16175 if ( 0 > status)
16176 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016177 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070016178 __func__);
16179 return status;
16180 }
Sravan Kumar Kairam589c5722016-01-27 20:28:53 +053016181
16182 if (pHddCtx->spoofMacAddr.isEnabled)
16183 {
16184 hddLog(VOS_TRACE_LEVEL_INFO,
16185 "%s: MAC Spoofing enabled ", __func__);
16186 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
16187 * to fill TxBds for probe request during SSID scan which may happen
16188 * as part of connect command
16189 */
16190 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
16191 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
16192 if (status != VOS_STATUS_SUCCESS)
16193 return -ECONNREFUSED;
16194 }
16195
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016196 if (req->channel)
16197 channel = req->channel->hw_value;
Mohit Khanna765234a2012-09-11 15:08:35 -070016198 else
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016199 channel = 0;
Kapil Gupta312028a2016-10-25 14:15:20 +053016200
16201 /* Abort if any scan is going on */
16202 status = wlan_hdd_scan_abort(pAdapter);
16203 if (0 != status)
16204 hddLog(VOS_TRACE_LEVEL_ERROR, FL("scan abort failed"));
16205
Abhishek Singhe3beee22017-07-31 15:35:40 +053016206 wlan_hdd_check_ht20_ht40_ind(pHddCtx, pAdapter, req);
16207
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016208 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
16209 req->ssid_len, req->bssid,
16210 bssid_hint, channel);
Jeff Johnson295189b2012-06-20 16:38:30 -070016211
Sushant Kaushikd7083982015-03-18 14:33:24 +053016212 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070016213 {
16214 //ReEnable BMPS if disabled
16215 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
16216 (NULL != pHddCtx))
16217 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053016218 if (pHddCtx->hdd_wlan_suspended)
16219 {
16220 hdd_set_pwrparams(pHddCtx);
16221 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016222 //ReEnable Bmps and Imps back
16223 hdd_enable_bmps_imps(pHddCtx);
16224 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053016225 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070016226 return status;
16227 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016228 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070016229 EXIT();
16230 return status;
16231}
16232
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016233static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
16234 struct net_device *ndev,
16235 struct cfg80211_connect_params *req)
16236{
16237 int ret;
16238 vos_ssr_protect(__func__);
16239 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
16240 vos_ssr_unprotect(__func__);
16241
16242 return ret;
16243}
Jeff Johnson295189b2012-06-20 16:38:30 -070016244
16245/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016246 * FUNCTION: wlan_hdd_disconnect
16247 * This function is used to issue a disconnect request to SME
16248 */
16249int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
16250{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053016251 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016252 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016253 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053016254 long ret;
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053016255 eConnectionState prev_conn_state;
Yeshwanth Sriram Guntukaae784d22017-12-06 14:20:51 +053016256 uint32_t wait_time = WLAN_WAIT_TIME_DISCONNECT;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016257
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016258 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016259
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016260 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016261 if (0 != status)
16262 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016263 return status;
16264 }
Abhishek Singh07e4a892015-11-23 11:29:57 +053016265 /* Indicate sme of disconnect so that in progress connection or preauth
16266 * can be aborted
16267 */
16268 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
Sushant Kaushikb4834d22015-07-15 15:29:05 +053016269 pAdapter->sessionId);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016270 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053016271
Agarwal Ashish47d18112014-08-04 19:55:07 +053016272 /* Need to apply spin lock before decreasing active sessions
16273 * as there can be chance for double decrement if context switch
16274 * Calls hdd_DisConnectHandler.
16275 */
16276
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053016277 prev_conn_state = pHddStaCtx->conn_info.connState;
16278
Agarwal Ashish47d18112014-08-04 19:55:07 +053016279 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053016280 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
16281 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053016282 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
16283 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053016284 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
16285 spin_unlock_bh(&pAdapter->lock_for_active_session);
Abhishek Singh78c691f2017-11-30 13:48:44 +053016286 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053016287
Abhishek Singhf4669da2014-05-26 15:07:49 +053016288 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053016289 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
16290
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016291 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016292
Mihir Shete182a0b22014-08-18 16:08:48 +053016293 /*
16294 * stop tx queues before deleting STA/BSS context from the firmware.
16295 * tx has to be disabled because the firmware can get busy dropping
16296 * the tx frames after BSS/STA has been deleted and will not send
16297 * back a response resulting in WDI timeout
16298 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053016299 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053016300 netif_tx_disable(pAdapter->dev);
16301 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053016302
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053016303 wlan_hdd_check_and_stop_mon(pAdapter, true);
16304
Mihir Shete182a0b22014-08-18 16:08:48 +053016305 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016306 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
16307 pAdapter->sessionId, reason);
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053016308 if((eHAL_STATUS_CMD_NOT_QUEUED == status) &&
16309 prev_conn_state != eConnectionState_Connecting)
16310 {
16311 hddLog(LOG1,
16312 FL("status = %d, already disconnected"), status);
16313 result = 0;
Yeshwanth Sriram Guntukaae784d22017-12-06 14:20:51 +053016314 /*
16315 * Wait here instead of returning directly. This will block the
16316 * next connect command and allow processing of the disconnect
16317 * in SME else we might hit some race conditions leading to SME
16318 * and HDD out of sync. As disconnect is already in progress,
16319 * wait here for 1 sec instead of 5 sec.
16320 */
16321 wait_time = WLAN_WAIT_DISCONNECT_ALREADY_IN_PROGRESS;
16322 goto wait_for_disconnect;
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053016323 }
16324 /*
16325 * Wait here instead of returning directly, this will block the next
16326 * connect command and allow processing of the scan for ssid and
16327 * the previous connect command in CSR. Else we might hit some
16328 * race conditions leading to SME and HDD out of sync.
16329 */
16330 else if(eHAL_STATUS_CMD_NOT_QUEUED == status)
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016331 {
16332 hddLog(LOG1,
16333 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053016334 }
16335 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016336 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016337 hddLog(LOGE,
16338 FL("csrRoamDisconnect failure, returned %d"),
16339 (int)status);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053016340 result = -EINVAL;
16341 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016342 }
Yeshwanth Sriram Guntukaae784d22017-12-06 14:20:51 +053016343wait_for_disconnect:
16344 ret = wait_for_completion_timeout(&pAdapter->disconnect_comp_var,
16345 msecs_to_jiffies(wait_time));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016346 if (!ret && (eHAL_STATUS_CMD_NOT_QUEUED != status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016347 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016348 hddLog(LOGE,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053016349 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053016350 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053016351 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053016352disconnected:
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016353 hddLog(LOG1,
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053016354 FL("Set HDD connState to eConnectionState_NotConnected"));
16355 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Mahesh A Saptasagar936ffc32016-05-25 11:27:43 +053016356#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
16357 /* Sending disconnect event to userspace for kernel version < 3.11
16358 * is handled by __cfg80211_disconnect call to __cfg80211_disconnected
16359 */
16360 hddLog(LOG1, FL("Send disconnected event to userspace"));
16361
Mahesh A Saptasagarf5859b12016-06-01 17:17:50 +053016362 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, true,
Mahesh A Saptasagar936ffc32016-05-25 11:27:43 +053016363 WLAN_REASON_UNSPECIFIED);
16364#endif
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053016365
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016366 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053016367 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016368}
16369
16370
16371/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016372 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070016373 * This function is used to issue a disconnect request to SME
16374 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016375static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016376 struct net_device *dev,
16377 u16 reason
16378 )
16379{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016380 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016381 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053016382 tCsrRoamProfile *pRoamProfile;
16383 hdd_station_ctx_t *pHddStaCtx;
16384 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053016385#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016386 tANI_U8 staIdx;
16387#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016388
Jeff Johnson295189b2012-06-20 16:38:30 -070016389 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016390
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053016391 if (!pAdapter) {
16392 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
16393 return -EINVAL;
16394 }
16395
16396 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16397 if (!pHddStaCtx) {
16398 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
16399 return -EINVAL;
16400 }
16401
16402 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16403 status = wlan_hdd_validate_context(pHddCtx);
16404 if (0 != status)
16405 {
16406 return status;
16407 }
16408
16409 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
16410
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016411 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16412 TRACE_CODE_HDD_CFG80211_DISCONNECT,
16413 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016414 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
16415 __func__, hdd_device_modetoString(pAdapter->device_mode),
16416 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070016417
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016418 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
16419 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070016420
Jeff Johnson295189b2012-06-20 16:38:30 -070016421 if (NULL != pRoamProfile)
16422 {
16423 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053016424 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
16425 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070016426 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016427 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070016428 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053016429 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070016430 switch(reason)
16431 {
16432 case WLAN_REASON_MIC_FAILURE:
16433 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
16434 break;
16435
16436 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
16437 case WLAN_REASON_DISASSOC_AP_BUSY:
16438 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
16439 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
16440 break;
16441
16442 case WLAN_REASON_PREV_AUTH_NOT_VALID:
16443 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053016444 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070016445 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
16446 break;
16447
Jeff Johnson295189b2012-06-20 16:38:30 -070016448 default:
16449 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
16450 break;
16451 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053016452 pScanInfo = &pHddCtx->scan_info;
16453 if (pScanInfo->mScanPending)
16454 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053016455 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053016456 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053016457 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053016458 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053016459 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053016460 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016461#ifdef FEATURE_WLAN_TDLS
16462 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080016463 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016464 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080016465 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
16466 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016467 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016468 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080016469 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053016470 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016471 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080016472 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016473 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016474 status = sme_DeleteTdlsPeerSta(
16475 WLAN_HDD_GET_HAL_CTX(pAdapter),
16476 pAdapter->sessionId,
16477 mac);
16478 if (status != eHAL_STATUS_SUCCESS) {
16479 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
16480 return -EPERM;
16481 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016482 }
16483 }
16484#endif
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053016485
16486 hddLog(LOG1, FL("Disconnecting with reasoncode:%u connState %d"),
16487 reasonCode,
16488 pHddStaCtx->conn_info.connState);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016489 status = wlan_hdd_disconnect(pAdapter, reasonCode);
16490 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070016491 {
16492 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080016493 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016494 __func__, (int)status );
16495 return -EINVAL;
16496 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016497 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053016498 else
16499 {
16500 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
16501 "called while in %d state", __func__,
16502 pHddStaCtx->conn_info.connState);
16503 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016504 }
16505 else
16506 {
16507 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
16508 }
16509
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016510 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016511 return status;
16512}
16513
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016514static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
16515 struct net_device *dev,
16516 u16 reason
16517 )
16518{
16519 int ret;
16520 vos_ssr_protect(__func__);
16521 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
16522 vos_ssr_unprotect(__func__);
16523
16524 return ret;
16525}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016526
Jeff Johnson295189b2012-06-20 16:38:30 -070016527/*
16528 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016529 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070016530 * settings in IBSS mode.
16531 */
16532static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016533 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070016534 struct cfg80211_ibss_params *params
16535 )
16536{
16537 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016538 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016539 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
16540 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016541
Jeff Johnson295189b2012-06-20 16:38:30 -070016542 ENTER();
16543
16544 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070016545 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070016546
16547 if (params->ie_len && ( NULL != params->ie) )
16548 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016549 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
16550 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070016551 {
16552 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
16553 encryptionType = eCSR_ENCRYPT_TYPE_AES;
16554 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016555 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070016556 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070016557 tDot11fIEWPA dot11WPAIE;
16558 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016559 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070016560
Wilson Yang00256342013-10-10 23:13:38 -070016561 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016562 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
16563 params->ie_len, DOT11F_EID_WPA);
16564 if ( NULL != ie )
16565 {
16566 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
16567 // Unpack the WPA IE
16568 //Skip past the EID byte and length byte - and four byte WiFi OUI
16569 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
16570 &ie[2+4],
16571 ie[1] - 4,
16572 &dot11WPAIE);
16573 /*Extract the multicast cipher, the encType for unicast
16574 cipher for wpa-none is none*/
16575 encryptionType =
16576 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
16577 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016578 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016579
Jeff Johnson295189b2012-06-20 16:38:30 -070016580 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
16581
16582 if (0 > status)
16583 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016584 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070016585 __func__);
16586 return status;
16587 }
16588 }
16589
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016590 pWextState->roamProfile.AuthType.authType[0] =
16591 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070016592 eCSR_AUTH_TYPE_OPEN_SYSTEM;
16593
16594 if (params->privacy)
16595 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016596 /* Security enabled IBSS, At this time there is no information available
16597 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070016598 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016599 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070016600 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016601 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070016602 *enable privacy bit in beacons */
16603
16604 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
16605 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070016606 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
16607 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070016608 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
16609 pWextState->roamProfile.EncryptionType.numEntries = 1;
16610 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070016611 return status;
16612}
16613
16614/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016615 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016616 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070016617 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016618static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016619 struct net_device *dev,
16620 struct cfg80211_ibss_params *params
16621 )
16622{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016623 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070016624 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
16625 tCsrRoamProfile *pRoamProfile;
16626 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016627 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16628 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016629 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070016630
16631 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016632
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016633 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16634 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
16635 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016636 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016637 "%s: device_mode = %s (%d)", __func__,
16638 hdd_device_modetoString(pAdapter->device_mode),
16639 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070016640
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016641 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016642 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070016643 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016644 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016645 }
16646
16647 if (NULL == pWextState)
16648 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016649 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070016650 __func__);
16651 return -EIO;
16652 }
16653
Agarwal Ashish51325b52014-06-16 16:50:49 +053016654 if (vos_max_concurrent_connections_reached()) {
16655 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
16656 return -ECONNREFUSED;
16657 }
16658
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016659 /*Try disconnecting if already in connected state*/
16660 status = wlan_hdd_try_disconnect(pAdapter);
16661 if ( 0 > status)
16662 {
16663 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
16664 " IBSS connection"));
16665 return -EALREADY;
16666 }
16667
Jeff Johnson295189b2012-06-20 16:38:30 -070016668 pRoamProfile = &pWextState->roamProfile;
16669
16670 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
16671 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016672 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080016673 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016674 return -EINVAL;
16675 }
16676
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070016677 /* BSSID is provided by upper layers hence no need to AUTO generate */
16678 if (NULL != params->bssid) {
16679 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
16680 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
16681 hddLog (VOS_TRACE_LEVEL_ERROR,
16682 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
16683 return -EIO;
16684 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016685 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070016686 }
krunal sonie9002db2013-11-25 14:24:17 -080016687 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
16688 {
16689 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
16690 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
16691 {
16692 hddLog (VOS_TRACE_LEVEL_ERROR,
16693 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
16694 return -EIO;
16695 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016696
16697 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080016698 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016699 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080016700 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070016701
Jeff Johnson295189b2012-06-20 16:38:30 -070016702 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070016703 if (NULL !=
16704#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
16705 params->chandef.chan)
16706#else
16707 params->channel)
16708#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016709 {
16710 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016711 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
16712 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
16713 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
16714 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070016715
16716 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016717 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070016718 ieee80211_frequency_to_channel(
16719#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
16720 params->chandef.chan->center_freq);
16721#else
16722 params->channel->center_freq);
16723#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016724
16725 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
16726 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070016727 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016728 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
16729 __func__);
16730 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070016731 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016732
16733 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070016734 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016735 if (channelNum == validChan[indx])
16736 {
16737 break;
16738 }
16739 }
16740 if (indx >= numChans)
16741 {
16742 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016743 __func__, channelNum);
16744 return -EINVAL;
16745 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016746 /* Set the Operational Channel */
16747 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
16748 channelNum);
16749 pRoamProfile->ChannelInfo.numOfChannels = 1;
16750 pHddStaCtx->conn_info.operationChannel = channelNum;
16751 pRoamProfile->ChannelInfo.ChannelList =
16752 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070016753 }
16754
16755 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016756 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070016757 if (status < 0)
16758 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016759 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070016760 __func__);
16761 return status;
16762 }
16763
16764 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016765 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Abhishek Singh4d924682015-11-17 15:23:06 +053016766 params->ssid_len, (const u8 *)&bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016767 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070016768
16769 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070016770 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016771
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016772 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016773 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016774}
16775
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016776static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
16777 struct net_device *dev,
16778 struct cfg80211_ibss_params *params
16779 )
16780{
16781 int ret = 0;
16782
16783 vos_ssr_protect(__func__);
16784 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
16785 vos_ssr_unprotect(__func__);
16786
16787 return ret;
16788}
16789
Jeff Johnson295189b2012-06-20 16:38:30 -070016790/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016791 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016792 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070016793 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016794static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016795 struct net_device *dev
16796 )
16797{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016798 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016799 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
16800 tCsrRoamProfile *pRoamProfile;
16801 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016802 int status;
Abhishek Singh69de3302016-11-11 16:44:32 +053016803 eHalStatus hal_status;
Abhishek Singh7cd040e2016-01-07 10:51:04 +053016804#ifdef WLAN_FEATURE_RMC
16805 tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN] = {0};
16806#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016807
16808 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016809
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016810 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16811 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
16812 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016813 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016814 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016815 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016816 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016817 }
16818
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016819 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
16820 hdd_device_modetoString(pAdapter->device_mode),
16821 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070016822 if (NULL == pWextState)
16823 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016824 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070016825 __func__);
16826 return -EIO;
16827 }
16828
16829 pRoamProfile = &pWextState->roamProfile;
16830
16831 /* Issue disconnect only if interface type is set to IBSS */
16832 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
16833 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016834 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070016835 __func__);
16836 return -EINVAL;
16837 }
16838
Abhishek Singh7cd040e2016-01-07 10:51:04 +053016839#ifdef WLAN_FEATURE_RMC
16840 /* Clearing add IE of beacon */
16841 if (ccmCfgSetStr(pHddCtx->hHal,
16842 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0],
16843 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN,
16844 NULL, eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
16845 {
16846 hddLog (VOS_TRACE_LEVEL_ERROR,
16847 "%s: unable to clear PROBE_RSP_BCN_ADDNIE_DATA", __func__);
16848 return -EINVAL;
16849 }
16850 if (ccmCfgSetInt(pHddCtx->hHal,
16851 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0, NULL,
16852 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
16853 {
16854 hddLog (VOS_TRACE_LEVEL_ERROR,
16855 "%s: unable to clear WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
16856 __func__);
16857 return -EINVAL;
16858 }
16859
16860 // Reset WNI_CFG_PROBE_RSP Flags
16861 wlan_hdd_reset_prob_rspies(pAdapter);
16862
16863 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
16864 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 0,NULL,
16865 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
16866 {
16867 hddLog (VOS_TRACE_LEVEL_ERROR,
16868 "%s: unable to clear WNI_CFG_PROBE_RSP_ADDNIE_FLAG",
16869 __func__);
16870 return -EINVAL;
16871 }
16872#endif
16873
Jeff Johnson295189b2012-06-20 16:38:30 -070016874 /* Issue Disconnect request */
16875 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singh69de3302016-11-11 16:44:32 +053016876 hal_status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
16877 pAdapter->sessionId,
16878 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
16879 if (!HAL_STATUS_SUCCESS(hal_status)) {
16880 hddLog(LOGE,
16881 FL("sme_RoamDisconnect failed hal_status(%d)"),
16882 hal_status);
16883 return -EAGAIN;
16884 }
16885 status = wait_for_completion_timeout(
16886 &pAdapter->disconnect_comp_var,
16887 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
16888 if (!status) {
16889 hddLog(LOGE,
16890 FL("wait on disconnect_comp_var failed"));
16891 return -ETIMEDOUT;
16892 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016893
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016894 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016895 return 0;
16896}
16897
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016898static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
16899 struct net_device *dev
16900 )
16901{
16902 int ret = 0;
16903
16904 vos_ssr_protect(__func__);
16905 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
16906 vos_ssr_unprotect(__func__);
16907
16908 return ret;
16909}
16910
Jeff Johnson295189b2012-06-20 16:38:30 -070016911/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016912 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070016913 * This function is used to set the phy parameters
16914 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
16915 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016916static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016917 u32 changed)
16918{
16919 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
16920 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016921 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016922
16923 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016924
16925 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016926 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
16927 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016928
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016929 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016930 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016931 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016932 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016933 }
16934
Jeff Johnson295189b2012-06-20 16:38:30 -070016935 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
16936 {
16937 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
16938 WNI_CFG_RTS_THRESHOLD_STAMAX :
16939 wiphy->rts_threshold;
16940
16941 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016942 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070016943 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016944 hddLog(VOS_TRACE_LEVEL_ERROR,
16945 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016946 __func__, rts_threshold);
16947 return -EINVAL;
16948 }
16949
16950 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
16951 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016952 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016953 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016954 hddLog(VOS_TRACE_LEVEL_ERROR,
16955 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016956 __func__, rts_threshold);
16957 return -EIO;
16958 }
16959
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016960 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016961 rts_threshold);
16962 }
16963
16964 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
16965 {
16966 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
16967 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
16968 wiphy->frag_threshold;
16969
16970 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016971 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016972 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016973 hddLog(VOS_TRACE_LEVEL_ERROR,
16974 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016975 frag_threshold);
16976 return -EINVAL;
16977 }
16978
16979 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
16980 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016981 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016982 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016983 hddLog(VOS_TRACE_LEVEL_ERROR,
16984 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016985 __func__, frag_threshold);
16986 return -EIO;
16987 }
16988
16989 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
16990 frag_threshold);
16991 }
16992
16993 if ((changed & WIPHY_PARAM_RETRY_SHORT)
16994 || (changed & WIPHY_PARAM_RETRY_LONG))
16995 {
16996 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
16997 wiphy->retry_short :
16998 wiphy->retry_long;
16999
17000 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
17001 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
17002 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017003 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017004 __func__, retry_value);
17005 return -EINVAL;
17006 }
17007
17008 if (changed & WIPHY_PARAM_RETRY_SHORT)
17009 {
17010 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
17011 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017012 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017013 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017014 hddLog(VOS_TRACE_LEVEL_ERROR,
17015 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017016 __func__, retry_value);
17017 return -EIO;
17018 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017019 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017020 __func__, retry_value);
17021 }
17022 else if (changed & WIPHY_PARAM_RETRY_SHORT)
17023 {
17024 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
17025 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017026 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017027 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017028 hddLog(VOS_TRACE_LEVEL_ERROR,
17029 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017030 __func__, retry_value);
17031 return -EIO;
17032 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017033 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017034 __func__, retry_value);
17035 }
17036 }
17037
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017038 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017039 return 0;
17040}
17041
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017042static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
17043 u32 changed)
17044{
17045 int ret;
17046
17047 vos_ssr_protect(__func__);
17048 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
17049 vos_ssr_unprotect(__func__);
17050
17051 return ret;
17052}
17053
Jeff Johnson295189b2012-06-20 16:38:30 -070017054/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017055 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070017056 * This function is used to set the txpower
17057 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017058static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070017059#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17060 struct wireless_dev *wdev,
17061#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017062#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017063 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070017064#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017065 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070017066#endif
17067 int dbm)
17068{
17069 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017070 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070017071 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
17072 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017073 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017074
17075 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017076
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017077 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17078 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
17079 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017080 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017081 if (0 != status)
17082 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017083 return status;
17084 }
17085
17086 hHal = pHddCtx->hHal;
17087
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017088 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
17089 dbm, ccmCfgSetCallback,
17090 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017091 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017092 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070017093 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
17094 return -EIO;
17095 }
17096
17097 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
17098 dbm);
17099
17100 switch(type)
17101 {
17102 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
17103 /* Fall through */
17104 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
17105 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
17106 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017107 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
17108 __func__);
17109 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070017110 }
17111 break;
17112 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017113 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070017114 __func__);
17115 return -EOPNOTSUPP;
17116 break;
17117 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017118 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
17119 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070017120 return -EIO;
17121 }
17122
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017123 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017124 return 0;
17125}
17126
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017127static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
17128#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17129 struct wireless_dev *wdev,
17130#endif
17131#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
17132 enum tx_power_setting type,
17133#else
17134 enum nl80211_tx_power_setting type,
17135#endif
17136 int dbm)
17137{
17138 int ret;
17139 vos_ssr_protect(__func__);
17140 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
17141#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17142 wdev,
17143#endif
17144#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
17145 type,
17146#else
17147 type,
17148#endif
17149 dbm);
17150 vos_ssr_unprotect(__func__);
17151
17152 return ret;
17153}
17154
Jeff Johnson295189b2012-06-20 16:38:30 -070017155/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017156 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070017157 * This function is used to read the txpower
17158 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017159static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070017160#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17161 struct wireless_dev *wdev,
17162#endif
17163 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070017164{
17165
17166 hdd_adapter_t *pAdapter;
17167 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017168 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017169
Jeff Johnsone7245742012-09-05 17:12:55 -070017170 ENTER();
17171
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017172 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017173 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017174 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017175 *dbm = 0;
17176 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017177 }
17178
Jeff Johnson295189b2012-06-20 16:38:30 -070017179 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
17180 if (NULL == pAdapter)
17181 {
17182 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
17183 return -ENOENT;
17184 }
17185
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017186 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17187 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
17188 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070017189 wlan_hdd_get_classAstats(pAdapter);
17190 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
17191
Jeff Johnsone7245742012-09-05 17:12:55 -070017192 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017193 return 0;
17194}
17195
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017196static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
17197#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17198 struct wireless_dev *wdev,
17199#endif
17200 int *dbm)
17201{
17202 int ret;
17203
17204 vos_ssr_protect(__func__);
17205 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
17206#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17207 wdev,
17208#endif
17209 dbm);
17210 vos_ssr_unprotect(__func__);
17211
17212 return ret;
17213}
17214
Dustin Brown8c1d4092017-07-28 18:08:01 +053017215/*
17216 * wlan_hdd_fill_summary_stats() - populate station_info summary stats
17217 * @stats: summary stats to use as a source
17218 * @info: kernel station_info struct to use as a destination
17219 *
17220 * Return: None
17221 */
17222static void wlan_hdd_fill_summary_stats(tCsrSummaryStatsInfo *stats,
17223 struct station_info *info)
17224{
17225 int i;
17226
17227 info->rx_packets = stats->rx_frm_cnt;
17228 info->tx_packets = 0;
17229 info->tx_retries = 0;
17230 info->tx_failed = 0;
17231
17232 for (i = 0; i < 4; ++i) {
17233 info->tx_packets += stats->tx_frm_cnt[i];
17234 info->tx_retries += stats->multiple_retry_cnt[i];
17235 info->tx_failed += stats->fail_cnt[i];
17236 }
17237
17238 info->filled |= STATION_INFO_TX_PACKETS |
17239 STATION_INFO_TX_RETRIES |
17240 STATION_INFO_TX_FAILED |
17241 STATION_INFO_RX_PACKETS;
17242}
17243
17244/**
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017245 * wlan_hdd_sap_get_sta_rssi() - get RSSI of the SAP client
17246 * @adapter: sap adapter pointer
17247 * @staid: station id of the client
17248 * @rssi: rssi value to fill
17249 *
17250 * Return: None
17251 */
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053017252void
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017253wlan_hdd_sap_get_sta_rssi(hdd_adapter_t *adapter, uint8_t staid, s8 *rssi)
17254{
17255 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
17256
17257 WLANTL_GetSAPStaRSSi(pVosContext, staid, rssi);
17258}
17259
17260/**
Dustin Brown8c1d4092017-07-28 18:08:01 +053017261 * wlan_hdd_get_sap_stats() - get aggregate SAP stats
17262 * @adapter: sap adapter to get stats for
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017263 * @mac: mac address of the station
Dustin Brown8c1d4092017-07-28 18:08:01 +053017264 * @info: kernel station_info struct to populate
17265 *
17266 * Fetch the vdev-level aggregate stats for the given SAP adapter. This is to
17267 * support "station dump" and "station get" for SAP vdevs, even though they
17268 * aren't technically stations.
17269 *
17270 * Return: errno
17271 */
17272static int
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017273wlan_hdd_get_sap_stats(hdd_adapter_t *adapter,
17274#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17275 const u8* mac,
17276#else
17277 u8* mac,
17278#endif
17279 struct station_info *info)
Dustin Brown8c1d4092017-07-28 18:08:01 +053017280{
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017281 v_MACADDR_t *peerMacAddr;
17282 uint8_t staid;
Dustin Brown8c1d4092017-07-28 18:08:01 +053017283 VOS_STATUS status;
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017284 bool bc_mac_addr;
Dustin Brown8c1d4092017-07-28 18:08:01 +053017285
17286 status = wlan_hdd_get_station_stats(adapter);
17287 if (!VOS_IS_STATUS_SUCCESS(status)) {
17288 hddLog(VOS_TRACE_LEVEL_ERROR,
17289 "Failed to get SAP stats; status:%d", status);
17290 return 0;
17291 }
17292
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017293 peerMacAddr = (v_MACADDR_t *)mac;
17294 bc_mac_addr = vos_is_macaddr_broadcast(peerMacAddr);
17295 staid = hdd_sta_id_find_from_mac_addr(adapter, peerMacAddr);
17296 hddLog(VOS_TRACE_LEVEL_INFO, "Get SAP stats for sta id:%d", staid);
17297
17298 if (staid < WLAN_MAX_STA_COUNT && !bc_mac_addr) {
17299 wlan_hdd_sap_get_sta_rssi(adapter, staid, &info->signal);
17300 info->filled |= STATION_INFO_SIGNAL;
17301 }
17302
Dustin Brown8c1d4092017-07-28 18:08:01 +053017303 wlan_hdd_fill_summary_stats(&adapter->hdd_stats.summary_stat, info);
17304
17305 return 0;
17306}
17307
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017308static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017309#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17310 const u8* mac,
17311#else
17312 u8* mac,
17313#endif
17314 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070017315{
17316 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
17317 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17318 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053017319 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070017320
17321 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
17322 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070017323
17324 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
17325 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
17326 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
17327 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
17328 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
17329 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
17330 tANI_U16 maxRate = 0;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053017331 int8_t snr = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070017332 tANI_U16 myRate;
17333 tANI_U16 currentRate = 0;
17334 tANI_U8 maxSpeedMCS = 0;
17335 tANI_U8 maxMCSIdx = 0;
17336 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053017337 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070017338 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017339 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017340
Leo Chang6f8870f2013-03-26 18:11:36 -070017341#ifdef WLAN_FEATURE_11AC
17342 tANI_U32 vht_mcs_map;
17343 eDataRate11ACMaxMcs vhtMaxMcs;
17344#endif /* WLAN_FEATURE_11AC */
17345
Jeff Johnsone7245742012-09-05 17:12:55 -070017346 ENTER();
17347
Dustin Brown8c1d4092017-07-28 18:08:01 +053017348 status = wlan_hdd_validate_context(pHddCtx);
17349 if (0 != status)
17350 {
17351 return status;
17352 }
17353
17354 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017355 return wlan_hdd_get_sap_stats(pAdapter, mac, sinfo);
Dustin Brown8c1d4092017-07-28 18:08:01 +053017356
Jeff Johnson295189b2012-06-20 16:38:30 -070017357 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
17358 (0 == ssidlen))
17359 {
17360 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
17361 " Invalid ssidlen, %d", __func__, ssidlen);
17362 /*To keep GUI happy*/
17363 return 0;
17364 }
17365
Mukul Sharma811205f2014-07-09 21:07:30 +053017366 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
17367 {
17368 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17369 "%s: Roaming in progress, so unable to proceed this request", __func__);
Sachin Ahuja81ab1812016-08-19 21:35:58 +053017370 /* return a cached value */
17371 sinfo->signal = pAdapter->rssi;
Mukul Sharma811205f2014-07-09 21:07:30 +053017372 return 0;
17373 }
17374
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053017375 wlan_hdd_get_station_stats(pAdapter);
17376 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070017377
Kiet Lam3b17fc82013-09-27 05:24:08 +053017378 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053017379 wlan_hdd_get_snr(pAdapter, &snr);
17380 pHddStaCtx->conn_info.signal = sinfo->signal;
17381 pHddStaCtx->conn_info.noise = pHddStaCtx->conn_info.signal - snr;
Kiet Lam3b17fc82013-09-27 05:24:08 +053017382 sinfo->filled |= STATION_INFO_SIGNAL;
17383
c_hpothu09f19542014-05-30 21:53:31 +053017384 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053017385 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
17386 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053017387 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053017388 {
17389 rate_flags = pAdapter->maxRateFlags;
17390 }
c_hpothu44ff4e02014-05-08 00:13:57 +053017391
Jeff Johnson295189b2012-06-20 16:38:30 -070017392 //convert to the UI units of 100kbps
17393 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
17394
17395#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070017396 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 -070017397 sinfo->signal,
17398 pCfg->reportMaxLinkSpeed,
17399 myRate,
17400 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070017401 (int) pCfg->linkSpeedRssiMid,
17402 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070017403 (int) rate_flags,
17404 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070017405#endif //LINKSPEED_DEBUG_ENABLED
17406
17407 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
17408 {
17409 // we do not want to necessarily report the current speed
17410 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
17411 {
17412 // report the max possible speed
17413 rssidx = 0;
17414 }
17415 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
17416 {
17417 // report the max possible speed with RSSI scaling
17418 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
17419 {
17420 // report the max possible speed
17421 rssidx = 0;
17422 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070017423 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070017424 {
17425 // report middle speed
17426 rssidx = 1;
17427 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070017428 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
17429 {
17430 // report middle speed
17431 rssidx = 2;
17432 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017433 else
17434 {
17435 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070017436 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070017437 }
17438 }
17439 else
17440 {
17441 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
17442 hddLog(VOS_TRACE_LEVEL_ERROR,
17443 "%s: Invalid value for reportMaxLinkSpeed: %u",
17444 __func__, pCfg->reportMaxLinkSpeed);
17445 rssidx = 0;
17446 }
17447
17448 maxRate = 0;
17449
17450 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053017451 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
17452 OperationalRates, &ORLeng))
17453 {
17454 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
17455 /*To keep GUI happy*/
17456 return 0;
17457 }
17458
Jeff Johnson295189b2012-06-20 16:38:30 -070017459 for (i = 0; i < ORLeng; i++)
17460 {
Jeff Johnsone7245742012-09-05 17:12:55 -070017461 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070017462 {
17463 /* Validate Rate Set */
17464 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
17465 {
17466 currentRate = supported_data_rate[j].supported_rate[rssidx];
17467 break;
17468 }
17469 }
17470 /* Update MAX rate */
17471 maxRate = (currentRate > maxRate)?currentRate:maxRate;
17472 }
17473
17474 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053017475 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
17476 ExtendedRates, &ERLeng))
17477 {
17478 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
17479 /*To keep GUI happy*/
17480 return 0;
17481 }
17482
Jeff Johnson295189b2012-06-20 16:38:30 -070017483 for (i = 0; i < ERLeng; i++)
17484 {
Jeff Johnsone7245742012-09-05 17:12:55 -070017485 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070017486 {
17487 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
17488 {
17489 currentRate = supported_data_rate[j].supported_rate[rssidx];
17490 break;
17491 }
17492 }
17493 /* Update MAX rate */
17494 maxRate = (currentRate > maxRate)?currentRate:maxRate;
17495 }
c_hpothu79aab322014-07-14 21:11:01 +053017496
Kiet Lamb69f8dc2013-11-15 15:34:27 +053017497 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053017498 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053017499 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053017500 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070017501 {
c_hpothu79aab322014-07-14 21:11:01 +053017502 if (rate_flags & eHAL_TX_RATE_VHT80)
17503 mode = 2;
17504 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
17505 mode = 1;
17506 else
17507 mode = 0;
17508
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053017509 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
17510 MCSRates, &MCSLeng))
17511 {
17512 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
17513 /*To keep GUI happy*/
17514 return 0;
17515 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017516 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070017517#ifdef WLAN_FEATURE_11AC
17518 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017519 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070017520 {
Leo Chang6f8870f2013-03-26 18:11:36 -070017521 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017522 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070017523 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070017524 {
Leo Chang6f8870f2013-03-26 18:11:36 -070017525 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070017526 }
Leo Chang6f8870f2013-03-26 18:11:36 -070017527 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070017528 {
Leo Chang6f8870f2013-03-26 18:11:36 -070017529 maxMCSIdx = 7;
17530 }
17531 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
17532 {
17533 maxMCSIdx = 8;
17534 }
17535 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
17536 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017537 //VHT20 is supporting 0~8
17538 if (rate_flags & eHAL_TX_RATE_VHT20)
17539 maxMCSIdx = 8;
17540 else
17541 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070017542 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017543
c_hpothu79aab322014-07-14 21:11:01 +053017544 if (0 != rssidx)/*check for scaled */
17545 {
17546 //get middle rate MCS index if rssi=1/2
17547 for (i=0; i <= maxMCSIdx; i++)
17548 {
17549 if (sinfo->signal <= rssiMcsTbl[mode][i])
17550 {
17551 maxMCSIdx = i;
17552 break;
17553 }
17554 }
17555 }
17556
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017557 if (rate_flags & eHAL_TX_RATE_VHT80)
17558 {
17559 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
17560 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
17561 }
17562 else if (rate_flags & eHAL_TX_RATE_VHT40)
17563 {
17564 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
17565 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
17566 }
17567 else if (rate_flags & eHAL_TX_RATE_VHT20)
17568 {
17569 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
17570 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
17571 }
17572
Leo Chang6f8870f2013-03-26 18:11:36 -070017573 maxSpeedMCS = 1;
17574 if (currentRate > maxRate)
17575 {
17576 maxRate = currentRate;
17577 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017578
Leo Chang6f8870f2013-03-26 18:11:36 -070017579 }
17580 else
17581#endif /* WLAN_FEATURE_11AC */
17582 {
17583 if (rate_flags & eHAL_TX_RATE_HT40)
17584 {
17585 rateFlag |= 1;
17586 }
17587 if (rate_flags & eHAL_TX_RATE_SGI)
17588 {
17589 rateFlag |= 2;
17590 }
17591
Girish Gowli01abcee2014-07-31 20:18:55 +053017592 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053017593 if (rssidx == 1 || rssidx == 2)
17594 {
17595 //get middle rate MCS index if rssi=1/2
17596 for (i=0; i <= 7; i++)
17597 {
17598 if (sinfo->signal <= rssiMcsTbl[mode][i])
17599 {
17600 temp = i+1;
17601 break;
17602 }
17603 }
17604 }
c_hpothu79aab322014-07-14 21:11:01 +053017605
17606 for (i = 0; i < MCSLeng; i++)
17607 {
Leo Chang6f8870f2013-03-26 18:11:36 -070017608 for (j = 0; j < temp; j++)
17609 {
17610 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
17611 {
17612 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053017613 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070017614 break;
17615 }
17616 }
17617 if ((j < temp) && (currentRate > maxRate))
17618 {
17619 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070017620 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017621 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053017622 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070017623 }
17624 }
17625
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017626 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
17627 {
17628 maxRate = myRate;
17629 maxSpeedMCS = 1;
17630 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
17631 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017632 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053017633 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070017634 {
17635 maxRate = myRate;
17636 if (rate_flags & eHAL_TX_RATE_LEGACY)
17637 {
17638 maxSpeedMCS = 0;
17639 }
17640 else
17641 {
17642 maxSpeedMCS = 1;
17643 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
17644 }
17645 }
17646
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017647 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070017648 {
17649 sinfo->txrate.legacy = maxRate;
17650#ifdef LINKSPEED_DEBUG_ENABLED
17651 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
17652#endif //LINKSPEED_DEBUG_ENABLED
17653 }
17654 else
17655 {
17656 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070017657#ifdef WLAN_FEATURE_11AC
17658 sinfo->txrate.nss = 1;
17659 if (rate_flags & eHAL_TX_RATE_VHT80)
17660 {
17661 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017662 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070017663 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017664 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070017665 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017666 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
17667 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
17668 }
17669 else if (rate_flags & eHAL_TX_RATE_VHT20)
17670 {
17671 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
17672 }
17673#endif /* WLAN_FEATURE_11AC */
17674 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
17675 {
17676 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
17677 if (rate_flags & eHAL_TX_RATE_HT40)
17678 {
17679 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
17680 }
Leo Chang6f8870f2013-03-26 18:11:36 -070017681 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017682 if (rate_flags & eHAL_TX_RATE_SGI)
17683 {
17684 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
17685 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017686
Jeff Johnson295189b2012-06-20 16:38:30 -070017687#ifdef LINKSPEED_DEBUG_ENABLED
17688 pr_info("Reporting MCS rate %d flags %x\n",
17689 sinfo->txrate.mcs,
17690 sinfo->txrate.flags );
17691#endif //LINKSPEED_DEBUG_ENABLED
17692 }
17693 }
17694 else
17695 {
17696 // report current rate instead of max rate
17697
17698 if (rate_flags & eHAL_TX_RATE_LEGACY)
17699 {
17700 //provide to the UI in units of 100kbps
17701 sinfo->txrate.legacy = myRate;
17702#ifdef LINKSPEED_DEBUG_ENABLED
17703 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
17704#endif //LINKSPEED_DEBUG_ENABLED
17705 }
17706 else
17707 {
17708 //must be MCS
17709 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070017710#ifdef WLAN_FEATURE_11AC
17711 sinfo->txrate.nss = 1;
17712 if (rate_flags & eHAL_TX_RATE_VHT80)
17713 {
17714 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
17715 }
17716 else
17717#endif /* WLAN_FEATURE_11AC */
17718 {
17719 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
17720 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017721 if (rate_flags & eHAL_TX_RATE_SGI)
17722 {
17723 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
17724 }
17725 if (rate_flags & eHAL_TX_RATE_HT40)
17726 {
17727 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
17728 }
Leo Chang6f8870f2013-03-26 18:11:36 -070017729#ifdef WLAN_FEATURE_11AC
17730 else if (rate_flags & eHAL_TX_RATE_VHT80)
17731 {
17732 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
17733 }
17734#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070017735#ifdef LINKSPEED_DEBUG_ENABLED
17736 pr_info("Reporting actual MCS rate %d flags %x\n",
17737 sinfo->txrate.mcs,
17738 sinfo->txrate.flags );
17739#endif //LINKSPEED_DEBUG_ENABLED
17740 }
17741 }
17742 sinfo->filled |= STATION_INFO_TX_BITRATE;
17743
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070017744 sinfo->tx_packets =
17745 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
17746 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
17747 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
17748 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
17749
17750 sinfo->tx_retries =
17751 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
17752 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
17753 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
17754 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
17755
17756 sinfo->tx_failed =
17757 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
17758 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
17759 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
17760 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
17761
17762 sinfo->filled |=
17763 STATION_INFO_TX_PACKETS |
17764 STATION_INFO_TX_RETRIES |
17765 STATION_INFO_TX_FAILED;
17766
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053017767 sinfo->rx_packets = pAdapter->hdd_stats.summary_stat.rx_frm_cnt;
17768 sinfo->filled |= STATION_INFO_RX_PACKETS;
17769
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053017770 vos_mem_copy(&pHddStaCtx->conn_info.txrate,
17771 &sinfo->txrate, sizeof(sinfo->txrate));
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053017772 if (rate_flags & eHAL_TX_RATE_LEGACY)
17773 hddLog(LOG1, FL("Reporting RSSI:%d legacy rate %d pkt cnt tx %d rx %d"),
17774 sinfo->signal, sinfo->txrate.legacy, sinfo->tx_packets,
17775 sinfo->rx_packets);
17776 else
17777 hddLog(LOG1,
17778 FL("Reporting RSSI:%d MCS rate %d flags 0x%x pkt cnt tx %d rx %d"),
17779 sinfo->signal, sinfo->txrate.mcs, sinfo->txrate.flags,
17780 sinfo->tx_packets, sinfo->rx_packets);
17781
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017782 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17783 TRACE_CODE_HDD_CFG80211_GET_STA,
17784 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070017785 EXIT();
17786 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070017787}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017788#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
17789static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
17790 const u8* mac, struct station_info *sinfo)
17791#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017792static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
17793 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017794#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017795{
17796 int ret;
17797
17798 vos_ssr_protect(__func__);
17799 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
17800 vos_ssr_unprotect(__func__);
17801
17802 return ret;
17803}
17804
17805static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070017806 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070017807{
17808 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017809 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070017810 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017811 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017812
Jeff Johnsone7245742012-09-05 17:12:55 -070017813 ENTER();
17814
Jeff Johnson295189b2012-06-20 16:38:30 -070017815 if (NULL == pAdapter)
17816 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017817 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017818 return -ENODEV;
17819 }
17820
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017821 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17822 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
17823 pAdapter->sessionId, timeout));
17824
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017825 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017826 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017827 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017828 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017829 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017830 }
17831
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017832 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
17833 (TRUE == pHddCtx->hdd_wlan_suspended) &&
17834 (pHddCtx->cfg_ini->fhostArpOffload) &&
17835 (eConnectionState_Associated ==
17836 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
17837 {
Amar Singhald53568e2013-09-26 11:03:45 -070017838
17839 hddLog(VOS_TRACE_LEVEL_INFO,
17840 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053017841 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017842 if (!VOS_IS_STATUS_SUCCESS(vos_status))
17843 {
17844 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017845 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017846 __func__, vos_status);
17847 }
17848 }
17849
Jeff Johnson295189b2012-06-20 16:38:30 -070017850 /**The get power cmd from the supplicant gets updated by the nl only
17851 *on successful execution of the function call
17852 *we are oppositely mapped w.r.t mode in the driver
17853 **/
17854 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
17855
17856 if (VOS_STATUS_E_FAILURE == vos_status)
17857 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053017858 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17859 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017860 return -EINVAL;
17861 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017862 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017863 return 0;
17864}
17865
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017866static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
17867 struct net_device *dev, bool mode, int timeout)
17868{
17869 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070017870
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017871 vos_ssr_protect(__func__);
17872 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
17873 vos_ssr_unprotect(__func__);
17874
17875 return ret;
17876}
Sushant Kaushik084f6592015-09-10 13:11:56 +053017877
Jeff Johnson295189b2012-06-20 16:38:30 -070017878#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017879static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
17880 struct net_device *netdev,
17881 u8 key_index)
17882{
17883 ENTER();
17884 return 0;
17885}
17886
Jeff Johnson295189b2012-06-20 16:38:30 -070017887static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017888 struct net_device *netdev,
17889 u8 key_index)
17890{
17891 int ret;
17892 vos_ssr_protect(__func__);
17893 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
17894 vos_ssr_unprotect(__func__);
17895 return ret;
17896}
17897#endif //LINUX_VERSION_CODE
17898
17899#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
17900static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
17901 struct net_device *dev,
17902 struct ieee80211_txq_params *params)
17903{
17904 ENTER();
17905 return 0;
17906}
17907#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
17908static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
17909 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070017910{
Jeff Johnsone7245742012-09-05 17:12:55 -070017911 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070017912 return 0;
17913}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017914#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070017915
17916#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
17917static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017918 struct net_device *dev,
17919 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070017920{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017921 int ret;
17922
17923 vos_ssr_protect(__func__);
17924 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
17925 vos_ssr_unprotect(__func__);
17926 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070017927}
17928#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
17929static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
17930 struct ieee80211_txq_params *params)
17931{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017932 int ret;
17933
17934 vos_ssr_protect(__func__);
17935 ret = __wlan_hdd_set_txq_params(wiphy, params);
17936 vos_ssr_unprotect(__func__);
17937 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070017938}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017939#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017940
Naresh Jayaram69e3f282014-10-14 12:29:12 +053017941static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017942 struct net_device *dev,
17943 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070017944{
17945 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017946 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017947 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017948 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017949 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017950 v_CONTEXT_t pVosContext = NULL;
17951 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017952
Jeff Johnsone7245742012-09-05 17:12:55 -070017953 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017954
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017955 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070017956 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017957 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017958 return -EINVAL;
17959 }
17960
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017961 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17962 TRACE_CODE_HDD_CFG80211_DEL_STA,
17963 pAdapter->sessionId, pAdapter->device_mode));
17964
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017965 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17966 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017967 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017968 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017969 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017970 }
17971
Jeff Johnson295189b2012-06-20 16:38:30 -070017972 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070017973 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070017974 )
17975 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017976 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
17977 pSapCtx = VOS_GET_SAP_CB(pVosContext);
17978 if(pSapCtx == NULL){
17979 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17980 FL("psapCtx is NULL"));
17981 return -ENOENT;
17982 }
Agrawal Ashish306b75f2017-01-11 19:16:25 +053017983 if (pHddCtx->cfg_ini->enable_sap_auth_offload)
17984 {
17985 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
17986 "Change reason code to eSIR_MAC_DISASSOC_LEAVING_BSS_REASON in sap auth offload");
17987 pDelStaParams->reason_code = eSIR_MAC_DISASSOC_LEAVING_BSS_REASON;
17988 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017989 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070017990 {
17991 v_U16_t i;
17992 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
17993 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017994 if ((pSapCtx->aStaInfo[i].isUsed) &&
17995 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070017996 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017997 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017998 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017999 ETHER_ADDR_LEN);
18000
Jeff Johnson295189b2012-06-20 16:38:30 -070018001 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018002 "%s: Delete STA with MAC::"
18003 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018004 __func__,
18005 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
18006 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070018007 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018008 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070018009 }
18010 }
18011 }
18012 else
18013 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018014
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018015 vos_status = hdd_softap_GetStaId(pAdapter,
18016 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018017 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18018 {
18019 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018020 "%s: Skip this DEL STA as this is not used::"
18021 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018022 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018023 return -ENOENT;
18024 }
18025
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018026 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018027 {
18028 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018029 "%s: Skip this DEL STA as deauth is in progress::"
18030 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018031 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018032 return -ENOENT;
18033 }
18034
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018035 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018036
Jeff Johnson295189b2012-06-20 16:38:30 -070018037 hddLog(VOS_TRACE_LEVEL_INFO,
18038 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080018039 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070018040 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018041 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018042
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018043 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018044 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18045 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018046 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018047 hddLog(VOS_TRACE_LEVEL_INFO,
18048 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080018049 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018050 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018051 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018052 return -ENOENT;
18053 }
18054
Jeff Johnson295189b2012-06-20 16:38:30 -070018055 }
18056 }
18057
18058 EXIT();
18059
18060 return 0;
18061}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018062
18063#ifdef CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053018064int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018065 struct net_device *dev,
18066 struct station_del_parameters *param)
18067#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018068#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
Kapil Gupta137ef892016-12-13 19:38:00 +053018069int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018070 struct net_device *dev, const u8 *mac)
18071#else
Kapil Gupta137ef892016-12-13 19:38:00 +053018072int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018073 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018074#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018075#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018076{
18077 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018078 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070018079
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018080 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018081
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018082#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018083 if (NULL == param) {
18084 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018085 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018086 return -EINVAL;
18087 }
18088
18089 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
18090 param->subtype, &delStaParams);
18091
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018092#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053018093 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018094 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018095#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018096 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
18097
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018098 vos_ssr_unprotect(__func__);
18099
18100 return ret;
18101}
18102
18103static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018104 struct net_device *dev,
18105#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18106 const u8 *mac,
18107#else
18108 u8 *mac,
18109#endif
18110 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018111{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018112 hdd_adapter_t *pAdapter;
18113 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018114 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018115#ifdef FEATURE_WLAN_TDLS
18116 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018117
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018118 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018119
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018120 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18121 if (NULL == pAdapter)
18122 {
18123 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18124 "%s: Adapter is NULL",__func__);
18125 return -EINVAL;
18126 }
18127 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18128 status = wlan_hdd_validate_context(pHddCtx);
18129 if (0 != status)
18130 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018131 return status;
18132 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018133
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018134 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18135 TRACE_CODE_HDD_CFG80211_ADD_STA,
18136 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018137 mask = params->sta_flags_mask;
18138
18139 set = params->sta_flags_set;
18140
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018141 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018142 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
18143 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018144
18145 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
18146 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080018147 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018148 }
18149 }
18150#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018151 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018152 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018153}
18154
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018155#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18156static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
18157 struct net_device *dev, const u8 *mac,
18158 struct station_parameters *params)
18159#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018160static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
18161 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018162#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018163{
18164 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018165
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018166 vos_ssr_protect(__func__);
18167 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
18168 vos_ssr_unprotect(__func__);
18169
18170 return ret;
18171}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018172#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070018173
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018174static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070018175 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018176{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018177 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18178 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018179 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018180 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018181 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018182 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070018183
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018184 ENTER();
18185
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018186 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018187 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018188 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018189 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018190 return -EINVAL;
18191 }
18192
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018193 if (!pmksa) {
18194 hddLog(LOGE, FL("pmksa is NULL"));
18195 return -EINVAL;
18196 }
18197
18198 if (!pmksa->bssid || !pmksa->pmkid) {
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070018199 hddLog(LOGE, FL("pmksa->bssid(%pK) or pmksa->pmkid(%pK) is NULL"),
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018200 pmksa->bssid, pmksa->pmkid);
18201 return -EINVAL;
18202 }
18203
18204 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
18205 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
18206
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018207 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18208 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018209 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018210 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018211 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018212 }
18213
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018214 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018215 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
18216
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018217 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
18218 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018219
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018220 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018221 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018222 &pmk_id, 1, FALSE);
18223
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018224 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18225 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
18226 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018227
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018228 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018229 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018230}
18231
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018232static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
18233 struct cfg80211_pmksa *pmksa)
18234{
18235 int ret;
18236
18237 vos_ssr_protect(__func__);
18238 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
18239 vos_ssr_unprotect(__func__);
18240
18241 return ret;
18242}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018243
Wilson Yang6507c4e2013-10-01 20:11:19 -070018244
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018245static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070018246 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018247{
Wilson Yang6507c4e2013-10-01 20:11:19 -070018248 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18249 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018250 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080018251 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018252
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018253 ENTER();
18254
Wilson Yang6507c4e2013-10-01 20:11:19 -070018255 /* Validate pAdapter */
18256 if (NULL == pAdapter)
18257 {
18258 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
18259 return -EINVAL;
18260 }
18261
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018262 if (!pmksa) {
18263 hddLog(LOGE, FL("pmksa is NULL"));
18264 return -EINVAL;
18265 }
18266
18267 if (!pmksa->bssid) {
18268 hddLog(LOGE, FL("pmksa->bssid is NULL"));
18269 return -EINVAL;
18270 }
18271
Kiet Lam98c46a12014-10-31 15:34:57 -070018272 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
18273 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
18274
Wilson Yang6507c4e2013-10-01 20:11:19 -070018275 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18276 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070018277 if (0 != status)
18278 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070018279 return status;
18280 }
18281
18282 /*Retrieve halHandle*/
18283 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
18284
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018285 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18286 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
18287 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018288 /* Delete the PMKID CSR cache */
18289 if (eHAL_STATUS_SUCCESS !=
18290 sme_RoamDelPMKIDfromCache(halHandle,
18291 pAdapter->sessionId, pmksa->bssid, FALSE)) {
18292 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
18293 MAC_ADDR_ARRAY(pmksa->bssid));
18294 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018295 }
18296
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018297 EXIT();
18298 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018299}
18300
Wilson Yang6507c4e2013-10-01 20:11:19 -070018301
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018302static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
18303 struct cfg80211_pmksa *pmksa)
18304{
18305 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018306
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018307 vos_ssr_protect(__func__);
18308 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
18309 vos_ssr_unprotect(__func__);
18310
18311 return ret;
18312
18313}
18314
18315static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018316{
Wilson Yang6507c4e2013-10-01 20:11:19 -070018317 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18318 tHalHandle halHandle;
18319 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080018320 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018321
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018322 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070018323
18324 /* Validate pAdapter */
18325 if (NULL == pAdapter)
18326 {
18327 hddLog(VOS_TRACE_LEVEL_ERROR,
18328 "%s: Invalid Adapter" ,__func__);
18329 return -EINVAL;
18330 }
18331
18332 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18333 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070018334 if (0 != status)
18335 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070018336 return status;
18337 }
18338
18339 /*Retrieve halHandle*/
18340 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
18341
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018342 /* Flush the PMKID cache in CSR */
18343 if (eHAL_STATUS_SUCCESS !=
18344 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
18345 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
18346 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018347 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018348 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080018349 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018350}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018351
18352static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
18353{
18354 int ret;
18355
18356 vos_ssr_protect(__func__);
18357 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
18358 vos_ssr_unprotect(__func__);
18359
18360 return ret;
18361}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018362#endif
18363
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018364#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018365static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
18366 struct net_device *dev,
18367 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018368{
18369 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18370 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018371 hdd_context_t *pHddCtx;
18372 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018373
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018374 ENTER();
18375
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018376 if (NULL == pAdapter)
18377 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080018378 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018379 return -ENODEV;
18380 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018381 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18382 ret = wlan_hdd_validate_context(pHddCtx);
18383 if (0 != ret)
18384 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018385 return ret;
18386 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018387 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018388 if (NULL == pHddStaCtx)
18389 {
18390 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
18391 return -EINVAL;
18392 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018393
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018394 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18395 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
18396 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018397 // Added for debug on reception of Re-assoc Req.
18398 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
18399 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080018400 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018401 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080018402 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018403 }
18404
18405#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080018406 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018407 ftie->ie_len);
18408#endif
18409
18410 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053018411 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
18412 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018413 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018414
18415 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018416 return 0;
18417}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018418
18419static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
18420 struct net_device *dev,
18421 struct cfg80211_update_ft_ies_params *ftie)
18422{
18423 int ret;
18424
18425 vos_ssr_protect(__func__);
18426 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
18427 vos_ssr_unprotect(__func__);
18428
18429 return ret;
18430}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018431#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018432
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018433#ifdef FEATURE_WLAN_SCAN_PNO
18434
18435void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
18436 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
18437{
18438 int ret;
18439 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
18440 hdd_context_t *pHddCtx;
18441
Nirav Shah80830bf2013-12-31 16:35:12 +053018442 ENTER();
18443
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018444 if (NULL == pAdapter)
18445 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053018446 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018447 "%s: HDD adapter is Null", __func__);
18448 return ;
18449 }
18450
18451 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18452 if (NULL == pHddCtx)
18453 {
18454 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18455 "%s: HDD context is Null!!!", __func__);
18456 return ;
18457 }
18458
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018459 spin_lock(&pHddCtx->schedScan_lock);
18460 if (TRUE == pHddCtx->isWiphySuspended)
18461 {
18462 pHddCtx->isSchedScanUpdatePending = TRUE;
18463 spin_unlock(&pHddCtx->schedScan_lock);
18464 hddLog(VOS_TRACE_LEVEL_INFO,
18465 "%s: Update cfg80211 scan database after it resume", __func__);
18466 return ;
18467 }
18468 spin_unlock(&pHddCtx->schedScan_lock);
18469
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018470 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
18471
18472 if (0 > ret)
18473 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagarfb49cdd2015-10-16 18:41:59 +053018474 else
18475 {
18476 /* Acquire wakelock to handle the case where APP's tries to suspend
18477 * immediatly after the driver gets connect request(i.e after pno)
18478 * from supplicant, this result in app's is suspending and not able
18479 * to process the connect request to AP */
18480 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
18481 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018482 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018483 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18484 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018485}
18486
18487/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018488 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053018489 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018490 */
18491static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
18492{
18493 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
18494 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018495 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018496 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18497 int status = 0;
Agrawal Ashishcff31692016-12-16 17:17:50 +053018498
18499 if (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
18500 {
18501 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18502 "%s: PNO is allowed only in STA interface", __func__);
18503 return eHAL_STATUS_FAILURE;
18504 }
18505
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018506 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
18507
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053018508 /* The current firmware design does not allow PNO during any
Agrawal Ashishcff31692016-12-16 17:17:50 +053018509 * active sessions. PNO is allowed only in case when sap session
18510 * is present and sapo auth offload feature enabled in firmare.
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053018511 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018512 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
18513 {
18514 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018515 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018516
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018517 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
18518 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
18519 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
18520 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
Agrawal Ashishcff31692016-12-16 17:17:50 +053018521 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode &&
18522 !pHddCtx->cfg_ini->enable_sap_auth_offload)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053018523 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018524 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018525 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018526 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018527 }
18528 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
18529 pAdapterNode = pNext;
18530 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018531 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018532}
18533
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018534void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
18535{
18536 hdd_adapter_t *pAdapter = callbackContext;
18537 hdd_context_t *pHddCtx;
18538
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018539 ENTER();
18540
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018541 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
18542 {
18543 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18544 FL("Invalid adapter or adapter has invalid magic"));
18545 return;
18546 }
18547
18548 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18549 if (0 != wlan_hdd_validate_context(pHddCtx))
18550 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018551 return;
18552 }
18553
c_hpothub53c45d2014-08-18 16:53:14 +053018554 if (VOS_STATUS_SUCCESS != status)
18555 {
18556 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018557 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053018558 pHddCtx->isPnoEnable = FALSE;
18559 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018560
18561 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
18562 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018563 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018564}
18565
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018566#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) || \
18567 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
18568/**
18569 * hdd_config_sched_scan_plan() - configures the sched scan plans
18570 * from the framework.
18571 * @pno_req: pointer to PNO scan request
18572 * @request: pointer to scan request from framework
18573 *
18574 * Return: None
18575 */
18576static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
18577 struct cfg80211_sched_scan_request *request,
18578 hdd_context_t *hdd_ctx)
18579{
18580 v_U32_t i = 0;
18581
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018582 pno_req->scanTimers.ucScanTimersCount = request->n_scan_plans;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018583 for (i = 0; i < request->n_scan_plans; i++)
18584 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018585 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
18586 request->scan_plans[i].iterations;
18587 pno_req->scanTimers.aTimerValues[i].uTimerValue =
18588 request->scan_plans[i].interval;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018589 }
18590}
18591#else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018592static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018593 struct cfg80211_sched_scan_request *request,
18594 hdd_context_t *hdd_ctx)
18595{
18596 v_U32_t i, temp_int;
18597 /* Driver gets only one time interval which is hardcoded in
18598 * supplicant for 10000ms. Taking power consumption into account 6
18599 * timers will be used, Timervalue is increased exponentially
18600 * i.e 10,20,40, 80,160,320 secs. And number of scan cycle for each
18601 * timer is configurable through INI param gPNOScanTimerRepeatValue.
18602 * If it is set to 0 only one timer will be used and PNO scan cycle
18603 * will be repeated after each interval specified by supplicant
18604 * till PNO is disabled.
18605 */
18606 if (0 == hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue)
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018607 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018608 HDD_PNO_SCAN_TIMERS_SET_ONE;
18609 else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018610 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018611 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
18612
18613 temp_int = (request->interval)/1000;
18614 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18615 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
18616 temp_int, hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue);
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018617 for ( i = 0; i < pno_req->scanTimers.ucScanTimersCount; i++)
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018618 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018619 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018620 hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue;
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018621 pno_req->scanTimers.aTimerValues[i].uTimerValue = temp_int;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018622 temp_int *= 2;
18623 }
18624 //Repeat last timer until pno disabled.
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018625 pno_req->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018626}
18627#endif
18628
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018629/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018630 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
18631 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018632 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018633static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018634 struct net_device *dev, struct cfg80211_sched_scan_request *request)
18635{
18636 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018637 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018638 hdd_context_t *pHddCtx;
18639 tHalHandle hHal;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018640 v_U32_t i, indx, num_ch, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053018641 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
18642 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018643 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
18644 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018645 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053018646 hdd_config_t *pConfig = NULL;
18647 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018648
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018649 ENTER();
18650
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018651 if (NULL == pAdapter)
18652 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018653 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018654 "%s: HDD adapter is Null", __func__);
18655 return -ENODEV;
18656 }
18657
18658 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018659 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018660
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018661 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018662 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018663 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018664 }
18665
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053018666 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018667 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
18668 if (NULL == hHal)
18669 {
18670 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18671 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018672 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018673 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018674 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18675 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
18676 pAdapter->sessionId, pAdapter->device_mode));
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053018677 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053018678 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053018679 {
18680 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18681 "%s: aborting the existing scan is unsuccessfull", __func__);
18682 return -EBUSY;
18683 }
18684
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018685 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018686 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053018687 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018688 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018689 return -EBUSY;
18690 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018691
c_hpothu37f21312014-04-09 21:49:54 +053018692 if (TRUE == pHddCtx->isPnoEnable)
18693 {
18694 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
18695 FL("already PNO is enabled"));
18696 return -EBUSY;
18697 }
c_hpothu225aa7c2014-10-22 17:45:13 +053018698
18699 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
18700 {
18701 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18702 "%s: abort ROC failed ", __func__);
18703 return -EBUSY;
18704 }
18705
c_hpothu37f21312014-04-09 21:49:54 +053018706 pHddCtx->isPnoEnable = TRUE;
18707
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018708 pnoRequest.enable = 1; /*Enable PNO */
18709 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018710
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018711 if (( !pnoRequest.ucNetworksCount ) ||
18712 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018713 {
18714 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053018715 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018716 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053018717 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018718 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018719 goto error;
18720 }
18721
18722 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
18723 {
18724 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053018725 "%s: Incorrect number of channels %d",
18726 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018727 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018728 goto error;
18729 }
18730
18731 /* Framework provides one set of channels(all)
18732 * common for all saved profile */
18733 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
18734 channels_allowed, &num_channels_allowed))
18735 {
18736 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18737 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018738 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018739 goto error;
18740 }
18741 /* Checking each channel against allowed channel list */
18742 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053018743 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018744 {
Nirav Shah80830bf2013-12-31 16:35:12 +053018745 char chList [(request->n_channels*5)+1];
18746 int len;
18747 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018748 {
Nirav Shah80830bf2013-12-31 16:35:12 +053018749 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018750 {
Nirav Shah80830bf2013-12-31 16:35:12 +053018751 if (request->channels[i]->hw_value == channels_allowed[indx])
18752 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053018753 if ((!pConfig->enableDFSPnoChnlScan) &&
18754 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
18755 {
18756 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18757 "%s : Dropping DFS channel : %d",
18758 __func__,channels_allowed[indx]);
18759 num_ignore_dfs_ch++;
18760 break;
18761 }
18762
Nirav Shah80830bf2013-12-31 16:35:12 +053018763 valid_ch[num_ch++] = request->channels[i]->hw_value;
18764 len += snprintf(chList+len, 5, "%d ",
18765 request->channels[i]->hw_value);
18766 break ;
18767 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018768 }
18769 }
Nirav Shah80830bf2013-12-31 16:35:12 +053018770 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018771
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053018772 /*If all channels are DFS and dropped, then ignore the PNO request*/
18773 if (num_ignore_dfs_ch == request->n_channels)
18774 {
18775 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18776 "%s : All requested channels are DFS channels", __func__);
18777 ret = -EINVAL;
18778 goto error;
18779 }
18780 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018781
18782 pnoRequest.aNetworks =
18783 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
18784 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018785 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018786 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
18787 FL("failed to allocate memory aNetworks %u"),
18788 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
18789 goto error;
18790 }
18791 vos_mem_zero(pnoRequest.aNetworks,
18792 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
18793
18794 /* Filling per profile params */
18795 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
18796 {
18797 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018798 request->match_sets[i].ssid.ssid_len;
18799
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018800 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
18801 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018802 {
18803 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053018804 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018805 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018806 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018807 goto error;
18808 }
18809
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018810 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018811 request->match_sets[i].ssid.ssid,
18812 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053018813 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18814 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018815 i, pnoRequest.aNetworks[i].ssId.ssId);
18816 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
18817 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
18818 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018819
18820 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018821 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
18822 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018823
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018824 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018825 }
18826
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018827 for (i = 0; i < request->n_ssids; i++)
18828 {
18829 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018830 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018831 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018832 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018833 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018834 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018835 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018836 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018837 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018838 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018839 break;
18840 }
18841 j++;
18842 }
18843 }
18844 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18845 "Number of hidden networks being Configured = %d",
18846 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053018847 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080018848 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018849
18850 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
18851 if (pnoRequest.p24GProbeTemplate == NULL)
18852 {
18853 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
18854 FL("failed to allocate memory p24GProbeTemplate %u"),
18855 SIR_PNO_MAX_PB_REQ_SIZE);
18856 goto error;
18857 }
18858
18859 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
18860 if (pnoRequest.p5GProbeTemplate == NULL)
18861 {
18862 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
18863 FL("failed to allocate memory p5GProbeTemplate %u"),
18864 SIR_PNO_MAX_PB_REQ_SIZE);
18865 goto error;
18866 }
18867
18868 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
18869 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
18870
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053018871 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
18872 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053018873 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018874 pnoRequest.us24GProbeTemplateLen = request->ie_len;
18875 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
18876 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053018877
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018878 pnoRequest.us5GProbeTemplateLen = request->ie_len;
18879 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
18880 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053018881 }
18882
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018883 hdd_config_sched_scan_plan(&pnoRequest, request, pHddCtx);
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053018884
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018885 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018886
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018887 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018888 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
18889 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018890 pAdapter->pno_req_status = 0;
18891
Nirav Shah80830bf2013-12-31 16:35:12 +053018892 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18893 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018894 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
18895 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053018896
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018897 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018898 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018899 hdd_cfg80211_sched_scan_done_callback, pAdapter);
18900 if (eHAL_STATUS_SUCCESS != status)
18901 {
18902 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053018903 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018904 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018905 goto error;
18906 }
18907
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018908 ret = wait_for_completion_timeout(
18909 &pAdapter->pno_comp_var,
18910 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
18911 if (0 >= ret)
18912 {
18913 // Did not receive the response for PNO enable in time.
18914 // Assuming the PNO enable was success.
18915 // Returning error from here, because we timeout, results
18916 // in side effect of Wifi (Wifi Setting) not to work.
18917 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18918 FL("Timed out waiting for PNO to be Enabled"));
18919 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018920 }
18921
18922 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053018923 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018924
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018925error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018926 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18927 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053018928 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018929 if (pnoRequest.aNetworks)
18930 vos_mem_free(pnoRequest.aNetworks);
18931 if (pnoRequest.p24GProbeTemplate)
18932 vos_mem_free(pnoRequest.p24GProbeTemplate);
18933 if (pnoRequest.p5GProbeTemplate)
18934 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018935
18936 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018937 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018938}
18939
18940/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018941 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
18942 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018943 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018944static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
18945 struct net_device *dev, struct cfg80211_sched_scan_request *request)
18946{
18947 int ret;
18948
18949 vos_ssr_protect(__func__);
18950 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
18951 vos_ssr_unprotect(__func__);
18952
18953 return ret;
18954}
18955
18956/*
18957 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
18958 * Function to disable PNO
18959 */
18960static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018961 struct net_device *dev)
18962{
18963 eHalStatus status = eHAL_STATUS_FAILURE;
18964 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18965 hdd_context_t *pHddCtx;
18966 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018967 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018968 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018969
18970 ENTER();
18971
18972 if (NULL == pAdapter)
18973 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018974 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018975 "%s: HDD adapter is Null", __func__);
18976 return -ENODEV;
18977 }
18978
18979 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018980
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018981 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018982 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018983 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018984 "%s: HDD context is Null", __func__);
18985 return -ENODEV;
18986 }
18987
18988 /* The return 0 is intentional when isLogpInProgress and
18989 * isLoadUnloadInProgress. We did observe a crash due to a return of
18990 * failure in sched_scan_stop , especially for a case where the unload
18991 * of the happens at the same time. The function __cfg80211_stop_sched_scan
18992 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
18993 * success. If it returns a failure , then its next invocation due to the
18994 * clean up of the second interface will have the dev pointer corresponding
18995 * to the first one leading to a crash.
18996 */
18997 if (pHddCtx->isLogpInProgress)
18998 {
18999 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19000 "%s: LOGP in Progress. Ignore!!!", __func__);
Mahesh A Saptasagar0c11d822015-10-08 19:54:08 +053019001 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019002 return ret;
19003 }
19004
Mihir Shete18156292014-03-11 15:38:30 +053019005 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019006 {
19007 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19008 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
19009 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019010 }
19011
19012 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
19013 if (NULL == hHal)
19014 {
19015 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19016 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019017 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019018 }
19019
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019020 pnoRequest.enable = 0; /* Disable PNO */
19021 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019022
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019023 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19024 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
19025 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019026
19027 INIT_COMPLETION(pAdapter->pno_comp_var);
19028 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
19029 pnoRequest.callbackContext = pAdapter;
19030 pAdapter->pno_req_status = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019031 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019032 pAdapter->sessionId,
19033 NULL, pAdapter);
19034 if (eHAL_STATUS_SUCCESS != status)
19035 {
19036 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19037 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019038 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019039 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019040 }
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019041 ret = wait_for_completion_timeout(
19042 &pAdapter->pno_comp_var,
19043 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
19044 if (0 >= ret)
19045 {
19046 // Did not receive the response for PNO disable in time.
19047 // Assuming the PNO disable was success.
19048 // Returning error from here, because we timeout, results
19049 // in side effect of Wifi (Wifi Setting) not to work.
Anurag Chouhan96b41cb2016-09-28 18:54:47 +053019050 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019051 FL("Timed out waiting for PNO to be disabled"));
19052 ret = 0;
19053 }
19054
19055 ret = pAdapter->pno_req_status;
19056 pHddCtx->isPnoEnable = (ret == 0) ? FALSE : TRUE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019057
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019058error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019059 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019060 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019061
19062 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019063 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019064}
19065
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019066/*
19067 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
19068 * NL interface to disable PNO
19069 */
19070static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
19071 struct net_device *dev)
19072{
19073 int ret;
19074
19075 vos_ssr_protect(__func__);
19076 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
19077 vos_ssr_unprotect(__func__);
19078
19079 return ret;
19080}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019081#endif /*FEATURE_WLAN_SCAN_PNO*/
19082
19083
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019084#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019085#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019086static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19087 struct net_device *dev,
19088 u8 *peer, u8 action_code,
19089 u8 dialog_token,
19090 u16 status_code, u32 peer_capability,
19091 const u8 *buf, size_t len)
19092#else /* TDLS_MGMT_VERSION2 */
19093#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
19094static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19095 struct net_device *dev,
19096 const u8 *peer, u8 action_code,
19097 u8 dialog_token, u16 status_code,
19098 u32 peer_capability, bool initiator,
19099 const u8 *buf, size_t len)
19100#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
19101static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19102 struct net_device *dev,
19103 const u8 *peer, u8 action_code,
19104 u8 dialog_token, u16 status_code,
19105 u32 peer_capability, const u8 *buf,
19106 size_t len)
19107#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
19108static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19109 struct net_device *dev,
19110 u8 *peer, u8 action_code,
19111 u8 dialog_token,
19112 u16 status_code, u32 peer_capability,
19113 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019114#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019115static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19116 struct net_device *dev,
19117 u8 *peer, u8 action_code,
19118 u8 dialog_token,
19119 u16 status_code, const u8 *buf,
19120 size_t len)
19121#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019122#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019123{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019124 hdd_adapter_t *pAdapter;
19125 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019126 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070019127 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080019128 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070019129 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019130 int ret;
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053019131 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019132#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019133 u32 peer_capability = 0;
19134#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053019135 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019136 hdd_station_ctx_t *pHddStaCtx = NULL;
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019137 tdlsCtx_t *pHddTdlsCtx;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019138
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019139 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19140 if (NULL == pAdapter)
19141 {
19142 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19143 "%s: Adapter is NULL",__func__);
19144 return -EINVAL;
19145 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019146 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19147 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
19148 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019149
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019150 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019151 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019152 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019153 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019154 "Invalid arguments");
19155 return -EINVAL;
19156 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019157
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080019158 if (pHddCtx->isLogpInProgress)
19159 {
19160 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19161 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053019162 wlan_hdd_tdls_set_link_status(pAdapter,
19163 peer,
19164 eTDLS_LINK_IDLE,
19165 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080019166 return -EBUSY;
19167 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019168
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019169 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
19170 {
19171 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19172 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
19173 return -EAGAIN;
19174 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019175
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019176 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
19177 if (!pHddTdlsCtx) {
19178 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19179 "%s: pHddTdlsCtx not valid.", __func__);
19180 }
19181
Hoonki Lee27511902013-03-14 18:19:06 -070019182 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019183 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019184 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070019185 "%s: TDLS mode is disabled OR not enabled in FW."
19186 MAC_ADDRESS_STR " action %d declined.",
19187 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019188 return -ENOTSUPP;
19189 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080019190
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019191 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
19192
19193 if( NULL == pHddStaCtx )
19194 {
19195 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19196 "%s: HDD station context NULL ",__func__);
19197 return -EINVAL;
19198 }
19199
19200 /* STA should be connected and authenticated
19201 * before sending any TDLS frames
19202 */
19203 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
19204 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
19205 {
19206 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19207 "STA is not connected or unauthenticated. "
19208 "connState %u, uIsAuthenticated %u",
19209 pHddStaCtx->conn_info.connState,
19210 pHddStaCtx->conn_info.uIsAuthenticated);
19211 return -EAGAIN;
19212 }
19213
Hoonki Lee27511902013-03-14 18:19:06 -070019214 /* other than teardown frame, other mgmt frames are not sent if disabled */
19215 if (SIR_MAC_TDLS_TEARDOWN != action_code)
19216 {
19217 /* if tdls_mode is disabled to respond to peer's request */
19218 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
19219 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019220 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070019221 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070019222 " TDLS mode is disabled. action %d declined.",
19223 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070019224
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019225 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070019226 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053019227
19228 if (vos_max_concurrent_connections_reached())
19229 {
19230 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
19231 return -EINVAL;
19232 }
Hoonki Lee27511902013-03-14 18:19:06 -070019233 }
19234
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019235 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
19236 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053019237 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019238 {
19239 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019240 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070019241 " TDLS setup is ongoing. action %d declined.",
19242 __func__, MAC_ADDR_ARRAY(peer), action_code);
19243 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019244 }
19245 }
19246
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019247 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
19248 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080019249 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053019250 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
19251 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080019252 {
19253 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
19254 we return error code at 'add_station()'. Hence we have this
19255 check again in addtion to add_station().
19256 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019257 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080019258 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019259 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19260 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053019261 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
19262 __func__, MAC_ADDR_ARRAY(peer), action_code,
19263 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053019264 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080019265 }
19266 else
19267 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019268 /* maximum reached. tweak to send error code to peer and return
19269 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080019270 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019271 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19272 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053019273 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
19274 __func__, MAC_ADDR_ARRAY(peer), status_code,
19275 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070019276 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019277 /* fall through to send setup resp with failure status
19278 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080019279 }
19280 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019281 else
19282 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019283 mutex_lock(&pHddCtx->tdls_lock);
19284 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019285 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019286 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019287 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019288 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070019289 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
19290 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019291 return -EPERM;
19292 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019293 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019294 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080019295 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019296
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019297 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053019298 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019299 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
19300 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019301
Hoonki Leea34dd892013-02-05 22:56:02 -080019302 /*Except teardown responder will not be used so just make 0*/
19303 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019304 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080019305 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070019306
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019307 mutex_lock(&pHddCtx->tdls_lock);
19308 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070019309
19310 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
19311 responder = pTdlsPeer->is_responder;
19312 else
Hoonki Leea34dd892013-02-05 22:56:02 -080019313 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070019314 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053019315 "%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 -070019316 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
19317 dialog_token, status_code, len);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019318 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070019319 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080019320 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019321 mutex_unlock(&pHddCtx->tdls_lock);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019322 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019323
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053019324 /* Discard TDLS setup if peer is removed by user app */
19325 if ((pHddCtx->cfg_ini->fTDLSExternalControl) &&
19326 ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
19327 (SIR_MAC_TDLS_SETUP_CNF == action_code) ||
19328 (SIR_MAC_TDLS_DIS_REQ == action_code))) {
19329
19330 mutex_lock(&pHddCtx->tdls_lock);
19331 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
19332 if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) {
19333 mutex_unlock(&pHddCtx->tdls_lock);
19334 hddLog(LOGE, FL("TDLS External Control enabled, but peer "
19335 MAC_ADDRESS_STR " is not forced, so reject the action code %d"),
19336 MAC_ADDR_ARRAY(peer), action_code);
19337 return -EINVAL;
19338 }
19339 mutex_unlock(&pHddCtx->tdls_lock);
19340 }
19341
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053019342 /* For explicit trigger of DIS_REQ come out of BMPS for
19343 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070019344 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Deepthi Gowrif78f1f72016-03-21 13:13:28 +053019345 (SIR_MAC_TDLS_SETUP_CNF== action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053019346 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
19347 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070019348 {
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019349 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter))) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019350 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019351 "%s: Sending frame action_code %u.Disable BMPS", __func__,
19352 action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019353 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
19354 if (status != VOS_STATUS_SUCCESS) {
19355 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019356 } else {
19357 pHddTdlsCtx->is_tdls_disabled_bmps = true;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019358 }
Hoonki Lee14621352013-04-16 17:51:19 -070019359 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019360 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019361 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019362 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
19363 }
19364 }
Hoonki Lee14621352013-04-16 17:51:19 -070019365 }
19366
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019367 /* make sure doesn't call send_mgmt() while it is pending */
19368 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
19369 {
19370 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080019371 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019372 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019373 ret = -EBUSY;
19374 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019375 }
19376
19377 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019378 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
19379
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019380 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
19381 pAdapter->sessionId, peer, action_code, dialog_token,
19382 status_code, peer_capability, (tANI_U8 *)buf, len,
19383 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019384
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019385 if (VOS_STATUS_SUCCESS != status)
19386 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019387 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19388 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019389 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019390 ret = -EINVAL;
19391 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019392 }
19393
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019394 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19395 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
19396 WAIT_TIME_TDLS_MGMT);
19397
Hoonki Leed37cbb32013-04-20 00:31:14 -070019398 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
19399 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
19400
19401 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019402 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070019403 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070019404 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070019405 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019406 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080019407
19408 if (pHddCtx->isLogpInProgress)
19409 {
19410 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19411 "%s: LOGP in Progress. Ignore!!!", __func__);
19412 return -EAGAIN;
19413 }
Abhishek Singh837adf22015-10-01 17:37:37 +053019414 if (rc <= 0)
19415 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
19416 WLAN_LOG_INDICATOR_HOST_DRIVER,
19417 WLAN_LOG_REASON_HDD_TIME_OUT,
19418 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080019419
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019420 ret = -EINVAL;
19421 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019422 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019423 else
19424 {
19425 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19426 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
19427 __func__, rc, pAdapter->mgmtTxCompletionStatus);
19428 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019429
Gopichand Nakkala05922802013-03-14 12:23:19 -070019430 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070019431 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019432 ret = max_sta_failed;
19433 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070019434 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019435
Hoonki Leea34dd892013-02-05 22:56:02 -080019436 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
19437 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019438 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019439 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
19440 }
Hoonki Leea34dd892013-02-05 22:56:02 -080019441 }
19442 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
19443 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019444 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019445 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
19446 }
Hoonki Leea34dd892013-02-05 22:56:02 -080019447 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019448
19449 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019450
19451tx_failed:
19452 /* add_station will be called before sending TDLS_SETUP_REQ and
19453 * TDLS_SETUP_RSP and as part of add_station driver will enable
19454 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
19455 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
19456 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
19457 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
19458 */
19459
19460 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
19461 (SIR_MAC_TDLS_SETUP_RSP == action_code))
19462 wlan_hdd_tdls_check_bmps(pAdapter);
19463 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019464}
19465
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019466#if TDLS_MGMT_VERSION2
19467static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
19468 u8 *peer, u8 action_code, u8 dialog_token,
19469 u16 status_code, u32 peer_capability,
19470 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019471#else /* TDLS_MGMT_VERSION2 */
19472#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
19473static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19474 struct net_device *dev,
19475 const u8 *peer, u8 action_code,
19476 u8 dialog_token, u16 status_code,
19477 u32 peer_capability, bool initiator,
19478 const u8 *buf, size_t len)
19479#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
19480static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19481 struct net_device *dev,
19482 const u8 *peer, u8 action_code,
19483 u8 dialog_token, u16 status_code,
19484 u32 peer_capability, const u8 *buf,
19485 size_t len)
19486#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
19487static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19488 struct net_device *dev,
19489 u8 *peer, u8 action_code,
19490 u8 dialog_token,
19491 u16 status_code, u32 peer_capability,
19492 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019493#else
19494static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
19495 u8 *peer, u8 action_code, u8 dialog_token,
19496 u16 status_code, const u8 *buf, size_t len)
19497#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019498#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019499{
19500 int ret;
19501
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019502 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019503#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019504 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
19505 dialog_token, status_code,
19506 peer_capability, buf, len);
19507#else /* TDLS_MGMT_VERSION2 */
19508#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
19509 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
19510 dialog_token, status_code,
19511 peer_capability, initiator,
19512 buf, len);
19513#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
19514 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
19515 dialog_token, status_code,
19516 peer_capability, buf, len);
19517#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
19518 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
19519 dialog_token, status_code,
19520 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019521#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019522 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
19523 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019524#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019525#endif
19526 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019527
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019528 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019529}
Atul Mittal115287b2014-07-08 13:26:33 +053019530
19531int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019532#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19533 const u8 *peer,
19534#else
Atul Mittal115287b2014-07-08 13:26:33 +053019535 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019536#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019537 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053019538 cfg80211_exttdls_callback callback)
19539{
19540
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019541 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053019542 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053019543 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053019544 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19545 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
19546 __func__, MAC_ADDR_ARRAY(peer));
19547
19548 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
19549 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
19550
19551 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019552 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
19553 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
19554 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053019555 return -ENOTSUPP;
19556 }
19557
19558 /* To cater the requirement of establishing the TDLS link
19559 * irrespective of the data traffic , get an entry of TDLS peer.
19560 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053019561 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019562 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
19563 if (pTdlsPeer == NULL) {
19564 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19565 "%s: peer " MAC_ADDRESS_STR " not existing",
19566 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053019567 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019568 return -EINVAL;
19569 }
19570
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053019571 /* check FW TDLS Off Channel capability */
19572 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053019573 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053019574 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019575 {
19576 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
19577 pTdlsPeer->peerParams.global_operating_class =
19578 tdls_peer_params->global_operating_class;
19579 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
19580 pTdlsPeer->peerParams.min_bandwidth_kbps =
19581 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053019582 /* check configured channel is valid, non dfs and
19583 * not current operating channel */
19584 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
19585 tdls_peer_params->channel)) &&
19586 (pHddStaCtx) &&
19587 (tdls_peer_params->channel !=
19588 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019589 {
19590 pTdlsPeer->isOffChannelConfigured = TRUE;
19591 }
19592 else
19593 {
19594 pTdlsPeer->isOffChannelConfigured = FALSE;
19595 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19596 "%s: Configured Tdls Off Channel is not valid", __func__);
19597
19598 }
19599 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053019600 "%s: tdls_off_channel %d isOffChannelConfigured %d "
19601 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019602 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053019603 pTdlsPeer->isOffChannelConfigured,
19604 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019605 }
19606 else
19607 {
19608 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053019609 "%s: TDLS off channel FW capability %d, "
19610 "host capab %d or Invalid TDLS Peer Params", __func__,
19611 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
19612 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019613 }
19614
Atul Mittal115287b2014-07-08 13:26:33 +053019615 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
19616
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019617 mutex_unlock(&pHddCtx->tdls_lock);
19618
Atul Mittal115287b2014-07-08 13:26:33 +053019619 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19620 " %s TDLS Add Force Peer Failed",
19621 __func__);
19622 return -EINVAL;
19623 }
19624 /*EXT TDLS*/
19625
19626 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019627 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019628 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19629 " %s TDLS set callback Failed",
19630 __func__);
19631 return -EINVAL;
19632 }
19633
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019634 mutex_unlock(&pHddCtx->tdls_lock);
19635
Atul Mittal115287b2014-07-08 13:26:33 +053019636 return(0);
19637
19638}
19639
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019640int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
19641#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19642 const u8 *peer
19643#else
19644 u8 *peer
19645#endif
19646)
Atul Mittal115287b2014-07-08 13:26:33 +053019647{
19648
19649 hddTdlsPeer_t *pTdlsPeer;
19650 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053019651
Atul Mittal115287b2014-07-08 13:26:33 +053019652 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19653 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
19654 __func__, MAC_ADDR_ARRAY(peer));
19655
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053019656 if (0 != wlan_hdd_validate_context(pHddCtx)) {
19657 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
19658 return -EINVAL;
19659 }
19660
Atul Mittal115287b2014-07-08 13:26:33 +053019661 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
19662 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
19663
19664 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019665 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
19666 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
19667 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053019668 return -ENOTSUPP;
19669 }
19670
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019671 mutex_lock(&pHddCtx->tdls_lock);
19672 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Atul Mittal115287b2014-07-08 13:26:33 +053019673
19674 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019675 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019676 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019677 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053019678 __func__, MAC_ADDR_ARRAY(peer));
19679 return -EINVAL;
19680 }
19681 else {
19682 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
19683 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053019684 hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_EXT_CTRL,
19685 pTdlsPeer->peerMac);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019686 /* if channel switch is configured, reset
19687 the channel for this peer */
19688 if (TRUE == pTdlsPeer->isOffChannelConfigured)
19689 {
19690 pTdlsPeer->peerParams.channel = 0;
19691 pTdlsPeer->isOffChannelConfigured = FALSE;
19692 }
Atul Mittal115287b2014-07-08 13:26:33 +053019693 }
19694
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019695 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019696 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019697 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053019698 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019699 }
Atul Mittal115287b2014-07-08 13:26:33 +053019700
19701 /*EXT TDLS*/
19702
19703 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019704 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019705 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19706 " %s TDLS set callback Failed",
19707 __func__);
19708 return -EINVAL;
19709 }
Atul Mittal115287b2014-07-08 13:26:33 +053019710
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019711 mutex_unlock(&pHddCtx->tdls_lock);
19712
19713 return(0);
Atul Mittal115287b2014-07-08 13:26:33 +053019714}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019715static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019716#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19717 const u8 *peer,
19718#else
19719 u8 *peer,
19720#endif
19721 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019722{
19723 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19724 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019725 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019726 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019727
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019728 ENTER();
19729
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053019730 if (!pAdapter) {
19731 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
19732 return -EINVAL;
19733 }
19734
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019735 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19736 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
19737 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019738 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019739 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019740 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070019741 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019742 return -EINVAL;
19743 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080019744
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019745 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019746 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080019747 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019748 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080019749 }
19750
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019751
19752 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080019753 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019754 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080019755 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019756 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
19757 "Cannot process TDLS commands",
19758 pHddCtx->cfg_ini->fEnableTDLSSupport,
19759 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019760 return -ENOTSUPP;
19761 }
19762
19763 switch (oper) {
19764 case NL80211_TDLS_ENABLE_LINK:
19765 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019766 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019767 long ret;
Hanumantha Reddy Pothulada389492016-02-11 17:29:27 +053019768 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams = { {0}, 0,
19769 0, 0, 0, 0, 0, 0, {0}, 0, {0} };
Agarwal Ashish16020c42014-12-29 22:01:11 +053019770 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019771 tANI_U16 numCurrTdlsPeers = 0;
19772 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053019773 tANI_U8 suppChannelLen = 0;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019774 tSirMacAddr peerMac;
19775 int channel;
19776 tTDLSLinkStatus peer_status = eTDLS_LINK_IDLE;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019777
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019778 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19779 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
19780 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019781
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019782 mutex_lock(&pHddCtx->tdls_lock);
19783 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053019784 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053019785 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019786 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053019787 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
19788 " (oper %d) not exsting. ignored",
19789 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
19790 return -EINVAL;
19791 }
19792
19793 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19794 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
19795 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
19796 "NL80211_TDLS_ENABLE_LINK");
19797
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070019798 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
19799 {
19800 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
19801 MAC_ADDRESS_STR " failed",
19802 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019803 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070019804 return -EINVAL;
19805 }
19806
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053019807 /* before starting tdls connection, set tdls
19808 * off channel established status to default value */
19809 pTdlsPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019810
19811 mutex_unlock(&pHddCtx->tdls_lock);
19812
Deepthi Gowri2d85bbf2016-07-25 15:43:31 +053019813 wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019814 /* TDLS Off Channel, Disable tdls channel switch,
19815 when there are more than one tdls link */
19816 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053019817 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019818 {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019819 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019820 /* get connected peer and send disable tdls off chan */
19821 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019822 if ((connPeer) &&
19823 (connPeer->isOffChannelSupported == TRUE) &&
19824 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019825 {
19826 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19827 "%s: More then one peer connected, Disable "
19828 "TDLS channel switch", __func__);
19829
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053019830 connPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019831 vos_mem_copy(peerMac, connPeer->peerMac, sizeof (tSirMacAddr));
19832 channel = connPeer->peerParams.channel;
19833
19834 mutex_unlock(&pHddCtx->tdls_lock);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019835
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019836 ret = sme_SendTdlsChanSwitchReq(
19837 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019838 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019839 peerMac,
19840 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019841 TDLS_OFF_CHANNEL_BW_OFFSET,
19842 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019843 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019844 hddLog(VOS_TRACE_LEVEL_ERROR,
19845 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019846 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019847 }
19848 else
19849 {
19850 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19851 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019852 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019853 "isOffChannelConfigured %d",
19854 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019855 (connPeer ? (connPeer->isOffChannelSupported)
19856 : -1),
19857 (connPeer ? (connPeer->isOffChannelConfigured)
19858 : -1));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019859 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019860 }
19861 }
19862
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019863 mutex_lock(&pHddCtx->tdls_lock);
19864 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
19865 if ( NULL == pTdlsPeer ) {
19866 mutex_unlock(&pHddCtx->tdls_lock);
19867 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19868 "%s: " MAC_ADDRESS_STR
19869 " (oper %d) peer got freed in other context. ignored",
19870 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
19871 return -EINVAL;
19872 }
19873 peer_status = pTdlsPeer->link_status;
19874 mutex_unlock(&pHddCtx->tdls_lock);
19875
19876 if (eTDLS_LINK_CONNECTED != peer_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019877 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019878 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053019879
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019880 if (0 != wlan_hdd_tdls_get_link_establish_params(
19881 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019882 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019883 return -EINVAL;
19884 }
19885 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053019886
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019887 ret = sme_SendTdlsLinkEstablishParams(
19888 WLAN_HDD_GET_HAL_CTX(pAdapter),
19889 pAdapter->sessionId, peer,
19890 &tdlsLinkEstablishParams);
19891 if (ret != VOS_STATUS_SUCCESS) {
19892 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
19893 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019894 /* Send TDLS peer UAPSD capabilities to the firmware and
19895 * register with the TL on after the response for this operation
19896 * is received .
19897 */
19898 ret = wait_for_completion_interruptible_timeout(
19899 &pAdapter->tdls_link_establish_req_comp,
19900 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
Masti, Narayanraddie1892a52015-12-15 15:01:01 +053019901
19902 mutex_lock(&pHddCtx->tdls_lock);
19903 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
19904 if ( NULL == pTdlsPeer ) {
19905 mutex_unlock(&pHddCtx->tdls_lock);
19906 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19907 "%s %d: " MAC_ADDRESS_STR
19908 " (oper %d) peer got freed in other context. ignored",
19909 __func__, __LINE__, MAC_ADDR_ARRAY(peer),
19910 (int)oper);
19911 return -EINVAL;
19912 }
19913 peer_status = pTdlsPeer->link_status;
19914 mutex_unlock(&pHddCtx->tdls_lock);
19915
19916 if (ret <= 0 || (peer_status == eTDLS_LINK_TEARING))
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019917 {
19918 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019919 FL("Link Establish Request Failed Status %ld"),
19920 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019921 return -EINVAL;
19922 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053019923 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019924
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019925 mutex_lock(&pHddCtx->tdls_lock);
19926 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
19927 if ( NULL == pTdlsPeer ) {
19928 mutex_unlock(&pHddCtx->tdls_lock);
19929 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19930 "%s: " MAC_ADDRESS_STR
19931 " (oper %d) peer got freed in other context. ignored",
19932 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
19933 return -EINVAL;
19934 }
19935
Atul Mittal115287b2014-07-08 13:26:33 +053019936 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
19937 eTDLS_LINK_CONNECTED,
19938 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053019939 staDesc.ucSTAId = pTdlsPeer->staId;
19940 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053019941
19942 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19943 "%s: tdlsLinkEstablishParams of peer "
19944 MAC_ADDRESS_STR "uapsdQueues: %d"
19945 "qos: %d maxSp: %d isBufSta: %d isOffChannelSupported: %d"
19946 "isResponder: %d peerstaId: %d",
19947 __func__,
19948 MAC_ADDR_ARRAY(tdlsLinkEstablishParams.peerMac),
19949 tdlsLinkEstablishParams.uapsdQueues,
19950 tdlsLinkEstablishParams.qos,
19951 tdlsLinkEstablishParams.maxSp,
19952 tdlsLinkEstablishParams.isBufSta,
19953 tdlsLinkEstablishParams.isOffChannelSupported,
19954 tdlsLinkEstablishParams.isResponder,
19955 pTdlsPeer->staId);
19956
19957 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19958 "%s: StaDesc ucSTAId: %d ucQosEnabled: %d",
19959 __func__,
19960 staDesc.ucSTAId,
19961 staDesc.ucQosEnabled);
19962
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019963 ret = WLANTL_UpdateTdlsSTAClient(
19964 pHddCtx->pvosContext,
19965 &staDesc);
19966 if (ret != VOS_STATUS_SUCCESS) {
19967 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
19968 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053019969
Gopichand Nakkala471708b2013-06-04 20:03:01 +053019970 /* Mark TDLS client Authenticated .*/
19971 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
19972 pTdlsPeer->staId,
19973 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070019974 if (VOS_STATUS_SUCCESS == status)
19975 {
Hoonki Lee14621352013-04-16 17:51:19 -070019976 if (pTdlsPeer->is_responder == 0)
19977 {
19978 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053019979 tdlsConnInfo_t *tdlsInfo;
19980
19981 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
19982
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053019983 if (!vos_timer_is_initialized(
19984 &pTdlsPeer->initiatorWaitTimeoutTimer))
19985 {
19986 /* Initialize initiator wait callback */
19987 vos_timer_init(
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053019988 &pTdlsPeer->initiatorWaitTimeoutTimer,
19989 VOS_TIMER_TYPE_SW,
19990 wlan_hdd_tdls_initiator_wait_cb,
19991 tdlsInfo);
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053019992 }
Hoonki Lee14621352013-04-16 17:51:19 -070019993 wlan_hdd_tdls_timer_restart(pAdapter,
19994 &pTdlsPeer->initiatorWaitTimeoutTimer,
19995 WAIT_TIME_TDLS_INITIATOR);
19996 /* suspend initiator TX until it receives direct packet from the
19997 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019998 ret = WLANTL_SuspendDataTx(
19999 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
20000 &staId, NULL);
20001 if (ret != VOS_STATUS_SUCCESS) {
20002 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
20003 }
Hoonki Lee14621352013-04-16 17:51:19 -070020004 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020005
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020006 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020007 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020008 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020009 suppChannelLen =
20010 tdlsLinkEstablishParams.supportedChannelsLen;
20011
20012 if ((suppChannelLen > 0) &&
20013 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
20014 {
20015 tANI_U8 suppPeerChannel = 0;
20016 int i = 0;
20017 for (i = 0U; i < suppChannelLen; i++)
20018 {
20019 suppPeerChannel =
20020 tdlsLinkEstablishParams.supportedChannels[i];
20021
20022 pTdlsPeer->isOffChannelSupported = FALSE;
20023 if (suppPeerChannel ==
20024 pTdlsPeer->peerParams.channel)
20025 {
20026 pTdlsPeer->isOffChannelSupported = TRUE;
20027 break;
20028 }
20029 }
20030 }
20031 else
20032 {
20033 pTdlsPeer->isOffChannelSupported = FALSE;
20034 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020035 }
20036 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20037 "%s: TDLS channel switch request for channel "
20038 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020039 "%d isOffChannelSupported %d", __func__,
20040 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020041 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020042 suppChannelLen,
20043 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020044
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020045 /* TDLS Off Channel, Enable tdls channel switch,
20046 when their is only one tdls link and it supports */
20047 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
20048 if ((numCurrTdlsPeers == 1) &&
20049 (TRUE == pTdlsPeer->isOffChannelSupported) &&
20050 (TRUE == pTdlsPeer->isOffChannelConfigured))
20051 {
20052 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20053 "%s: Send TDLS channel switch request for channel %d",
20054 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053020055
20056 pTdlsPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020057 vos_mem_copy(peerMac, pTdlsPeer->peerMac, sizeof (tSirMacAddr));
20058 channel = pTdlsPeer->peerParams.channel;
20059
20060 mutex_unlock(&pHddCtx->tdls_lock);
20061
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020062 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
20063 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020064 peerMac,
20065 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020066 TDLS_OFF_CHANNEL_BW_OFFSET,
20067 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020068 if (ret != VOS_STATUS_SUCCESS) {
20069 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
20070 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020071 }
20072 else
20073 {
20074 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20075 "%s: TDLS channel switch request not sent"
20076 " numCurrTdlsPeers %d "
20077 "isOffChannelSupported %d "
20078 "isOffChannelConfigured %d",
20079 __func__, numCurrTdlsPeers,
20080 pTdlsPeer->isOffChannelSupported,
20081 pTdlsPeer->isOffChannelConfigured);
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020082 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020083 }
20084
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070020085 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020086 else
20087 mutex_unlock(&pHddCtx->tdls_lock);
20088
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020089 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020090
20091 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053020092 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
20093 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020094 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053020095 int ac;
20096 uint8 ucAc[4] = { WLANTL_AC_VO,
20097 WLANTL_AC_VI,
20098 WLANTL_AC_BK,
20099 WLANTL_AC_BE };
20100 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
20101 for(ac=0; ac < 4; ac++)
20102 {
20103 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
20104 pTdlsPeer->staId, ucAc[ac],
20105 tlTid[ac], tlTid[ac], 0, 0,
20106 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020107 if (status != VOS_STATUS_SUCCESS) {
20108 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
20109 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053020110 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020111 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020112 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020113
Bhargav Shah66896792015-10-01 18:17:37 +053020114 /* stop TCP delack timer if TDLS is enable */
20115 set_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
20116 hdd_manage_delack_timer(pHddCtx);
Abhishek Singh67fa6bc2016-01-05 15:57:19 +053020117 hdd_wlan_tdls_enable_link_event(peer,
20118 pTdlsPeer->isOffChannelSupported,
20119 pTdlsPeer->isOffChannelConfigured,
20120 pTdlsPeer->isOffChannelEstablished);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020121 }
20122 break;
20123 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080020124 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020125 tANI_U16 numCurrTdlsPeers = 0;
20126 hddTdlsPeer_t *connPeer = NULL;
20127
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020128 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20129 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
20130 __func__, MAC_ADDR_ARRAY(peer));
20131
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020132 mutex_lock(&pHddCtx->tdls_lock);
20133 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020134
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020135
Sunil Dutt41de4e22013-11-14 18:09:02 +053020136 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020137 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020138 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
20139 " (oper %d) not exsting. ignored",
20140 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20141 return -EINVAL;
20142 }
20143
20144 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20145 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
20146 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
20147 "NL80211_TDLS_DISABLE_LINK");
20148
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020149 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080020150 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020151 long status;
20152
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053020153 /* set tdls off channel status to false for this peer */
20154 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053020155 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
20156 eTDLS_LINK_TEARING,
20157 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
20158 eTDLS_LINK_UNSPECIFIED:
20159 eTDLS_LINK_DROPPED_BY_REMOTE);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020160 mutex_unlock(&pHddCtx->tdls_lock);
20161
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020162 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
20163
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020164 status = sme_DeleteTdlsPeerSta(
20165 WLAN_HDD_GET_HAL_CTX(pAdapter),
20166 pAdapter->sessionId, peer );
20167 if (status != VOS_STATUS_SUCCESS) {
20168 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
20169 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020170
20171 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
20172 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020173
20174 mutex_lock(&pHddCtx->tdls_lock);
20175 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20176 if ( NULL == pTdlsPeer ) {
20177 mutex_unlock(&pHddCtx->tdls_lock);
20178 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
20179 " peer was freed in other context",
20180 __func__, MAC_ADDR_ARRAY(peer));
20181 return -EINVAL;
20182 }
20183
Atul Mittal271a7652014-09-12 13:18:22 +053020184 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053020185 eTDLS_LINK_IDLE,
20186 eTDLS_LINK_UNSPECIFIED);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020187 mutex_unlock(&pHddCtx->tdls_lock);
20188
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020189 if (status <= 0)
20190 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020191 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20192 "%s: Del station failed status %ld",
20193 __func__, status);
20194 return -EPERM;
20195 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020196
20197 /* TDLS Off Channel, Enable tdls channel switch,
20198 when their is only one tdls link and it supports */
20199 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
20200 if (numCurrTdlsPeers == 1)
20201 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020202 tSirMacAddr peerMac;
20203 int channel;
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053020204
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020205 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020206 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053020207
20208 if (connPeer == NULL) {
20209 mutex_unlock(&pHddCtx->tdls_lock);
20210 hddLog(VOS_TRACE_LEVEL_ERROR,
20211 "%s connPeer is NULL", __func__);
20212 return -EINVAL;
20213 }
20214
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020215 vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr));
20216 channel = connPeer->peerParams.channel;
20217
20218 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20219 "%s: TDLS channel switch "
20220 "isOffChannelSupported %d "
20221 "isOffChannelConfigured %d "
20222 "isOffChannelEstablished %d",
20223 __func__,
20224 (connPeer ? connPeer->isOffChannelSupported : -1),
20225 (connPeer ? connPeer->isOffChannelConfigured : -1),
20226 (connPeer ? connPeer->isOffChannelEstablished : -1));
20227
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020228 if ((connPeer) &&
20229 (connPeer->isOffChannelSupported == TRUE) &&
20230 (connPeer->isOffChannelConfigured == TRUE))
20231 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053020232 connPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020233 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020234 status = sme_SendTdlsChanSwitchReq(
20235 WLAN_HDD_GET_HAL_CTX(pAdapter),
20236 pAdapter->sessionId,
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020237 peerMac,
20238 channel,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020239 TDLS_OFF_CHANNEL_BW_OFFSET,
20240 TDLS_CHANNEL_SWITCH_ENABLE);
20241 if (status != VOS_STATUS_SUCCESS) {
20242 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
20243 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020244 }
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020245 else
20246 mutex_unlock(&pHddCtx->tdls_lock);
20247 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020248 else
20249 {
20250 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20251 "%s: TDLS channel switch request not sent "
20252 "numCurrTdlsPeers %d ",
20253 __func__, numCurrTdlsPeers);
20254 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080020255 }
20256 else
20257 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020258 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020259 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20260 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080020261 }
Bhargav Shah66896792015-10-01 18:17:37 +053020262 if (numCurrTdlsPeers == 0) {
20263 /* start TCP delack timer if TDLS is disable */
20264 clear_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
20265 hdd_manage_delack_timer(pHddCtx);
20266 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080020267 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020268 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020269 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053020270 {
Atul Mittal115287b2014-07-08 13:26:33 +053020271 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020272
Atul Mittal115287b2014-07-08 13:26:33 +053020273 if (0 != status)
20274 {
20275 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020276 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053020277 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053020278 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053020279 break;
20280 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020281 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053020282 {
Atul Mittal115287b2014-07-08 13:26:33 +053020283 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
20284 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020285 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053020286 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020287
Atul Mittal115287b2014-07-08 13:26:33 +053020288 if (0 != status)
20289 {
20290 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020291 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053020292 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053020293 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053020294 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053020295 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020296 case NL80211_TDLS_DISCOVERY_REQ:
20297 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020298 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020299 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020300 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020301 return -ENOTSUPP;
20302 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020303 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20304 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020305 return -ENOTSUPP;
20306 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020307
20308 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020309 return 0;
20310}
Chilam NG571c65a2013-01-19 12:27:36 +053020311
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020312static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020313#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20314 const u8 *peer,
20315#else
20316 u8 *peer,
20317#endif
20318 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020319{
20320 int ret;
20321
20322 vos_ssr_protect(__func__);
20323 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
20324 vos_ssr_unprotect(__func__);
20325
20326 return ret;
20327}
20328
Chilam NG571c65a2013-01-19 12:27:36 +053020329int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
20330 struct net_device *dev, u8 *peer)
20331{
Arif Hussaina7c8e412013-11-20 11:06:42 -080020332 hddLog(VOS_TRACE_LEVEL_INFO,
20333 "tdls send discover req: "MAC_ADDRESS_STR,
20334 MAC_ADDR_ARRAY(peer));
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020335#if TDLS_MGMT_VERSION2
20336 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20337 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
20338#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020339#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
20340 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20341 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
20342#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
20343 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20344 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
20345#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
20346 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20347 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
20348#else
Chilam NG571c65a2013-01-19 12:27:36 +053020349 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20350 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020351#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020352#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053020353}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020354#endif
20355
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020356#ifdef WLAN_FEATURE_GTK_OFFLOAD
20357/*
20358 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
20359 * Callback rountine called upon receiving response for
20360 * get offload info
20361 */
20362void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
20363 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
20364{
20365
20366 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020367 tANI_U8 tempReplayCounter[8];
20368 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020369
20370 ENTER();
20371
20372 if (NULL == pAdapter)
20373 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053020374 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020375 "%s: HDD adapter is Null", __func__);
20376 return ;
20377 }
20378
20379 if (NULL == pGtkOffloadGetInfoRsp)
20380 {
20381 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20382 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
20383 return ;
20384 }
20385
20386 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
20387 {
20388 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20389 "%s: wlan Failed to get replay counter value",
20390 __func__);
20391 return ;
20392 }
20393
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020394 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
20395 /* Update replay counter */
20396 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
20397 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
20398
20399 {
20400 /* changing from little to big endian since supplicant
20401 * works on big endian format
20402 */
20403 int i;
20404 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
20405
20406 for (i = 0; i < 8; i++)
20407 {
20408 tempReplayCounter[7-i] = (tANI_U8)p[i];
20409 }
20410 }
20411
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020412 /* Update replay counter to NL */
20413 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020414 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020415}
20416
20417/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020418 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020419 * This function is used to offload GTK rekeying job to the firmware.
20420 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020421int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020422 struct cfg80211_gtk_rekey_data *data)
20423{
20424 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20425 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
20426 hdd_station_ctx_t *pHddStaCtx;
20427 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020428 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020429 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020430 eHalStatus status = eHAL_STATUS_FAILURE;
20431
20432 ENTER();
20433
20434 if (NULL == pAdapter)
20435 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053020436 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020437 "%s: HDD adapter is Null", __func__);
20438 return -ENODEV;
20439 }
20440
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053020441 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20442 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
20443 pAdapter->sessionId, pAdapter->device_mode));
20444
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020445 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020446 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020447 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020448 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020449 }
20450
20451 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
20452 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
20453 if (NULL == hHal)
20454 {
20455 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20456 "%s: HAL context is Null!!!", __func__);
20457 return -EAGAIN;
20458 }
20459
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020460 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
20461 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
20462 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
20463 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020464 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020465 {
20466 /* changing from big to little endian since driver
20467 * works on little endian format
20468 */
20469 tANI_U8 *p =
20470 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
20471 int i;
20472
20473 for (i = 0; i < 8; i++)
20474 {
20475 p[7-i] = data->replay_ctr[i];
20476 }
20477 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020478
20479 if (TRUE == pHddCtx->hdd_wlan_suspended)
20480 {
20481 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020482 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
20483 sizeof (tSirGtkOffloadParams));
20484 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020485 pAdapter->sessionId);
20486
20487 if (eHAL_STATUS_SUCCESS != status)
20488 {
20489 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20490 "%s: sme_SetGTKOffload failed, returned %d",
20491 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053020492
20493 /* Need to clear any trace of key value in the memory.
20494 * Thus zero out the memory even though it is local
20495 * variable.
20496 */
20497 vos_mem_zero(&hddGtkOffloadReqParams,
20498 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020499 return status;
20500 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020501 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20502 "%s: sme_SetGTKOffload successfull", __func__);
20503 }
20504 else
20505 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020506 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20507 "%s: wlan not suspended GTKOffload request is stored",
20508 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020509 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020510
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053020511 /* Need to clear any trace of key value in the memory.
20512 * Thus zero out the memory even though it is local
20513 * variable.
20514 */
20515 vos_mem_zero(&hddGtkOffloadReqParams,
20516 sizeof(hddGtkOffloadReqParams));
20517
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020518 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020519 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020520}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020521
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020522int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
20523 struct cfg80211_gtk_rekey_data *data)
20524{
20525 int ret;
20526
20527 vos_ssr_protect(__func__);
20528 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
20529 vos_ssr_unprotect(__func__);
20530
20531 return ret;
20532}
20533#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020534/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020535 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020536 * This function is used to set access control policy
20537 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020538static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
20539 struct net_device *dev,
20540 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020541{
20542 int i;
20543 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20544 hdd_hostapd_state_t *pHostapdState;
20545 tsap_Config_t *pConfig;
20546 v_CONTEXT_t pVosContext = NULL;
20547 hdd_context_t *pHddCtx;
20548 int status;
20549
20550 ENTER();
20551
20552 if (NULL == pAdapter)
20553 {
20554 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20555 "%s: HDD adapter is Null", __func__);
20556 return -ENODEV;
20557 }
20558
20559 if (NULL == params)
20560 {
20561 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20562 "%s: params is Null", __func__);
20563 return -EINVAL;
20564 }
20565
20566 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
20567 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020568 if (0 != status)
20569 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020570 return status;
20571 }
20572
20573 pVosContext = pHddCtx->pvosContext;
20574 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
20575
20576 if (NULL == pHostapdState)
20577 {
20578 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20579 "%s: pHostapdState is Null", __func__);
20580 return -EINVAL;
20581 }
20582
20583 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
20584 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053020585 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20586 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
20587 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020588
20589 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
20590 {
20591 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
20592
20593 /* default value */
20594 pConfig->num_accept_mac = 0;
20595 pConfig->num_deny_mac = 0;
20596
20597 /**
20598 * access control policy
20599 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
20600 * listed in hostapd.deny file.
20601 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
20602 * listed in hostapd.accept file.
20603 */
20604 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
20605 {
20606 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
20607 }
20608 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
20609 {
20610 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
20611 }
20612 else
20613 {
20614 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20615 "%s:Acl Policy : %d is not supported",
20616 __func__, params->acl_policy);
20617 return -ENOTSUPP;
20618 }
20619
20620 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
20621 {
20622 pConfig->num_accept_mac = params->n_acl_entries;
20623 for (i = 0; i < params->n_acl_entries; i++)
20624 {
20625 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20626 "** Add ACL MAC entry %i in WhiletList :"
20627 MAC_ADDRESS_STR, i,
20628 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
20629
20630 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
20631 sizeof(qcmacaddr));
20632 }
20633 }
20634 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
20635 {
20636 pConfig->num_deny_mac = params->n_acl_entries;
20637 for (i = 0; i < params->n_acl_entries; i++)
20638 {
20639 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20640 "** Add ACL MAC entry %i in BlackList :"
20641 MAC_ADDRESS_STR, i,
20642 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
20643
20644 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
20645 sizeof(qcmacaddr));
20646 }
20647 }
20648
20649 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
20650 {
20651 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20652 "%s: SAP Set Mac Acl fail", __func__);
20653 return -EINVAL;
20654 }
20655 }
20656 else
20657 {
20658 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053020659 "%s: Invalid device_mode = %s (%d)",
20660 __func__, hdd_device_modetoString(pAdapter->device_mode),
20661 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020662 return -EINVAL;
20663 }
20664
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020665 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020666 return 0;
20667}
20668
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020669static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
20670 struct net_device *dev,
20671 const struct cfg80211_acl_data *params)
20672{
20673 int ret;
20674 vos_ssr_protect(__func__);
20675 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
20676 vos_ssr_unprotect(__func__);
20677
20678 return ret;
20679}
20680
Leo Chang9056f462013-08-01 19:21:11 -070020681#ifdef WLAN_NL80211_TESTMODE
20682#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070020683void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070020684(
20685 void *pAdapter,
20686 void *indCont
20687)
20688{
Leo Changd9df8aa2013-09-26 13:32:26 -070020689 tSirLPHBInd *lphbInd;
20690 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053020691 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070020692
20693 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070020694 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070020695
c_hpothu73f35e62014-04-18 13:40:08 +053020696 if (pAdapter == NULL)
20697 {
20698 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20699 "%s: pAdapter is NULL\n",__func__);
20700 return;
20701 }
20702
Leo Chang9056f462013-08-01 19:21:11 -070020703 if (NULL == indCont)
20704 {
20705 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070020706 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070020707 return;
20708 }
20709
c_hpothu73f35e62014-04-18 13:40:08 +053020710 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070020711 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070020712 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053020713 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070020714 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070020715 GFP_ATOMIC);
20716 if (!skb)
20717 {
20718 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20719 "LPHB timeout, NL buffer alloc fail");
20720 return;
20721 }
20722
Leo Changac3ba772013-10-07 09:47:04 -070020723 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070020724 {
20725 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20726 "WLAN_HDD_TM_ATTR_CMD put fail");
20727 goto nla_put_failure;
20728 }
Leo Changac3ba772013-10-07 09:47:04 -070020729 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070020730 {
20731 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20732 "WLAN_HDD_TM_ATTR_TYPE put fail");
20733 goto nla_put_failure;
20734 }
Leo Changac3ba772013-10-07 09:47:04 -070020735 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070020736 sizeof(tSirLPHBInd), lphbInd))
20737 {
20738 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20739 "WLAN_HDD_TM_ATTR_DATA put fail");
20740 goto nla_put_failure;
20741 }
Leo Chang9056f462013-08-01 19:21:11 -070020742 cfg80211_testmode_event(skb, GFP_ATOMIC);
20743 return;
20744
20745nla_put_failure:
20746 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20747 "NLA Put fail");
20748 kfree_skb(skb);
20749
20750 return;
20751}
20752#endif /* FEATURE_WLAN_LPHB */
20753
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020754static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070020755{
20756 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
20757 int err = 0;
20758#ifdef FEATURE_WLAN_LPHB
20759 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070020760 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020761
20762 ENTER();
20763
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053020764 err = wlan_hdd_validate_context(pHddCtx);
20765 if (0 != err)
20766 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053020767 return err;
20768 }
Leo Chang9056f462013-08-01 19:21:11 -070020769#endif /* FEATURE_WLAN_LPHB */
20770
20771 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
20772 if (err)
20773 {
20774 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20775 "%s Testmode INV ATTR", __func__);
20776 return err;
20777 }
20778
20779 if (!tb[WLAN_HDD_TM_ATTR_CMD])
20780 {
20781 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20782 "%s Testmode INV CMD", __func__);
20783 return -EINVAL;
20784 }
20785
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053020786 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20787 TRACE_CODE_HDD_CFG80211_TESTMODE,
20788 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070020789 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
20790 {
20791#ifdef FEATURE_WLAN_LPHB
20792 /* Low Power Heartbeat configuration request */
20793 case WLAN_HDD_TM_CMD_WLAN_HB:
20794 {
20795 int buf_len;
20796 void *buf;
20797 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080020798 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070020799
20800 if (!tb[WLAN_HDD_TM_ATTR_DATA])
20801 {
20802 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20803 "%s Testmode INV DATA", __func__);
20804 return -EINVAL;
20805 }
20806
20807 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
20808 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080020809
Manjeet Singh3c577442017-02-10 19:03:38 +053020810 if (buf_len > sizeof(*hb_params)) {
20811 hddLog(LOGE, FL("buf_len=%d exceeded hb_params size limit"),
20812 buf_len);
20813 return -ERANGE;
20814 }
20815
Amar Singhal05852702014-02-04 14:40:00 -080020816 hb_params_temp =(tSirLPHBReq *)buf;
20817 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
20818 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
20819 return -EINVAL;
20820
Leo Chang9056f462013-08-01 19:21:11 -070020821 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
20822 if (NULL == hb_params)
20823 {
20824 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20825 "%s Request Buffer Alloc Fail", __func__);
20826 return -EINVAL;
20827 }
20828
Ashish Kumar Dhanotiya3a8c0a72017-07-13 18:58:59 +053020829 vos_mem_zero(hb_params, sizeof(tSirLPHBReq));
Leo Chang9056f462013-08-01 19:21:11 -070020830 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070020831 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
20832 hb_params,
20833 wlan_hdd_cfg80211_lphb_ind_handler);
20834 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070020835 {
Leo Changd9df8aa2013-09-26 13:32:26 -070020836 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20837 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070020838 vos_mem_free(hb_params);
20839 }
Leo Chang9056f462013-08-01 19:21:11 -070020840 return 0;
20841 }
20842#endif /* FEATURE_WLAN_LPHB */
20843 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020844 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20845 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070020846 return -EOPNOTSUPP;
20847 }
20848
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020849 EXIT();
20850 return err;
Leo Chang9056f462013-08-01 19:21:11 -070020851}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020852
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053020853static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
20854#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
20855 struct wireless_dev *wdev,
20856#endif
20857 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020858{
20859 int ret;
20860
20861 vos_ssr_protect(__func__);
20862 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
20863 vos_ssr_unprotect(__func__);
20864
20865 return ret;
20866}
Leo Chang9056f462013-08-01 19:21:11 -070020867#endif /* CONFIG_NL80211_TESTMODE */
20868
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053020869extern void hdd_set_wlan_suspend_mode(bool suspend);
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020870static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020871 struct net_device *dev,
20872 int idx, struct survey_info *survey)
20873{
20874 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20875 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053020876 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020877 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053020878 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020879 v_S7_t snr,rssi;
20880 int status, i, j, filled = 0;
20881
20882 ENTER();
20883
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020884 if (NULL == pAdapter)
20885 {
20886 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20887 "%s: HDD adapter is Null", __func__);
20888 return -ENODEV;
20889 }
20890
20891 if (NULL == wiphy)
20892 {
20893 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20894 "%s: wiphy is Null", __func__);
20895 return -ENODEV;
20896 }
20897
20898 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
20899 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020900 if (0 != status)
20901 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020902 return status;
20903 }
20904
Mihir Sheted9072e02013-08-21 17:02:29 +053020905 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
20906
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020907 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053020908 0 != pAdapter->survey_idx ||
20909 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020910 {
20911 /* The survey dump ops when implemented completely is expected to
20912 * return a survey of all channels and the ops is called by the
20913 * kernel with incremental values of the argument 'idx' till it
20914 * returns -ENONET. But we can only support the survey for the
20915 * operating channel for now. survey_idx is used to track
20916 * that the ops is called only once and then return -ENONET for
20917 * the next iteration
20918 */
20919 pAdapter->survey_idx = 0;
20920 return -ENONET;
20921 }
20922
Mukul Sharma9d5233b2015-06-11 20:28:20 +053020923 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
20924 {
20925 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20926 "%s: Roaming in progress, hence return ", __func__);
20927 return -ENONET;
20928 }
20929
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020930 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
20931
20932 wlan_hdd_get_snr(pAdapter, &snr);
20933 wlan_hdd_get_rssi(pAdapter, &rssi);
20934
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053020935 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20936 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
20937 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020938 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
20939 hdd_wlan_get_freq(channel, &freq);
20940
20941
20942 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
20943 {
20944 if (NULL == wiphy->bands[i])
20945 {
20946 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
20947 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
20948 continue;
20949 }
20950
20951 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
20952 {
20953 struct ieee80211_supported_band *band = wiphy->bands[i];
20954
20955 if (band->channels[j].center_freq == (v_U16_t)freq)
20956 {
20957 survey->channel = &band->channels[j];
20958 /* The Rx BDs contain SNR values in dB for the received frames
20959 * while the supplicant expects noise. So we calculate and
20960 * return the value of noise (dBm)
20961 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
20962 */
20963 survey->noise = rssi - snr;
20964 survey->filled = SURVEY_INFO_NOISE_DBM;
20965 filled = 1;
20966 }
20967 }
20968 }
20969
20970 if (filled)
20971 pAdapter->survey_idx = 1;
20972 else
20973 {
20974 pAdapter->survey_idx = 0;
20975 return -ENONET;
20976 }
20977
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020978 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020979 return 0;
20980}
20981
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020982static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
20983 struct net_device *dev,
20984 int idx, struct survey_info *survey)
20985{
20986 int ret;
20987
20988 vos_ssr_protect(__func__);
20989 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
20990 vos_ssr_unprotect(__func__);
20991
20992 return ret;
20993}
20994
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020995/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053020996 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020997 * this is called when cfg80211 driver resume
20998 * driver updates latest sched_scan scan result(if any) to cfg80211 database
20999 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021000int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021001{
21002 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
21003 hdd_adapter_t *pAdapter;
21004 hdd_adapter_list_node_t *pAdapterNode, *pNext;
21005 VOS_STATUS status = VOS_STATUS_SUCCESS;
21006
21007 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021008
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053021009 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021010 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021011 return 0;
21012 }
21013
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021014 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
21015 NO_SESSION, pHddCtx->isWiphySuspended));
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021016
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053021017 if (pHddCtx->is_ap_mode_wow_supported)
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021018 {
21019 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21020 "%s: Resume SoftAP", __func__);
21021 hdd_set_wlan_suspend_mode(false);
21022 }
21023
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021024 spin_lock(&pHddCtx->schedScan_lock);
21025 pHddCtx->isWiphySuspended = FALSE;
21026 if (TRUE != pHddCtx->isSchedScanUpdatePending)
21027 {
21028 spin_unlock(&pHddCtx->schedScan_lock);
21029 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21030 "%s: Return resume is not due to PNO indication", __func__);
21031 return 0;
21032 }
21033 // Reset flag to avoid updatating cfg80211 data old results again
21034 pHddCtx->isSchedScanUpdatePending = FALSE;
21035 spin_unlock(&pHddCtx->schedScan_lock);
21036
21037 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
21038
21039 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
21040 {
21041 pAdapter = pAdapterNode->pAdapter;
21042 if ( (NULL != pAdapter) &&
21043 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
21044 {
21045 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021046 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021047 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
21048 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021049 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021050 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021051 {
21052 /* Acquire wakelock to handle the case where APP's tries to
21053 * suspend immediately after updating the scan results. Whis
21054 * results in app's is in suspended state and not able to
21055 * process the connect request to AP
21056 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053021057 hdd_prevent_suspend_timeout(2000,
21058 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021059 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021060 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021061
21062 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21063 "%s : cfg80211 scan result database updated", __func__);
21064
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021065 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021066 return 0;
21067
21068 }
21069 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
21070 pAdapterNode = pNext;
21071 }
21072
21073 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21074 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021075 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021076 return 0;
21077}
21078
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021079int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
21080{
21081 int ret;
21082
21083 vos_ssr_protect(__func__);
21084 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
21085 vos_ssr_unprotect(__func__);
21086
21087 return ret;
21088}
21089
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021090/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021091 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021092 * this is called when cfg80211 driver suspends
21093 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021094int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021095 struct cfg80211_wowlan *wow)
21096{
21097 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021098 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021099
21100 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021101
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021102 ret = wlan_hdd_validate_context(pHddCtx);
21103 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021104 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021105 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021106 }
21107
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053021108 if (pHddCtx->is_ap_mode_wow_supported) {
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021109 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21110 "%s: Suspend SoftAP", __func__);
21111 hdd_set_wlan_suspend_mode(true);
21112 }
21113
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021114
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021115 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21116 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
21117 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021118 pHddCtx->isWiphySuspended = TRUE;
21119
21120 EXIT();
21121
21122 return 0;
21123}
21124
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021125int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
21126 struct cfg80211_wowlan *wow)
21127{
21128 int ret;
21129
21130 vos_ssr_protect(__func__);
21131 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
21132 vos_ssr_unprotect(__func__);
21133
21134 return ret;
21135}
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021136
21137#ifdef FEATURE_OEM_DATA_SUPPORT
21138static void wlan_hdd_cfg80211_oem_data_rsp_ind_new(void *ctx,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021139 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021140{
21141 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
21142
21143 ENTER();
21144
21145 if (wlan_hdd_validate_context(pHddCtx)) {
21146 return;
21147 }
21148 if (!pMsg)
21149 {
21150 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
21151 return;
21152 }
21153
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021154 send_oem_data_rsp_msg(evLen, pMsg);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021155
21156 EXIT();
21157 return;
21158
21159}
21160
21161void wlan_hdd_cfg80211_oemdata_callback(void *ctx, const tANI_U16 evType,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021162 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021163{
21164 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
21165
21166 ENTER();
21167
21168 if (wlan_hdd_validate_context(pHddCtx)) {
21169 return;
21170 }
21171
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021172 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d) evLen %d"), evType, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021173
21174 switch(evType) {
21175 case SIR_HAL_START_OEM_DATA_RSP_IND_NEW:
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021176 wlan_hdd_cfg80211_oem_data_rsp_ind_new(ctx, pMsg, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021177 break;
21178 default:
21179 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
21180 break;
21181 }
21182 EXIT();
21183}
21184#endif
21185
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053021186#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
21187 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053021188/**
21189 * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api
21190 * @wiphy: Pointer to wiphy
21191 * @wdev: Pointer to wireless device structure
21192 *
21193 * This function is used to abort an ongoing scan
21194 *
21195 * Return: None
21196 */
21197static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
21198 struct wireless_dev *wdev)
21199{
21200 struct net_device *dev = wdev->netdev;
21201 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
21202 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
21203 int ret;
21204
21205 ENTER();
21206
21207 if (NULL == adapter) {
21208 hddLog(VOS_TRACE_LEVEL_FATAL, FL("HDD adapter is NULL"));
21209 return;
21210 }
21211
21212 ret = wlan_hdd_validate_context(hdd_ctx);
21213 if (0 != ret)
21214 return;
21215
21216 wlan_hdd_scan_abort(adapter);
21217
21218 return;
21219}
21220
21221/**
21222 * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api
21223 * @wiphy: Pointer to wiphy
21224 * @wdev: Pointer to wireless device structure
21225 *
21226 * Return: None
21227 */
21228void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
21229 struct wireless_dev *wdev)
21230{
21231 vos_ssr_protect(__func__);
21232 __wlan_hdd_cfg80211_abort_scan(wiphy, wdev);
21233 vos_ssr_unprotect(__func__);
21234
21235 return;
21236}
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053021237#endif
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053021238
Abhishek Singh936c6932017-11-07 17:28:23 +053021239#ifdef CHANNEL_SWITCH_SUPPORTED
21240/**
21241 * __wlan_hdd_cfg80211_channel_switch()- function to switch
21242 * channel in SAP/GO
21243 * @wiphy: wiphy pointer
21244 * @dev: dev pointer.
21245 * @csa_params: Change channel params
21246 *
21247 * This function is called to switch channel in SAP/GO
21248 *
21249 * Return: 0 if success else return non zero
21250 */
21251static int __wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
21252 struct net_device *dev, struct cfg80211_csa_settings *csa_params)
21253{
21254 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
21255 hdd_context_t *hdd_ctx;
21256 uint8_t channel;
21257 int ret;
21258 v_CONTEXT_t vos_ctx;
21259
21260 hddLog(LOGE, FL("Set Freq %d"), csa_params->chandef.chan->center_freq);
21261
21262 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
21263 ret = wlan_hdd_validate_context(hdd_ctx);
21264 if (ret)
21265 return ret;
21266
21267 vos_ctx = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
21268 if (!vos_ctx) {
21269 hddLog(LOGE, FL("Vos ctx is null"));
21270 return -EINVAL;
21271 }
21272
21273 if ((WLAN_HDD_SOFTAP != adapter->device_mode) &&
21274 (WLAN_HDD_P2P_GO != adapter->device_mode))
21275 return -ENOTSUPP;
21276
21277 channel = vos_freq_to_chan(csa_params->chandef.chan->center_freq);
Abhishek Singhceb6fe22017-11-27 13:53:18 +053021278 ret = wlansap_set_channel_change(vos_ctx, channel, false);
Abhishek Singh936c6932017-11-07 17:28:23 +053021279
21280 return ret;
21281}
21282
21283/**
21284 * wlan_hdd_cfg80211_channel_switch()- function to switch
21285 * channel in SAP/GO
21286 * @wiphy: wiphy pointer
21287 * @dev: dev pointer.
21288 * @csa_params: Change channel params
21289 *
21290 * This function is called to switch channel in SAP/GO
21291 *
21292 * Return: 0 if success else return non zero
21293 */
21294static int wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
21295 struct net_device *dev, struct cfg80211_csa_settings *csa_params)
21296{
21297 int ret;
21298
21299 vos_ssr_protect(__func__);
21300 ret = __wlan_hdd_cfg80211_channel_switch(wiphy, dev, csa_params);
21301 vos_ssr_unprotect(__func__);
21302
21303 return ret;
21304}
21305#endif
21306
Jeff Johnson295189b2012-06-20 16:38:30 -070021307/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053021308static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070021309{
21310 .add_virtual_intf = wlan_hdd_add_virtual_intf,
21311 .del_virtual_intf = wlan_hdd_del_virtual_intf,
21312 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
21313 .change_station = wlan_hdd_change_station,
21314#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
21315 .add_beacon = wlan_hdd_cfg80211_add_beacon,
21316 .del_beacon = wlan_hdd_cfg80211_del_beacon,
21317 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070021318#else
21319 .start_ap = wlan_hdd_cfg80211_start_ap,
21320 .change_beacon = wlan_hdd_cfg80211_change_beacon,
21321 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070021322#endif
21323 .change_bss = wlan_hdd_cfg80211_change_bss,
21324 .add_key = wlan_hdd_cfg80211_add_key,
21325 .get_key = wlan_hdd_cfg80211_get_key,
21326 .del_key = wlan_hdd_cfg80211_del_key,
21327 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080021328#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070021329 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080021330#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070021331 .scan = wlan_hdd_cfg80211_scan,
21332 .connect = wlan_hdd_cfg80211_connect,
21333 .disconnect = wlan_hdd_cfg80211_disconnect,
21334 .join_ibss = wlan_hdd_cfg80211_join_ibss,
21335 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
21336 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
21337 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
21338 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070021339 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
21340 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053021341 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070021342#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
21343 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
21344 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
21345 .set_txq_params = wlan_hdd_set_txq_params,
21346#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070021347 .get_station = wlan_hdd_cfg80211_get_station,
21348 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
21349 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070021350 .add_station = wlan_hdd_cfg80211_add_station,
21351#ifdef FEATURE_WLAN_LFR
21352 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
21353 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
21354 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
21355#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070021356#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
21357 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
21358#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021359#ifdef FEATURE_WLAN_TDLS
21360 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
21361 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
21362#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021363#ifdef WLAN_FEATURE_GTK_OFFLOAD
21364 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
21365#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053021366#ifdef FEATURE_WLAN_SCAN_PNO
21367 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
21368 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
21369#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021370 .resume = wlan_hdd_cfg80211_resume_wlan,
21371 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021372 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070021373#ifdef WLAN_NL80211_TESTMODE
21374 .testmode_cmd = wlan_hdd_cfg80211_testmode,
21375#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021376 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053021377#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
21378 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053021379 .abort_scan = wlan_hdd_cfg80211_abort_scan,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053021380#endif
Abhishek Singh936c6932017-11-07 17:28:23 +053021381#ifdef CHANNEL_SWITCH_SUPPORTED
21382 .channel_switch = wlan_hdd_cfg80211_channel_switch,
21383#endif
21384
Jeff Johnson295189b2012-06-20 16:38:30 -070021385};
21386